如何处理cudaFree上全局变量,实例化

问题描述:

我有,我用它来实例化一个全局变量的类:如何处理cudaFree上全局变量,实例化

class BitUnpackPtrs 
{ 
public: 
    ushort* d_dataIn; 

    BitUnpackPtrs() : d_dataIn(NULL) {}; 

    ~BitUnpackPtrs() 
    { 
     cudaFree(d_dataIn); 
    } 

    void update(...) { ... } 
}; 

类是全球实例作为手柄,以减少CUDA内存的频繁分配。然而,当我的程序终止,CUDA-MEMCHECK产生一个警告:

计划打cudaErrorCudartUnloading(误差29)由于对CUDA API调用cudaFree “司机关停”。

处理这个问题的正确方法是什么?我可以删除cudaFree,但是如果此类在稍后的某个非全局级别使用,则会导致内存泄漏。我可以在构造函数中使用一个标志来指示应该如何处理内存。

或者,有没有办法检测cuda驱动程序是否正在关闭,而不是在那种情况下调用cudaFree?

+2

不要实例化期望调用或必须在构造函数或析构函数中调用cuda运行时API函数的类的全局对象。 CUDA运行时初始化/拆卸可以在程序启动和关闭时对此进行破坏,具体取决于您在类构造函数和析构函数中所做的操作。没有办法检测cuda驱动程序是否正在关闭(不会在'cuda-memcheck'中标记),并且不会在该实例中调用'cudaFree'。 –

不是让这个对象成为全局对象,而是在你的main()函数(或者被main()调用并包装你的应用程序的整个执行过程)中实例化它。这将确保您的cudaFree()调用在CUDA拆除发生之前被调用。

另一种替代方法是使用std::shared_ptrcustom deleter,它调用cudaFree()。如果你这样做,那么cudaFree()调用将在最后一个“用户”破坏其共享指针的副本之后发生 - 在main()完成之前和CUDA拆卸之前。

+0

我考虑过使用共享指针,但全局对象实际上是库的一部分。最终,我认为真正的解决方案将需要重构代码。目前,我已经向构造函数添加了一个参数来指示析构函数的内存处理。我只是让系统照顾cudaFree。 – AaronS

+0

@AaronS:够公平的;但请记住,其他用户会阅读这个问题,对他们来说,第二个选择可能仍然相关。 – einpoklum