我编写了一个简单的CUDA内核,用于在两个大小为2 ^ 18的列向量上执行SAXPY。
我发现我的GPU(特斯拉C2070)每块最多可以运行1024个线程。因此,我使我的块大小X = 1024,Y = 1,Z = 1.我还使我的网格大小X = 2 ^ 18/1024,Y = 1,Z = 1.我这样做是因为我想确保每个块的每个单独的线程都在使用。
但是,我发现运行块大小为X = 512和X = 128的内核始终比运行块大小为X = 1024的内核运行更快。
为什么?如果块大小小于1024,我不是在浪费线程吗?
答案 0 :(得分:3)
像SAXPY这样的1级BLAS功能是内存带宽有限的。操作
y <- alpha * x + y
仅执行单个FMAD,但需要两个加载和来自全局内存的存储。您的C2070具有大约37.5Gfloat / s的全局内存带宽和500 GFMAD / s的单精度算术吞吐量。因此性能取决于内存控制器,而不是ALU。通常减少内存带宽限制内核中每个块的线程数可以提高性能,因为它可以减少内存控制器和缓存资源的争用并提高带宽利用率。
这可能是你的SAXPY内核发生的事情。您应该能够通过基准测试找到最佳的块大小,但我的经验是,它将在像C2070这样的Fermi器件上的每块128-384个线程中。
答案 1 :(得分:1)
对于使用共享内存缓存读/写/数据共享的代码,较小的块大小可能导致每个线程使用更大的共享内存块,从而增加了良好的内存访问模式(更多合并)的机会。 p>
我同意talonmies,根据我的经验,每个块128-192个线程几乎总能为我的代码带来最佳性能,即使可以启动更多线程。