2011-07-15 11 views
2

私は、書いたコードをCUDAを使ってGPUで処理する独自のライブラリに入れました。新しいスレッドでCUDA対応ライブラリを呼び出す

私はQtのを使用してGUIフロントエンドを構築していて、GUIをロードするの一環として、私が呼び出したときに、アプリケーションが可能な限り応答するように、先に行くとGPUを初期化するために

CUresult res; 
CUdevice dev; 
CUcontext ctx; 

    cuInit(0); 
    cuDeviceGet(dev,0); 
    cuCtxCreate(ctx, 0, dev); 

を呼び出しますCUDA対応ライブラリー。

問題は、別のスレッドからCUDA対応ライブラリを呼び出すようになったことです。

これを行うには何らかの努力が必要ですか?他のスレッドは、(cuInit()を呼び出すメインスレッドを除く)任意のcuda関数を呼び出すだけですが、私のコードは私のcudaライブラリのcudaFree()呼び出しでクラッシュしています。

ありがとうございました

答えて

3

コンテキストは、それらを作成したスレッドに関連付けられています。つまり、GPU「ワーカースレッド」にコンテキストを確立させるか、ドライバーAPIコンテキストのマイグレーション呼び出し(cuCtxPopCurrentcuCtxPushCurrent)を使用してコンテキストをスレッドからスレッドに移動させるかの2つの選択肢があります。コンテキストの移行は無料ではないことに注意してください。そうすれば、GPUの待ち時間が増えることに気付くでしょう。

+0

私は、ワーカースレッドでcuCtxPopCurrent()を呼び出そうとしましたが、ワーカースレッドでnullの結果を返すようです – Derek

1

私は通常、ドライバAPIを使用していませんので、cuCtxPopCurrent()cuCtxPushCurrent()の間で混乱しやすい以外の直接のアドバイスはできません。

しかし、確かにCUDA Toolkit 4.0 Readiness Tech Briefをチェックしてください。 CUDA 4.0はマルチスレッドやマルチGPUの仕組みに大きな変化をもたらしました。

1

これまで私が使ってきたソリューション(Cuda 2.2)は、GPUの「ワーカースレッド」パラダイムでもあります。ここでは、単一の専用スレッドがCUDAコンテキストを管理します。 (関数コールを転送するために、ブースト::バインドを使用して)

A非常に一般的なアプローチは、リンクからhttp://forums.nvidia.com/index.php?showtopic=66598

例コードを見ることができる。

GPUWorker gpu0(0); 
GPUWorker gpu1(1); 

// allocate data 
int *d_data0; 
gpu0.call(bind(cudaMalloc, (void**)((void*)&d_data0), sizeof(int)*N)); 
int *d_data1; 
gpu1.call(bind(cudaMalloc, (void**)((void*)&d_data1), sizeof(int)*N)); 

// call kernel 
gpu0.callAsync(bind(kernel_caller, d_data0, N)); 
gpu1.callAsync(bind(kernel_caller, d_data1, N)); 

GPUWorkerオブジェクトは、関数が呼び出しを介してオブジェクトを受け付けメソッドをキューにプッシュします。 GPUWorker :: run()は関数オブジェクトをポップアウトし、適切なCUDAコンテキストで呼び出します。

関連する問題