如何使用cudaMallocManaged为C++类成员变量正确分配GPU内存?
问题原因与解决方法
CUDA error=1对应cudaErrorInvalidValue,错误根源在cudaMallocManaged的调用参数上:
cudaMallocManaged的标准签名为cudaError_t cudaMallocManaged(void** devPtr, size_t size, unsigned int flags = cudaMemAttachGlobal),仅接受最多3个参数(第三个为可选的内存附着标志),你错误地将height作为第三个参数传入,导致参数不匹配。- 实际需要分配的内存大小应为图像总像素数×单个
Color的大小,即sizeof(Color) * width * height,你之前仅计算了width维度的大小,遗漏了height。
修正后的完整代码
#include <iostream> // limited version of checkCudaErrors from helper_cuda.h in CUDA examples #define checkCudaErrors(val) check_cuda((val), #val, __FILE__, __LINE__) void check_cuda(cudaError_t result, char const* const func, const char* const file, int const line) { if (result) { std::cerr << "CUDA error = " << static_cast<unsigned int>(result) << " at " << file << ":" << line << " '" << func << "' \n"; // Make sure we call CUDA Device Reset before exiting cudaDeviceReset(); exit(-1); } } class Color { public: double r, g, b; __host__ __device__ Color() : r(0.0), g(0.0), b(0.0) { } }; class Image { public: Color* frame; }; int main() { int width = 1960; int height = 1080; Image *image; // 分配Image对象的托管内存 checkCudaErrors(cudaMallocManaged((void **)&image, sizeof(Image))); // 分配frame指向的托管内存,计算正确的总大小 checkCudaErrors(cudaMallocManaged((void **)&(image->frame), sizeof(Color) * width * height)); // 使用完内存后释放,避免泄漏 checkCudaErrors(cudaFree(image->frame)); checkCudaErrors(cudaFree(image)); return 0; }
额外说明
- 托管内存会自动在CPU与GPU间同步访问,无需手动调用
cudaMemcpy。 - 所有通过
cudaMallocManaged分配的内存,必须用cudaFree释放。 - 若需指定内存附着行为(如仅允许CPU线程访问),可在
cudaMallocManaged中传入第三个参数,例如cudaMemAttachHost。
内容的提问来源于stack exchange,提问作者Rahn
相关产品推荐
相关产品推荐

