【发布时间】:2017-01-03 10:51:45
【问题描述】:
我正在使用 (py)CUDA 编写光线追踪器,但加速比非常低;例如,在 1000x1000 的图像中,GPU 并行代码仅比在 CPU 中执行的顺序代码快 4 倍。
对于每条射线,我必须求解 5 个方程(射线追踪器使用 this paper 中描述的过程生成黑洞图像),所以我的设置如下:每条射线在一个单独的块中计算,其中 5 个线程计算使用共享内存的方程。也就是说,如果我想生成一个宽度为W像素、高度为H像素的图像,设置是:
- 网格:
W块 xH块。 - 块:
5线程。
最昂贵的计算是方程的分辨率,我使用自定义 Runge Kutta 4-5 算法求解。
代码很长,很难在这么短的问题中解释,但您可以在Github 中看到它。 CUDA 内核是here,Runge Kutta 求解器是here。可以找到具有完全相同求解器的顺序版本的 CPU 版本in the same repo。
要求解的方程涉及多个计算,恐怕sin、cos 和sqrt 等某些函数的 CPU 优化会导致速度不快(?)
我的机器规格是:
- GPU:GeForce GTX 780
- CPU:英特尔酷睿 i7 CPU 930 @ 2.80GHz
我的问题是:
- 在 GPU 并行的光线追踪器中相对于顺序代码获得 3 倍或 4 倍的加速是否正常?
- 您是否发现 CUDA 设置或代码中有任何可能导致此行为的错误?
- 我错过了什么重要的事情吗?
我知道这个问题可能过于具体,但如果您需要更多信息,请直说,我很乐意提供。
【问题讨论】:
-
在 GTZ 780 上,双重运算 (+,-,*) 的算术吞吐量仅为 1/24 of the single precision throughput。此外,使用 5 个线程的块仅使用每个 warp 的 5/32。这两个问题立即将 GPU 令人印象深刻的峰值 4 TFLOP/s 降低到仅 26 GFLOP/s。
-
此外,每个块仅使用一个 warp 最多可为您提供 25% 的占用率,因此只能部分隐藏延迟。
-
你最好将 32 或 64 像素组合成一个块,这样一个块使用 160 或 320 个线程。
-
还可以尝试每个块使用 64、128 和 256 个线程。仅使用 32 仍会限制您的入住率。此外,如果您还没有这样做,请将经纱分配给例如8×4 水平×垂直像素而不是 32×1,因为如果像素靠得更近,所需的 Runge-Kutta 步数可能会在一个扭曲中变化较小,从而导致更少的禁用线程和更好的资源使用。
-
即使你不能只用单精度代替双精度,也可能在某些地方可以使用单精度,而在其他地方使用双精度。
标签: performance cuda gpgpu