OpenCL单线程移动平均核执行过慢,是否存在操作失误?
关于OpenCL串行移动平均滤波器GPU性能低下的问题解答
GPU跑串行任务本来就远不如CPU
GPU的硬件架构是为大规模并行计算设计的,单线程性能完全没法和CPU的高性能核心比。CPU单核心有更高的主频、更大的缓存,还有分支预测、指令级并行等专门优化单线程的技术;而GPU的计算单元需要同时跑成百上千个线程才能填满流水线,单线程运行时绝大多数硬件资源都处于闲置状态,慢2-3个数量级是正常现象。你的核代码还存在额外性能损耗
除了架构天生劣势,你的代码本身也有拖慢速度的问题:RunningTotal是按值传递的参数,不是内存引用,GPU对这个变量的读写会有额外开销,而且串行更新这个变量完全无法利用GPU的并行特性。- 所有内存操作都用的是全局内存,GPU的全局内存延迟极高,哪怕是连续访问,缓存效率也远不如CPU的L1/L2缓存。
- 循环里的指针循环操作
CircularBufferPointerCtr &= 0xFF虽然简单,但单线程下没有任何并行优化空间,只能一步步执行。
针对你的需求的优化方案
你的核心诉求是在GPU完成并行处理后,直接在GPU做滤波以减少回传数据量,完全没必要用串行核,改成并行实现才能发挥GPU的优势:- 用前缀和并行实现移动平均:移动平均可以转化为前缀和的差值(比如窗口大小为256的话,
Filtered[sampleCtr] = Prefix[sampleCtr] - Prefix[sampleCtr-256],注意边界处理)。前缀和可以用GPU高效并行计算(OpenCL有内置的并行前缀和函数,或者自己实现并行核),整个滤波过程完全并行,能充分利用GPU的硬件资源。 - 直接在GPU筛选1%样本:计算完滤波结果后,不需要把所有数据回传主机,写一个并行核只把需要保留的1%样本复制到专门的输出缓冲区,再回传主机,这样数据传输量的优势就能完全体现出来。
- GPU只做并行任务:哪怕有少量必须串行的步骤,也尽量放在CPU上执行,让GPU专注于它擅长的大规模并行计算,避免资源浪费。
- 用前缀和并行实现移动平均:移动平均可以转化为前缀和的差值(比如窗口大小为256的话,
内容的提问来源于stack exchange,提问作者user202474
相关产品推荐
相关产品推荐

