3

我编写了一个简单的 CUDA 内核来对两个大小为 2^18 的列向量执行 SAXPY。

我发现我的 GPU 是 Tesla C2070,每个块最多可以运行 1024 个线程。因此,我使我的块大小 X = 1024,Y = 1,Z = 1。我还使我的网格大小 X = 2^18 / 1024,Y = 1,Z = 1。我这样做是因为我想确保每个块的每个线程都在使用。

但是,我发现以 X = 512 和 X = 128 的块大小运行内核始终比以 X = 1024 的块大小运行内核更快。

这是为什么?如果我的块大小小于 1024,我不是在浪费线程吗?

4

2 回答 2

3

1 级 BLAS 函数(如 SAXPY)受内存带宽限制。操作

y <- alpha * x + y

仅执行一次 FMAD,但需要两次加载和一次来自全局内存的存储。您的 C2070 具有大约 37.5Gfloat/s 的全局内存带宽和 500 GFMAD/s 的单精度算术吞吐量。所以性能是由内存控制器而不是 ALU 决定的。通常减少内存带宽受限内核中每个块的线程数会提高性能,因为它减少了内存控制器和缓存资源的争用,并增加了带宽利用率。

这可能是您的 SAXPY 内核正在发生的事情。您应该能够通过基准测试找到最佳块大小,但我的经验是,在像 C2070 这样的 Fermi 设备上,每个块的线程数为 128-384 个。

于 2012-10-28T06:41:02.707 回答
1

对于使用共享内存来缓存读取/写入/数据共享的代码,较小的块大小可能会导致每个线程使用更大的共享内存块,这反过来会增加良好的内存访问模式(更多合并)的机会。

我同意 talonmies 的观点,根据我的经验,每个块 128-192 个线程几乎总是会为我的代码带来最佳性能,即使可以启动更多线程也是如此。

于 2012-10-28T13:32:59.210 回答