2017-04-05 88 views
1

我有,我用它來實例化一個全局變量的類:如何處理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'。 –

回答

1

不是讓這個對象成爲全局對象,而是在你的main()函數(或者被main()調用幷包裝你的應用程序的整個執行過程)中實例化它。這將確保您的cudaFree()調用在CUDA拆除發生之前被調用。

另一種替代方法是使用std::shared_ptrcustom deleter,它調用cudaFree()。如果你這樣做,那麼cudaFree()調用將在最後一個「用戶」破壞其共享指針的副本之後發生 - 在main()完成之前和CUDA拆卸之前。

+0

我考慮過使用共享指針,但全局對象實際上是庫的一部分。最終,我認爲真正的解決方案將需要重構代碼。目前,我已經向構造函數添加了一個參數來指示析構函數的內存處理。我只是讓系統照顧cudaFree。 – AaronS

+0

@AaronS:夠公平的;但請記住,其他用戶會閱讀這個問題,對他們來說,第二個選擇可能仍然相關。 – einpoklum