如何以异步方式有效地将变量从 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?的主要内容,如果未能解决你的问题,请参考以下文章

如何轻松地将变量从一个视图传递到另一个视图?

如何有效地将用户添加到 GitLab 中的所有项目(以编程方式或其他方式)

如何有效地将子域名传递给 Laravel 中的控制器和视图

将令牌从服务器传递到客户端并以安全方式存储

Matlab - 迭代地将行插入/追加到矩阵中

在 Python 中轻松地将变量从/向命名空间/字典转储