如果一个线程正在访问全局内存,为什么它访问一个大块?这个大块存储在哪里?
如果您以合并的方式从全局内存中读取,将全局内存的公共块复制到共享内存中是否有益,或者不会有任何改进。
即:如果每个线程正在读取接下来的 5 个或 10 个或 100 个内存位置,并对它们进行平均,如果你可以将全局内存中的一大块 X 点放入共享内存中,你能不能写一个 if 语句来说明你是否正在寻找一个这些内存值,从共享内存而不是全局读取?我假设翘曲发散惩罚将小于每次从全局内存中读取。
如果一个线程正在访问全局内存,为什么它访问一个大块?这个大块存储在哪里?
如果您以合并的方式从全局内存中读取,将全局内存的公共块复制到共享内存中是否有益,或者不会有任何改进。
即:如果每个线程正在读取接下来的 5 个或 10 个或 100 个内存位置,并对它们进行平均,如果你可以将全局内存中的一大块 X 点放入共享内存中,你能不能写一个 if 语句来说明你是否正在寻找一个这些内存值,从共享内存而不是全局读取?我假设翘曲发散惩罚将小于每次从全局内存中读取。
当您从全局内存中读取数据时,首先在 L1 缓存中搜索数据(高带宽,Fermi 上为 1.600GB/s,但大小有限,Fermi 上为 48KB),然后,如果 L1 中不存在,则在 L2 中搜索它们(带宽较低,但大于 L1,在 Fermi 上为 768KB),最后,如果 L2 中不存在,它们将从全局内存中加载*。
当发生全局内存加载时,数据被移动到 L2,然后到 L1,以便在下次需要全局内存读取时能够以更快的方式访问它们。
这些数据可能会被后续的全局内存负载驱逐,也可能不会。因此,原则上,如果您正在读取“小”数据块,则不必强制数据位于共享内存中以便下次快速访问它们。
考虑到,在 Fermi 和 Kepler 上,共享内存是由 L1 高速缓存的相同电路构成的。然后,您可以将共享内存视为受控的 L1 缓存。
然后,您应该强制数据驻留在共享内存中,以确保它们驻留在“最快的可用缓存”上,并且在您需要多次访问这些相同数据时执行此操作。
请注意,以上是全局内存传输背后的一般理念。实现细节可能因底层架构而异。
*Il 应该注意,L1 高速缓存行可以通过编译器选项禁用。这在随机访问数据模式的性能方面很有用。