CUDA 共享内存不比全局内存更快吗?

3

嗨,我有一个内核函数,在这个函数中我需要比较字节。我想要搜索的区域被分成了多个块,所以4k字节的数组被分成了16个块,每块包含256个字节。每个块中的线程会读取数组中的索引,并将其与另一个数组进行比较,而另一个数组中存放着我要搜索的内容。我有两种方法实现了这个功能:

  1. 比较全局内存中的数据,但是块中的线程经常需要读取相同的地址。

  2. 将数据从全局内存复制到共享内存,并以与上述相同的方式在共享内存中比较字节。仍然存在相同地址读取的问题。
    将数据复制到共享内存的代码如下:

     myArray[idx] = global[someIndex-idx];
     whatToSearch[idx] = global[someIndex+idx];
    

代码的其余部分是相同的。只有在示例2中对数据进行的操作才在共享数组上执行。

但第一种选项比使用共享内存快大约10%,为什么?感谢您的解释。


请提供一个完整的示例。如果没有它,所有当前的答案都是纯粹的猜测。您对下面的答案的评论不足以说明您正在做什么。 - harrism
2个回答

12

如果您仅在一个块内使用数据一次且没有数据在不同线程之间重用,那么使用共享内存实际上会更慢。原因是当您将数据从全局内存复制到共享内存时,它仍然算作全局事务。从共享内存读取数据会更快,但这并不重要,因为您已经必须先从全局内存读取内存,而从共享内存读取的第二步只是一个额外的步骤,没有提供任何有价值的东西。

所以,关键点是只有在需要多次访问相同数据时(无论是来自同一线程还是来自同一块中的不同线程),使用共享内存才有用。


共享内存还可以用于将低效的访问模式转换为良好的 coalesced 模式,例如用于 transpose 操作。 - Tom

1

您正在使用共享内存来减少对全局内存的访问,但每个线程仍然会对全局内存进行两次访问,因此速度不会更快。速度下降可能是因为在块内访问全局内存中相同位置的线程尝试将其读入共享内存中的相同位置,这需要串行化。

根据您发布的代码,我不确定您确切地在做什么,但您应确保在使用共享内存时,所有线程在一个块中聚合的从global读取和写入的次数显著降低。否则,您将看不到性能提升。


当(global_array[someIndex-idx+match] == global_array[someIndex+idx+match])时 { match++; } // 对分析数据进行一些操作。这就是我正在做的事情。 - Hlavson
线程块中的线程可能访问global_array位置的最大范围是多少?someIndex是否跨线程静态? - Vanwaril
这是静态索引,对于块中的所有线程都相同,但对于每个下一个块略有不同。就像块0正在处理索引为(744-1000)和(1000-1256)的数据,块1正在处理索引为(488-744)和(1000-1256)的数据,以此类推。 - Hlavson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接