cudaMemcpyAsync()并非真的Async

最近好奇,cudaMemcpyAsync()这个函数相对于Host端是否真的的异步的。 

简单测试了一下,发现有些时候并非是异步的。

通过阅读文档发现,cudaMemcpyAsync()是否异步遵循以下定义。

通过以上文档说明,对于cudaMemcpyAsync(), Host端pinned memory是必须的(与函数参数说明中一直)。

非pinned memory的情况下,不是同步的,就是需要将pageable memory转化成pinned memory,之后再异步,非常耗时。

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
cudaMemcpyAsync是一个异步内存复制函数,用于在CUDA设备和主机之间复制数据。与同步函数不同,它不会阻塞CPU线程,而是将复制操作放入CUDA流中,以便在GPU上异步执行。这个函数需要指定源内存地址、目标内存地址、复制的字节数以及流。当函数返回时,无法确保复制操作是否已经启动,更无法保证它是否已经结束。但是,我们能够得到的保证是,复制操作肯定会在下一个被放入流中的操作之前执行。需要注意的是,任何传递给cudaMemcpyAsync()的主机内存指针都必须已经通过cudaHostAlloc()分配好内存,也就是说,你只能以异步方式对页锁定内存进行复制操作。 下面是一个使用cudaMemcpyAsync()的例子: ```python import numpy as np from numba import cuda # 定义一个CUDA核函数 @cuda.jit def add_kernel(x, y, out): i = cuda.grid(1) if i < x.shape[0]: out[i] = x[i] + y[i] # 分配设备内存 x_device = cuda.to_device(np.array([1, 2, 3])) y_device = cuda.to_device(np.array([4, 5, 6])) out_device = cuda.device_array(3) # 定义流 stream = cuda.stream() # 异步复制数据到设备 cuda.memcpy_async(out_device, x_device, 3 * np.dtype(np.int32).itemsize, stream=stream) cuda.memcpy_async(out_device, y_device, 3 * np.dtype(np.int32).itemsize, stream=stream) # 在流上启动核函数 threads_per_block = 3 blocks_per_grid = 1 add_kernel[blocks_per_grid, threads_per_block, stream](x_device, y_device, out_device) # 异步复制结果到主机 out_host = np.empty(3, dtype=np.int32) cuda.memcpy_async(out_host, out_device, 3 * np.dtype(np.int32).itemsize, stream=stream) # 等待流执行完毕 stream.synchronize() # 输出结果 print(out_host) ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值