我尝试了此链接中的代码Is CUDA pinned memory zero-copy? 要求声称该程序适合他的人 但是我的工作方式不同 如果我在内核中操作它们,值不会改变。
基本上我的问题是,我的GPU内存还不够,但我想进行需要更多内存的计算。我的程序使用RAM内存或主机内存,并能够使用CUDA进行计算。链接中的程序似乎解决了我的问题,但代码没有提供输出,如该人所示。
有关零拷贝内存的任何帮助或任何工作示例都很有用。
谢谢
__global__ void testPinnedMemory(double * mem)
{
double currentValue = mem[threadIdx.x];
printf("Thread id: %d, memory content: %f\n", threadIdx.x, currentValue);
mem[threadIdx.x] = currentValue+10;
}
void test()
{
const size_t THREADS = 8;
double * pinnedHostPtr;
cudaHostAlloc((void **)&pinnedHostPtr, THREADS, cudaHostAllocDefault);
//set memory values
for (size_t i = 0; i < THREADS; ++i)
pinnedHostPtr[i] = i;
//call kernel
dim3 threadsPerBlock(THREADS);
dim3 numBlocks(1);
testPinnedMemory<<< numBlocks, threadsPerBlock>>>(pinnedHostPtr);
//read output
printf("Data after kernel execution: ");
for (int i = 0; i < THREADS; ++i)
printf("%f ", pinnedHostPtr[i]);
printf("\n");
}
答案 0 :(得分:8)
首先,要分配 ZeroCopy 内存,您必须将cudaHostAllocMapped
标志指定为cudaHostAlloc
的参数。
cudaHostAlloc((void **)&pinnedHostPtr, THREADS * sizeof(double), cudaHostAllocMapped);
仍然pinnedHostPointer
将仅用于从主机端访问映射的内存。要从设备访问相同的内存,您必须将设备端指针指向内存,如下所示:
double* dPtr;
cudaHostGetDevicePointer(&dPtr, pinnedHostPtr, 0);
将此指针作为内核参数传递。
testPinnedMemory<<< numBlocks, threadsPerBlock>>>(dPtr);
此外,您必须将内核执行与主机同步以读取更新的值。只需在内核调用后添加cudaDeviceSynchronize
。
链接问题中的代码正常工作,因为提出问题的人正在64位操作系统上运行代码,并且启用了Compute Capability 2.0和TCC的GPU。此配置自动启用GPU的Unified Virtual Addressing功能,其中设备将主机+设备内存视为单个大内存而不是单独的内存,使用cudaHostAlloc
分配的主机指针可以直接传递给内核。
在您的情况下,最终代码将如下所示:
#include <cstdio>
__global__ void testPinnedMemory(double * mem)
{
double currentValue = mem[threadIdx.x];
printf("Thread id: %d, memory content: %f\n", threadIdx.x, currentValue);
mem[threadIdx.x] = currentValue+10;
}
int main()
{
const size_t THREADS = 8;
double * pinnedHostPtr;
cudaHostAlloc((void **)&pinnedHostPtr, THREADS * sizeof(double), cudaHostAllocMapped);
//set memory values
for (size_t i = 0; i < THREADS; ++i)
pinnedHostPtr[i] = i;
double* dPtr;
cudaHostGetDevicePointer(&dPtr, pinnedHostPtr, 0);
//call kernel
dim3 threadsPerBlock(THREADS);
dim3 numBlocks(1);
testPinnedMemory<<< numBlocks, threadsPerBlock>>>(dPtr);
cudaDeviceSynchronize();
//read output
printf("Data after kernel execution: ");
for (int i = 0; i < THREADS; ++i)
printf("%f ", pinnedHostPtr[i]);
printf("\n");
return 0;
}