所有块都读取相同的全局内存位置部分。最快的方法是?

All blocks read same global memory location section. Fastest method is?

我正在编写一个所有块都读取相同地址的算法。比如我们有一个 list=[1, 2, 3, 4],所有的块都在读取它并将它存储到它们自己的共享内存中......我的测试显示读取它的块越多,速度就越慢...... .我想这里没有广播?知道我可以让它更快吗?谢谢!!!

我从之前的 post 了解到这可以在一个包装中广播,似乎不能在不同的包装中发生....(实际上在我的情况下,一个包装中的线程读取的不是相同的位置...)

一旦列表元素被 SM 单元的第一个 warp 访问,同一 SM 单元中的第二个 warp 从缓存中获取它并广播到所有 simt 通道。但是另一个 SM 单元的 warp 可能没有它在 L1 缓存中,因此它首先从 L2 获取到 L1。

它在 __constant__ 内存中类似,但它需要所有线程访问相同的地址。它的延迟更接近寄存器访问。 __constant__ 内存就像指令缓存,当所有线程都做同样的事情时,你会获得更高的性能。

例如,如果您有一个 Gaussian-filter 在所有线程上迭代相同的 coefficient-list 过滤器,最好使用常量内存。使用共享内存没有太多优势,因为过滤器数组不是随机扫描的。当每个块的过滤器数组内容不同或需要随机访问时,共享内存更好。

你也可以结合常量内存和共享内存。从常量内存中获取列表的一半,然后从共享内存中获取另一半。这应该让 1024 个线程隐藏隐藏在另一种内存类型后面的一种内存类型的延迟。

如果列表足够小,可以直接使用寄存器(必须是 compile-time 已知索引)。但它会增加套准压力并可能降低入住率,因此请注意这一点。

一些旧的 cuda 架构(在 fma 操作的情况下)需要一个操作数从常量内存中获取,另一个操作数从寄存器中获取,以在 compute-bottlenecked 算法中实现更好的性能。

在将 12000 个浮点数作为过滤器应用于所有线程输入的测试中,具有 128 个 threads-per-block 的共享内存版本在 330 毫秒内完成工作,而 constant-memory 版本在 260 毫秒内完成工作,L1访问性能是两个版本中真正的瓶颈,所以真正的 constant-memory 性能甚至更好,只要它对所有线程都是 similar-index。