我在使用 Cuda Runtime API 时遇到了一个非常奇怪的问题。对 cudaMallocHost()
、cudaEventCreate()
、cudaFree()
等函数的调用似乎仅当内核在 GPU 上完成执行时才会执行。这些内核都是在使用 cudaStreamNonBlocking 标志创建的流上启动的。问题是什么?我必须在某处放置一些其他标志吗?
最佳答案
它们可以设为异步,但如果不是异步也不足为奇。
对于cudaMallocHost()
,它要求为GPU映射主机内存:如果预分配池无法满足分配,则必须编辑GPU的页表。如果驱动程序有无法编辑正在执行的内核的页表的限制,我一点也不会感到惊讶。 (特别是因为页表编辑必须由内核模式驱动程序代码完成。)
对于cudaEventCreate()
,它确实应该是异步的,因为这些分配通常可以从预分配池中得到满足。主要障碍是更改行为会破坏依赖其当前同步行为的现有应用程序。
异步释放对象需要驱动程序跟踪提交给 GPU 的命令缓冲区中引用了哪些对象,并将实际的释放操作推迟到 GPU 处理完它们之后。这是可行的,但我不确定 NVIDIA 是否已完成这项工作。
对于cudaFree()
,不可能像跟踪 CUDA 事件那样跟踪引用(因为可以存储指针以供正在运行的内核读取和追踪)。因此,对于应该释放和取消映射的大虚拟地址范围,释放必须推迟到所有挂起的 GPU 操作执行完毕之后。同样,可行,但我不确定 NVIDIA 是否已完成这项工作。
我认为 NVIDIA 通常希望开发人员能够解决这些入口点缺乏异步性的问题。
关于cuda - cudaMallocHost() 、 cudaCreateEvent() 与执行内核异步吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15694665/