如何以异步方式有效地将变量从 Matlab 传递到 GPU?
Posted
技术标签:
【中文标题】如何以异步方式有效地将变量从 Matlab 传递到 GPU?【英文标题】:How to efficiently pass a variable from Matlab to GPU in Asynchronous way? 【发布时间】:2021-06-23 13:59:36 【问题描述】:在我的 CUDA 项目中,我可以定义一个固定内存,将数据从 .txt 文件复制到固定内存,并在内核中进行处理时使用流将数据复制到 GPU。 现在,我想制作一个 CUDA MEX 文件并在 Matlab 中将我的数据(称为 RfData)变量传递给它。但是,我注意到没有办法将 MATLAB 数组直接分配为固定的 CUDA 内存。所以,我必须用可分页内存来做如下:
int* RfData;
RfData = (int *)mxGetPr(prhs[0]);
int* Device_RfData;
int ArrayByteSize_RfData = sizeof(int) * (96* 96* 2048);
cudaMalloc((int**)&Device_RfData, ArrayByteSize_RfData);
cudaMemcpy(Device_RfData, RfData, ArrayByteSize_RfData, cudaMemcpyHostToDevice);
这对我来说很重要,可以通过流复制 RfData 异步。我能想到的唯一方法是首先将我的 RfData 复制到固定内存,然后使用流式传输:
int* RfData_Pinned;
cudaHostAlloc((void**)&RfData_Pinned, ArrayByteSize_RfData, cudaHostAllocWriteCombined);
for (int j = 0; j < (96* 96* 2048); j++)
RfData_Pinned[j] = RfData[j];
但是,它增加了我的 MEX 函数的总体处理时间。
所以,现在的问题是:如何以异步方式将我的数据从 matlab 传输到 GPU?也许CUDA中有一个命令可以将数据从可分页快速复制到固定内存!!!?
提前致谢, 莫因。
【问题讨论】:
【参考方案1】:您确实可以使用cudaHostAlloc
分配固定内存,但如果您已经分配了内存,则可以改为使用cudaHostRegister
固定它,这需要一个已经分配的主机数组指针(在您的情况下取自mxGetPr
) .
请注意,这将花费一些时间来固定内存,但可能少于执行cudaHostAlloc
然后复制它。
【讨论】:
好的。所以,如果我理解正确,我需要使用: cudaHostRegister(RfData, ArrayByteSize_RfData, cudaHostRegisterMapped);固定已经定义的可分页内存(RfData),在我的例子中它来自 mxGetPr。然后,我可以使用 RfData 指针作为指向固定内存的指针来进行流式传输。对吗? @MoeinMozaffarzadeh 是的。那是正确的。我使用cudaHostRegisterPortable
,但我现在不记得为什么使用cudaHostRegisterMapped
,或者它是否有所作为。之后,只需使用cudaMemcpyAsync
,最后一个参数是流。如果你想要一个例子,我会在 TIGRE 工具箱上使用所有这些,但它可能有点混淆,是一个简单的例子。
谢谢。还有一个问题。我是否还需要使用特定命令释放此内存,或者只是 free(RfData) 可以正常工作?
@Moein 你应该取消固定它。由于它是一个 matlab 数组(你刚刚得到了指针),我相信 matlab 会在它认为合适的时候释放它。以上是关于如何以异步方式有效地将变量从 Matlab 传递到 GPU?的主要内容,如果未能解决你的问题,请参考以下文章