OpenACC加速Fortran程序首次copyout时cuMemToHostAlloc耗时过长咨询
问题原因解析
首次调用耗时超长的核心原因
使用copyout(test)子句时,NVHPC编译器为了提升设备到主机的数据传输效率,会在首次执行该内核时调用cuMemToHostAlloc创建可分页锁定内存(Pinned Memory)。这类内存能规避普通内存传输时的页交换开销,但首次创建需要操作系统完成内存页的锁定操作,这个初始化过程本身开销较大,导致第一次调用的cuMemToHostAlloc耗时异常。
后续调用耗时正常的逻辑
首次创建锁定内存后,编译器会复用这块已锁定的内存区域,后续的copyout操作直接使用现有区域完成数据传输,无需再次执行内存页锁定的初始化步骤,因此传输时间恢复正常水平。
移除copyout后调用消失的原因
去掉copyout(test)子句后,编译器不再需要将设备端的test数据复制回主机,自然不需要为数据传输准备锁定内存,所以cuMemToHostAlloc调用不会触发。你提到主机端test已完成分配且有值,是因为此时编译器可能将内核逻辑优化到主机端执行(或隐式未在设备端创建数据副本),直接在主机内存中完成赋值操作。
优化建议
如果想消除首次调用的额外开销,可以提前通过显式内存管理指令初始化锁定内存:
- 用OpenACC的
!$acc enter data create(test)提前在设备端创建数据副本并关联主机锁定内存 - 或者手动调用CUDA的
cudaMallocHost分配锁定内存,再绑定到OpenACC数据区域
内容的提问来源于stack exchange,提问作者Paul Zehner
相关产品推荐
相关产品推荐

