cuda异步内存复制
cuda异步内存复制
在cuda handbook中发现了一个利用cuda event来进行的异步的内存的复制,觉得比较巧妙,但是美中不足的是书中代码里存在一个bug,不过思想还是很不错的
利用两个buffer来充当异步复制的缓冲区
1 | void *g_hostBuffers[2]; |
定义需要的两个event,这里定义了之后就立马record,以便将来函数内第一次Sync时不会出错。
1 | cudaEventCreate( &g_events[0] ); |
之后的内存分配和数据初始化部分我们就省略掉。接下来是最重要的函数部分
1 | void |
这里我们可以看到在第11行我们把src里的数据拷贝到缓冲区中,之后12行执行一个异步的复制操作。
这个复制操作由于是异步的,所以很快就会返回,执行下一步记录的操作,这一轮的复制操作就结束了,之后更新index,把1变成0,0变成1。
当我们执行到下一轮的cudaEventSynchronize语句时,我们会等待index所指的事件结束,由于事件是在复制之后被记录的,事件结束也意味着异步复制的结束。这一步是保证当前index的下一个复制时前一个复制已经结束,这样就可以保证两个时间分别进行两个异步的内存复制。
这里上述的代码是正确的,原书中的代码第13行是错误的,原书中g_event的索引是错误的,为g_events[1-stagingIndex],这样会导致整个流程都在串行,因为刚刚记录的g_event[0]在下一轮就立马执行了cudaEventSynchronize。
实验也证明了这一点,原书中的代码在实验室的TITAN V 显卡下的拷贝性能为2987.32 MB/s,而修改后上述的正确的代码的性能为4052.28 MB/s
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 WhatGhost!