cudaFree 和 cudaFreeHost 无法释放堆分配的内存

w0r*_*t3r 2 c++ oop cuda

我写了一个类,其中堆中的构造函数内存是用 cudaMallocHost() 和 cudaMalloc() 分配的。

如果我尝试释放内存 cudaFree() 或 cudaFreeHost(),GPUassert 会抱怨:

GPUassert:无效的设备指针 ../src/main.cu 97

或者

GPUassert:无效参数../src/main.cu 95

我在具有计算能力 2.1 的设备上使用 CUDA TK 7.0。

我想我错过了一些基本的东西。我可以创建在设备上分配内存的对象吗?

class FreeMe {

public:
    FreeMe(int size);
    ~FreeMe(void);

private:
    float *A, *dA;
    int size;
};

FreeMe::FreeMe(int size) :
        size(size) {
    gpuErrchk(cudaMallocHost((void** ) &A, sizeof(float) * size));
    gpuErrchk(cudaMalloc((void** ) &dA, sizeof(float) * size));
}
FreeMe::~FreeMe(void) {
    std::cout << "FreeMe obj deleted: Free ..." << std::endl;
    gpuErrchk(cudaFreeHost(A));
    gpuErrchk(cudaFree(dA));
}

int main(int argc, char **argv) {
    int size = 3;

    FreeMe free1(size);

    cudaDeviceReset();
    std::cout << "Program terminated successfully." << std::endl;
    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

syn*_*gma 6

该错误是由您调用 引起的cudaDeviceReset()。查看其文档

显式销毁和清理当前进程中与当前设备关联的所有资源。对该设备的任何后续 API 调用都将重新初始化该设备。

请注意,此功能将立即重置设备。调用者有责任确保在调用此函数时进程中的任何其他主机线程都不会访问该设备。

请注意,您的对象将该调用后被销毁。当您重置设备时,它将无法释放内存(这是在析构函数中完成的)。

一个解决办法是分配堆使用你的对象newdelete,因此你可以delete你的free1对象之前调用cudaDeviceReset()