2011-07-19 6 views
0

私は、NVidia Tesla C2050でn個のホストスレッドを同時に使用してn個のストリームを作成することを意図しています。カーネルは単純なベクトル乗算です...私はn個のストリームの間でデータを等分しています。各ストリームは同時に実行/データ転送を続けます。各ホストスレッドからのCUDAストリームの起動

データは浮動小数点ですが、時々CPU/GPUの合計が等しくなることもありますが、時にはそれらが離れていることもあります...これは私のコードでは同期構造が失われたためです私はすべてのCPUに一意のストリームを制御させ、スレッド内で非同期のデータコピーとカーネルの実行を気にしないので、ストリーム間の同期構造は必要ではないとも思っています。

//every thread would run this method in conjunction 

static CUT_THREADPROC solverThread(TGPUplan *plan) 
{ 

    //Allocate memory 
    cutilSafeCall(cudaMalloc((void**)&plan->d_Data, plan->dataN * sizeof(float))); 

    //Copy input data from CPU 
    cutilSafeCall(cudaMemcpyAsync((void *)plan->d_Data, (void *)plan->h_Data, plan->dataN * sizeof(float), cudaMemcpyHostToDevice, plan->stream)); 
    //to make cudaMemcpyAsync blocking 
    cudaStreamSynchronize(plan->stream); 

    //launch 
    launch_simpleKernel(plan->d_Data, BLOCK_N, THREAD_N, plan->stream); 
    cutilCheckMsg("simpleKernel() execution failed.\n"); 

    cudaStreamSynchronize(plan->stream); 

    //Read back GPU results 
    cutilSafeCall(cudaMemcpyAsync(plan->h_Data, plan->d_Data, plan->dataN * sizeof(float), cudaMemcpyDeviceToHost, plan->stream)); 
    //to make the cudaMemcpyAsync blocking...    
    cudaStreamSynchronize(plan->stream); 

    cutilSafeCall(cudaFree(plan->d_Data)); 

    CUT_THREADEND; 
} 

、複数のスレッドの作成と上記の関数を呼び出す:

for(i = 0; i < nkernels; i++) 
      threadID[i] = cutStartThread((CUT_THREADROUTINE)solverThread, &plan[i]); 

    printf("main(): waiting for GPU results...\n"); 
    cutWaitForThreads(threadID, nkernels); 

私はCUDAコードSDKサンプルの一つからこの戦略を取った

後、各スレッドが実行されるコードです。私が前に言ったように、このコードは時々動作しますが、それ以外の時には結果は馬鹿げています。私はこのコードを修正するのに助けが必要です...

答えて

1

私の賭けは

BLOCK_N、THREAD_N

は、あなたが渡す配列の正確なサイズをカバーしていないということです。 ストリームを初期化するコードとそれらのバッファのサイズを指定してください。

注釈として、ストリームはメモリ転送とのオーバーラップ計算に役立ちます。各非同期呼び出しの後にストリームを同期させることはまったく役に立ちません。

+0

私にその方向を指摘していただきありがとうございます!私のブロック・スレッドの次元は32X512であり、すべてのスレッドは1つのストリームを作成しています。上記の 'solverThread'関数の最初の行は' cudaStreamCreate(&plan-> stream) 'です。 – Sayan

2

私は最初の私の経験から、想像力の任意のストレッチで専門家ではありません。

なぜこれに複数のホストスレッドが必要かわかりません。 1つのデバイスを管理し、複数のストリームを渡しているようです。私はそこからこのなさ(擬似コード)

{ 
create a handle 

allocate an array of streams equal to the number of streams you want 

for(int n=0;n<NUM_STREAMS;n++) 
{ 
    cudaStreamCreate(&streamArray[n]); 
} 

} 

を見てきた方法は、あなただけのさまざまな非同期呼び出し(cudaMemcpyAsync()、カーネル・ストリームなど)に使用しているアレイ内のストリームを渡すことができ、デバイスが管理します残り。私は、複数のストリーム(GTX460で4〜8周ぐらいの問題にぶつかりますが、10kストリームを作ろうとしません)に奇妙なスケーラビリティの問題がありました。最高の幸運は、

ジョン

+1

私は現在、GPUと複数のCPUスレッドでプログラムするさまざまな方法をテストしていますが、それぞれのストリームを制御することはテストケースの1つです。これは動作を見るための単なる調査です。上記の例では、1つのGPUに4つのストリームしか作成していません。 BTW私は、あなたが提案しているように、1つのホストスレッドがGPU上で4つのストリームを制御しており、一定量のデータに対してうまく動作するテストケースを持っています。 – Sayan

関連する問題