我有一个用于实例化全局变量的类:
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?
答案 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拆除之前。