首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >CUDA的内存是零拷贝吗?

CUDA的内存是零拷贝吗?
EN

Stack Overflow用户
提问于 2014-02-06 18:40:03
回答 2查看 2.8K关注 0票数 8

固定内存应该能提高主机到设备之间的传输速率(api接口引用)。但是,我发现我不需要调用cuMemcpyHtoD来访问内核的值,也不需要调用cuMemcpyDtoA来读取返回的值。我原以为这不管用,但确实是这样:

代码语言: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");
}

输出:

代码语言:javascript
运行
复制
Data after kernel execution: 10.000000 11.000000 12.000000 13.000000 14.000000 15.000000 16.000000 17.000000
Thread id: 0, memory content: 0.000000
Thread id: 1, memory content: 1.000000
Thread id: 2, memory content: 2.000000
Thread id: 3, memory content: 3.000000
Thread id: 4, memory content: 4.000000
Thread id: 5, memory content: 5.000000
Thread id: 6, memory content: 6.000000
Thread id: 7, memory content: 7.000000

我的问题是:

  • 固定内存是零拷贝吗?我以为只有映射的固定记忆是零拷贝。
  • 如果是零拷贝,为什么要显式地将它映射到设备(cudaHostAlloc和cudaHostAllocMapped选项)

我使用的是CUDA工具包5.5,Quadro 4000,驱动程序设置为TCC模式,以及编译选项sm_20,compute_20

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-02-06 19:08:42

祝贺你!您正遇到一个2.x计算能力+ TCC +64位OS功能,它有更新的CUDA版本:)

读读其余的,找出更多!

首先,像数据自动化系统( CUDA )所告诉我们的那样,一个小的理论总结:

  • 固定内存不是零拷贝,因为GPU无法访问它(它没有映射到它的地址空间),它用于从主机高效地传输到GPU。它是一种页面锁定(宝贵的内核资源)内存,与可分页的普通内存相比具有一些性能优势.
  • 固定零拷贝内存是页面锁定内存(通常与cudaHostAllocMapped标志一起分配),它自映射到其地址空间后也被GPU使用。

为什么要访问从主机分配的内存而没有显式地指定它?

请看CUDA 4.0 (及更高版本)的发布说明:

  • (Windows和Linux)增加了对统一虚拟地址空间的支持。

支持64位和计算2.0及更高性能的设备现在在主机和所有设备之间共享一个统一的地址空间。这意味着用于访问主机上内存的指针与用于访问设备上内存的指针相同。因此,可以直接从其指针值查询内存的位置;不需要指定内存副本的方向。

总结一下:,如果您的卡是2.0+ (它是: https://developer.nvidia.com/cuda-gpus),您正在运行64位操作系统,并且在Windows上有TCC模式,在主机和设备之间自动使用UVA (统一虚拟寻址) 。这意味着:使用零拷贝类访问自动增强代码。

这也出现在“主机分配的主机内存的自动映射”一段中的当前版本的CUDA文档中。

票数 10
EN

Stack Overflow用户

发布于 2014-02-06 19:08:52

映射内存是一种固定内存。它是在您插入内存并传递cudaHostAllocMapped标志时创建的。但是,即使您指定了cudaHostAllocDefault,在某些情况下,内存也会被“映射”。我相信TCC模式与64位操作系统相结合,足以满足“自动映射”功能所需的环境。

核心问题是UVA是否有效。在你的情况下,是的。

关于为什么具有显式功能的问题,它适用于UVA无效的情况(例如32位主机操作系统)。

来自文档 (当UVA生效时):

主机分配主机内存的自动映射 通过使用cudaMallocHost()和cudaHostAlloc()的所有设备分配的所有主机内存总是可以从所有支持统一寻址的设备直接访问。无论是否指定了标志cudaHostAllocPortable和cudaHostAllocMapped,情况都是如此。可以在支持统一寻址的所有设备上以内核访问分配的主机存储器的指针值与在主机上访问该存储器的指针值相同。没有必要调用cudaHostGetDevicePointer()来获取这些分配的设备指针。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21611252

复制
相关文章

相似问题

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