OpenCL内核提交至执行阶段的高开销问题排查
针对你遇到的内核提交(CL_PROFILING_COMMAND_SUBMIT)到执行启动(CL_PROFILING_COMMAND_START)的开销(约350ms)远高于内核实际执行时间(约61ms)的问题,结合硬件特性与代码逻辑,核心原因如下:
移动GPU休眠唤醒的额外开销:Adreno 730为了降低功耗,在闲置时会自动进入低功耗休眠状态(如降频、关闭非必要硬件单元)。你的代码在每次循环中调用
clFinish(),会强制GPU完成当前任务后进入闲置状态;下一次循环提交内核时,GPU需要从休眠状态唤醒,包括提升时钟频率、初始化执行单元等操作,这部分耗时会完全计入提交到启动的时间间隔中,而非内核本身的执行准备开销。过度同步打断GPU执行流水线:循环内同时使用
clWaitForEvents()和clFinish(),会强制CPU等待GPU完成所有任务并清空命令队列。这种频繁的同步会彻底中断GPU的执行流水线,每次提交新内核时,OpenCL Runtime需要重新向GPU调度任务、重建执行上下文,从而产生大量额外调度延迟。移动平台OpenCL Runtime的功耗优化策略:Adreno的OpenCL Runtime针对移动设备做了功耗优先的优化,默认不会让GPU长时间保持活跃。当命令队列清空后,Runtime会主动触发GPU进入低功耗模式,下一次任务提交时需要重新启动调度流程,这部分流程的耗时远高于桌面平台的Runtime。
此外,循环内重复创建和释放cl_event对象虽不是主要原因,但频繁的对象生命周期管理也会带来微小的累积延迟。
内容的提问来源于stack exchange,提问作者mr_jnrdve

