首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Cuda:固定内存零拷贝问题

Cuda:固定内存零拷贝问题
EN

Stack Overflow用户
提问于 2014-11-17 09:35:25
回答 1查看 1.4K关注 0票数 5

我尝试了这个链接Is CUDA pinned memory zero-copy?中的代码,询问者声称该程序对他很好,但在我的程序上却没有相同的工作方式,如果我在内核中操作它们,值就不会改变。

基本上我的问题是,我的GPU内存是不够的,但我想做的计算,需要更多的内存。我的程序使用RAM内存,或者主机内存,并且能够使用CUDA进行计算。链接中的程序似乎解决了我的问题,但是代码没有给出输出,正如这个家伙所示。

任何关于零拷贝内存的帮助或任何工作示例都是有用的。

谢谢

代码语言:javascript
复制
__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");
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-11-17 09:53:09

首先,要分配ZeroCopy内存,必须指定cudaHostAllocMapped标志作为cudaHostAlloc的参数。

代码语言:javascript
复制
cudaHostAlloc((void **)&pinnedHostPtr, THREADS * sizeof(double), cudaHostAllocMapped);

不过,pinnedHostPointer将仅用于从主机端访问映射的内存。要从设备访问相同的内存,您必须获得指向内存的设备侧指针,如下所示:

代码语言:javascript
复制
double* dPtr;
cudaHostGetDevicePointer(&dPtr, pinnedHostPtr, 0);

将此指针作为内核参数传递。

代码语言:javascript
复制
testPinnedMemory<<< numBlocks, threadsPerBlock>>>(dPtr);

此外,您还必须与主机同步内核执行,以读取更新的值。只需在内核调用之后添加cudaDeviceSynchronize即可。

链接问题中的代码工作正常,因为提出问题的人在64位操作系统上运行代码,并启用了GPU of Compute Capability 2.0和TCC。此配置自动启用GPU的Unified Virtual Addressing特性,其中设备将主机+设备内存视为单个大内存,而不是单独的内存,并且可以将使用cudaHostAlloc分配的主机指针直接传递给内核。

在您的示例中,最终代码如下所示:

代码语言:javascript
复制
#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;
}
票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26969534

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档