indirectJ2[MAX_SUPER_SIZE]
是一个共享数组。
我的cuda设备内核包含以下语句(由线程块中的所有线程执行):
int nnz_col = indirectJ2[MAX_SUPER_SIZE - 1];
我怀疑这会导致银行冲突。
有没有什么方法可以使用针对kepler GPU的新shuffle指令有效地实现上述线程块级别广播?我理解它在warp级别是如何工作的。其他解决方案,除了随机指令(例如使用CUB等)之外,也是受欢迎的。
答案 0 :(得分:2)
K40上的那行代码没有银行冲突。共享内存访问已经提供了广播机制。引自programming guide
" warp的共享内存请求不会在访问同一个32位字内的任何子字的两个线程之间或者在索引i和j所在的两个32位字内产生存储体冲突相同的64字对齐的段(即,其第一个索引是64的倍数的段)并且使得j = i + 32(即使两个子字的地址落在同一个库中):在那种情况下,对于读取访问, 32位字广播到请求线程"
在线程块级别没有共享内存库冲突这样的概念。银行冲突仅涉及由单个warp发出的共享内存请求生成的访问模式,用于该warp中的单个指令。
如果您愿意,可以编写一个简单的测试内核并使用profiler metrics(例如shared_replay_overhead
)来测试共享内存库冲突。
Warp shuffle机制不会延伸到单个warp之外;因此,没有短的shuffle-only序列可以将单个数量广播到线程块中的多个warp。共享内存可以用于向warp中的所有线程提供单个数量的直接访问;你已经这样做了。
全局内存,__constant__
内存和内核参数也可以全部用于"广播"与线程块中所有线程相同的值。