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

时间:2017-04-05 15:27:00

标签: c++ cuda global-variables dynamic-memory-allocation

我有一个用于实例化全局变量的类:

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?

1 个答案:

答案 0 :(得分:1)

不是将此对象设为全局,而是在 class Hole : ICloneable { public Dictionary<int, double> Candidates { get; set; } public double PosX { get; private set; } public double PosY { get; private set; } public bool isOccupied { get; set; } public Hole(double posX, double posY) { PosX = posX; PosY = posY; } public object Clone() { var hole = new Hole(this.PosX, this.PosY) { isOccupied = this.isOccupied, Candidates = this.Candidates }; return hole; } } // and replace // duration.Holes = new List<Hole>(holes); // to duration.Holes = new List<Hole>(holes.Select(x=>x.Clone() as Hole)); 函数(或由main()调用的某个地方实例化它并包装应用程序的整个执行)。这将确保在CUDA拆除发生之前调用main()来电。

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