我正在使用我的GPU与我的CPU同时使用。当我分析内存传输时,我发现cuBLAS中的异步调用不是异步行为。
我的代码类似于以下内容
cudaEvent_t event;
cudaEventCreate(&event);
// time-point A
cublasSetVectorAsync(n, elemSize, x, incx, y, incy, 0);
cudaEventRecord(event);
// time-point B
cudaEventSynchronize(event);
// time-point C
我正在使用sys/time.h
进行配置(为了清晰起见,省略了代码)。我发现cublasSetVectorAsync
调用在时间上占主导地位,就好像它是同步行为一样。即持续时间A-B比持续时间B-C长得多,并随着我增加转移的大小而增加。
可能的原因是什么?是否需要设置某个环境变量或者需要使用的更新驱动程序?
我正在使用带有Cuda编译工具的GeForce GTX 285,版本4.1,V0.2.1221
答案 0 :(得分:2)
cublasSetVectorAsync
是cudaMemcpyAsync
的精简包装。不幸的是,在某些情况下,这个函数的名称用词不当,如this page from the CUDA reference manual所述。
值得注意的是:
对于从可分页主机内存到设备内存的传输,在启动副本之前执行流同步。一旦将可分页缓冲区复制到分段存储器以便DMA传输到设备存储器,该函数将返回,但DMA到最终目标可能尚未完成。
和
对于从可分页主机内存到设备内存的传输,主机内存会立即复制到分段缓冲区(不执行设备同步)。一旦将可分页缓冲区复制到分段存储器,该函数将返回。 DMA转移到最终目的地可能尚未完成。
因此,您的问题的解决方案可能只是使用cudaHostAlloc
而不是标准x
(或C ++ malloc
)来分配new
您的主机数据阵列。
或者,如果您的GPU和CUDA版本支持它,您可以使用malloc
,然后在malloc
- ed指针上调用cudaHostRegister
。请在文档中注明您必须使用cudaDeviceMapHost
标记创建CUDA上下文才能使cudaHostRegister
生效(请参阅cudaSetDeviceFlags
的文档。
答案 1 :(得分:-1)
在cuBLAS / cuSPARSE中,如果您未指定其他流,则会在流0中发生。要指定流,您必须使用cublasSetStream(请参阅cuBLAS文档)。