cudaMemcpyToSymbol和cudaMemcpy有什么区别,为什么cudaMemcpyToSymbol仍然存在?

13
1个回答

46
简而言之,由于cudaMemcpy无法在不进行额外API调用的情况下完成与cudaMemcpyToSymbol相同的操作。考虑一个常量内存数组:
__constant__ float coeffs[8];

使用cudaMemcpyToSymbol将值复制到此数组,只需执行以下操作:

cudaMemcpyToSymbol(coeffs, hostData, 8*sizeof(float));

使用cudaMemcpy实现相同的操作需要这样做:

float *dcoeffs;
cudaGetSymbolAddress((void **)&dcoeffs, coeffs);
cudaMemcpy(dcoeffs, hostData, 8*sizeof(float), cudaMemcpyHostToDevice);

cudaMemcpy的直接调用是非法的,需要先进行符号查找。

[免责声明:所有代码都是在没有访问文档或编译器的情况下在浏览器中编写的,使用时自行承担风险]


1
谢谢,__constant__内存和方法签名中的const指针参数之间有什么关系? __constant__的类型是指向const的指针吗?此外,为什么不能只使用&coeffs获取地址? - rubixibuc
5
__constant__ 是 CUDA 中的存储类说明符,表示该符号位于 GPU DRAM 的特殊缓存、只读部分。它与 const 完全独立。你不能使用 &coeffs,因为那会暗示符号在主机内存中的地址而不是 GPU 内存,而 API 调用需要的是 GPU 内存中的地址。 - talonmies
指针变量coeffs指向的地址在哪里?将其复制到该地址会将内存定向到哪里?这是否也适用于使用__device__声明的变量? - rubixibuc
1
通过CUDA API复制到该地址将失败并提示无效参数错误,因为它不是API之前分配的GPU内存空间中的地址。是的,这也适用于通用的__device__指针和静态声明的设备符号。 - talonmies
API在使用cudaGetSymbolAddress时,是否区分指针类型和非指针类型的设备变量的地址?当调用该函数时,它是获取实际指针变量的内存地址还是被指向内存的起始地址?与获取标准int设备变量的地址相比如何? - rubixibuc
重要的是要提到,cudaGetSymbolAddress(...) 应该从“.cu”文件中调用,而不是“.cuh”,否则会引发错误号13。 - ddleon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接