Numba CUDA计算比串行运行慢,是否存在明显代码错误?
问题解答
代码存在的问题
- 数组规模过小:你当前设置的
n=100000仅10万元素,CPU做单精度加法的耗时远低于GPU核函数启动、数据传输带来的固定开销,GPU并行优势完全无法体现。 - 网格配置错误:你注释了正确的网格尺寸计算逻辑,硬编码
blockspergrid = 30,即便你用了网格步长的写法逻辑不会出错,但GTX 1080 Ti的算力资源完全没有被充分利用,正确的配置应该是blockspergrid = math.ceil(n / threadsperblock)。 - 计时方法错误:
time.process_time()统计的是CPU进程的执行时间,CUDA核函数运行时CPU处于闲置状态,该函数无法正确统计GPU侧的执行耗时,应该用time.perf_counter()或者CUDA内置的事件计时接口。
性能差异的原因
你当前的测试场景计算密度极低,仅做简单的元素加法,GPU的固定开销占比远超实际计算耗时,才会出现比CPU串行还慢的情况。当你把数组规模放大到1000万以上,GPU的并行优势就会明显体现。
关于to_device()的疑问
Numba CUDA本身支持隐式数据拷贝,如果你不主动调用to_device()把数组传到设备,调用核函数时Numba会自动完成数据的设备传输、结果回拷的操作。你当前的计时范围只包含核函数启动和同步阶段,隐式拷贝的耗时没有被统计到,所以才会出现用不用to_device()速度差异不大的错觉。
优化测试建议
- 将数组规模
n调整到1e7及以上,保证计算量足够覆盖GPU的固定开销 - 恢复正确的网格尺寸计算逻辑,充分利用显卡算力资源
- 更换计时方式,如需统计端到端性能要将数据拷贝、核函数执行的全流程耗时纳入统计
内容的提问来源于stack exchange,提问作者D Cro
相关产品推荐
相关产品推荐

