2. API 同步行为

API 提供了同步和异步形式的 memcpy/memset 函数,后者带有 “Async” 后缀。这是一个用词不当,因为每个函数都可能根据传递给函数的参数表现出同步或异步行为。这些 API 的同步形式通过默认流发出这些复制操作。

任何 CUDA API 调用都可能因各种原因(例如争用或内部资源不可用)而阻塞或同步。此类行为可能会发生变化,不应依赖未记录的行为。

Memcpy

在参考文档中,每个 memcpy 函数都分为同步或异步,对应于以下定义。

同步

  1. 对于从分页主机内存到设备内存的传输,在启动复制之前会执行流同步。一旦分页缓冲区被复制到暂存内存以进行 DMA 传输到设备内存,该函数将返回,但到最终目的地的 DMA 可能尚未完成。

  2. 对于从固定主机内存到设备内存的传输,该函数相对于主机是同步的。

  3. 对于从设备到分页或固定主机内存的传输,该函数仅在复制完成后才返回。

  4. 对于从设备内存到设备内存的传输,不执行主机端同步。

  5. 对于从任何主机内存到任何主机内存的传输,该函数相对于主机是完全同步的。

异步

  1. 对于设备内存和分页主机内存之间的传输,该函数可能相对于主机是同步的。

  2. 对于从任何主机内存到任何主机内存的传输,该函数相对于主机是完全同步的。

  3. 如果分页内存必须首先暂存到固定内存,则驱动程序可能会与流同步并将副本暂存到固定内存中。

  4. 对于所有其他传输,该函数应完全异步。

Memset

cudaMemset 函数相对于主机是异步的,除非目标内存是固定主机内存。Async 版本始终相对于主机是异步的。

内核启动

内核启动相对于主机是异步的。并发内核执行和数据传输的详细信息可以在 CUDA 程序员指南中找到。