2017-04-05 1 views
1

にcudaFreeを処理するために、私はグローバル変数をインスタンス化するために使用するクラスを持っている:どのように世界的にインスタンス化された変数

class BitUnpackPtrs 
{ 
public: 
    ushort* d_dataIn; 

    BitUnpackPtrs() : d_dataIn(NULL) {}; 

    ~BitUnpackPtrs() 
    { 
     cudaFree(d_dataIn); 
    } 

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

クラスは、CUDAメモリの頻繁な割り当てを削減するためのハンドルとして世界的にインスタンス化されます。しかし、私のプログラムが終了すると、CUDA-memcheckは警告を生成します。

プログラムが原因cudaFreeにCUDA API呼び出しに「ドライバがシャットダウン」にcudaErrorCudartUnloading(エラー29)を押してください。

これを処理する適切な方法は何ですか?私はcudaFreeを削除することができますが、このクラスがある時点で非グローバルレベルで使用されると、メモリリークが発生します。私は、メモリをどのように扱うべきかを示すために、コンストラクタ内にフラグを使用することができます。

代わりに、cudaドライバがシャットダウンしているかどうかを検出し、そのインスタンスでcudaFreeを呼び出さない方法がありますか?

+2

コンストラクタまたはデストラクタで呼び出しを行うクラスまたはcudaランタイムAPI関数を呼び出す必要があるクラスのグローバルオブジェクトをインスタンス化しないでください。 CUDAランタイムの初期化/分解は、クラスのコンストラクタとデストラクタで行う処理の正確さに応じて、プログラムの起動時とシャットダウン時に混乱を招く可能性があります。 cudaドライバがシャットダウンしている( 'cuda-memcheck'でフラグが立てられないように)検出し、そのインスタンスで' cudaFree'を呼び出さない方法はありません。 –

答えて

1

このオブジェクトをグローバルにする代わりに、main()関数(またはmain()によって呼び出され、アプリケーションの実行全体をラップする)でインスタンス化します。これにより、CUDAのティアダウンが発生する前にcudaFree()コールが呼び出されるようになります。

もう1つの方法は、std::shared_ptrcustom deletercudaFree())を使用することです。これを行うと、cudaFree()コールは、最後の「ユーザー」が共有ポインターのコピーを破棄した後に発生します。これはmain()が完了する前とCUDAの分解前です。

+0

私は共有ポインタの使用を検討しましたが、グローバルオブジェクトは実際にはライブラリの一部です。最終的には、実際のソリューションではコードを再構築する必要があると思います。当面は、デストラクタのメモリ処理を示すために、コンストラクタにパラメータを追加しました。私はちょうどシステムがcudaFreeを世話するようにしました。 – AaronS

+0

@AaronS:十分に公正。しかし、他のユーザーがこの質問を読んでくれることを覚えておいてください。そして、2番目の選択肢は依然として関連性があります。 – einpoklum

関連する問題