CUDA内核可以修改主机内存吗

Can CUDA Kernels Modify Host Memory?

本文关键字:主机 内存 修改 内核 CUDA      更新时间:2024-09-21

是否有任何方法可以让内核通过将指向整数的指针传递给内核来修改该整数?指针似乎指向设备内存中的一个地址,因此内核不会影响主机。

下面是一个我注意到的行为的简化示例。

#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <iostream>
__global__
void change_cuda(int* c);
void change_var(int* c);
int main() {
using namespace std; 
int c = 0;
int* ptc = &c;
change_var(ptc); // *ptc = 123
cout << c << endl;
cudaError_t errors;
cudaMallocManaged((void**)&ptc, sizeof(int));
change_cuda<<<1, 1>>> (ptc); // *ptc = 555
errors = cudaDeviceSynchronize();
cudaFree(ptc);
cout << cudaGetErrorString(errors) << endl;
cout << c << endl;
return 0;
}
__global__
void change_cuda(int* c) {
*c = 555;
}
void change_var(int* c) {
*c = 123;
}

理想情况下,这将在最后将c修改为555,但此示例的输出为

123
no error
123

很明显,我误解了这是怎么回事。获得我期望的行为的正确方法是什么?

是的,你有误解。cudaMallocManaged分配器,例如mallocnew。它返回一个指针,指向请求大小的新分配

这不是允许从设备代码访问基于主机堆栈的变量的某种方法。

然而,cudaMallocManaged返回的指针所指向的分配区域可以从设备代码或主机代码访问。(它不会指向您的c变量。(

您可以通过进行以下更改来最低限度地修复代码。1.注释掉对cudaFree的调用。2.打印出*ptc的值,而不是c的值。也许一个更明智的改变可能是这样的:

int main() {
using namespace std; 
int* ptc;
cudaMallocManaged((void**)&ptc, sizeof(int));
change_var(ptc); // *ptc = 123
cout << *ptc << endl;
cudaError_t errors;
change_cuda<<<1, 1>>> (ptc); // *ptc = 555
cudaDeviceSynchronize();
errors = cudaGetLastError();
cout << cudaGetErrorString(errors) << endl;
cout << *ptc << endl;
return 0;
}