如何在CUDA中将矢量类型值转换为固定内存

6
我有关于制作固定内存的问题。
现在我正在使用CUDA处理大量数据。
为了减少运行时间,我想到需要重叠内存复制和核心启动。
在搜索一些文本和网页后,为了重叠内存复制和核心启动,我注意到需要使用cudaMallocHost来分配主机内存,这将分配主机内存到固定内存中。 在主机上使用整数或数组类型的情况下,很容易制作固定内存。
就像这样...
cudaStream_t* streams = (cudaStream_t*)malloc(MAX_num_stream * sizeof(cudaStream_t));
for(i=0; i<MAX_num_stream; i++)
    cudaStreamCreate(&(streams[i]));

cudaMallocHost(&departure, its_size);

for(n=1; ... ; n++){
   cudaMemcpyAsync( ... streams[n]);
   kernel <<< ... , ... , ... , streams[n] >>> (...);
}

然而在我的情况下,我的主机离开内存是由向量类型设置的。

我找不到任何方法可以使用cudaMallocHost将向量类型主机内存转换为固定内存。

请帮助我或者给出一些解决这个问题的建议。感谢您阅读我拙劣的英文,谢谢。


1
"vector type" 究竟是什么意思?您是指C++的 std::vector,还是其他东西? - talonmies
是的,我指的是std::vector。 - Umbrella
1个回答

6

使用 cudaMallocHost 时,你只能为其他 POD 类型分配内存。

如果你确实需要一个使用固定内存的 std::vector,则需要实现自己的 std::allocator 模型,并在其中调用 cudaMallocHost,然后使用该自定义分配器实例化你的 std::vector

另外,thrust 模板库(在 CUDA 工具包的最新版本中提供)包括一个实验性的固定内存分配器,你可以将其与 thrust 自己的 vector 类一起使用,这个类本身就是 std::vector 的模型。


谢谢talonmies。这些内容对我的情况很有帮助。 - Umbrella
我还有一个小问题。在使用cudaMemcpyAsync 和 kernel时,是否可以不使用cudaMallocHost?我试图创建异步代码而不制作主机固定内存,但这个方法效果很好。这是一般情况还是偶然情况? - Umbrella
1
是的,它可以工作,但对于任何大于64kb的传输,设备上的传输将不会是异步的。主机API调用会立即返回,但设备会被阻塞直到复制完成,即没有同时执行内核和内存复制或cudaMemcpyAsync的任何其他好处。 - talonmies
非常感谢。我曾经怀疑使用cudaMemcpyAsync和没有创建固定内存的kernel测量运行时间比不使用cudaMemcpyAsync的情况要稍微短一些。现在我猜测这是由于某些小于64kb的数据传输导致了运行时间的缩短。感谢您的回复。 - Umbrella

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接