2011-12-14 5 views
1

私はCUDAプログラムが一定のサイズの行列を計算するのにどれくらい時間がかかりますか?たとえば、10x10,100x100,500x500,100x1000などです。CUDAタイムイベント

しかし、結果は私が期待していたものではありません。グラフの数値は、予想される数値ではありません。行列のサイズが大きくなると、計算時間が短くなる。

例えば、ここでは(1000回のランからの)平均時間は次のとおりです。 10×10:0.032768s 100×100:0.068960s 500×500:0.006336s 1000×1000:0.018400s

時間は、その後アップ再び、ダウン何が起きているのですか?特定のポイントで数字がピークになってはいけませんか?なぜこのようなローラーコースターで行くのですか? MAXTHREADSが1024であり、大きさがIがマトリクス状に持つ要素の量である

int blocksNeeded=0; 
cudaError_t cudaStatus; 
blocksNeeded=(size/MAXTHREADS)+1; 
int threadsPerBlock = MAXTHREADS/blocksNeeded+1; 
cudaEvent_t start, stop; 
float elapsedtime; 
. 
. 
. 
. 
. 
cudaEventCreate(&start); 
cudaEventCreate(&stop); 
cudaEventRecord(start, 0); 
addKernel<<<blocksNeeded, size>>>(dev_c, dev_a, dev_b,size); 
cudaStatus = cudaDeviceSynchronize(); 
cudaEventRecord(stop, 0); 
cudaEventSynchronize(stop); 
cudaEventElapsedTime(&elapsedtime, start, stop); 
cudaEventDestroy(start); 
cudaEventDestroy(stop); 

:ここ

は実際のタイミングコードが実行されている方法です。 I. 10x10マトリックスには100個の要素があります。あなたは、カーネルの呼び出しで2番目のパラメータは、各ブロックに起動するスレッドの数ではなく、合計数です

addKernel<<<blocksNeeded, MAXTHREADS>>>(dev_c, dev_a, dev_b,size); 

でカーネルを呼び出す必要があります

__global__ void addKernel(float *c, float *a, float *b,int size) 
{ 
    int idx = blockDim.x * blockIdx.x + threadIdx.x; 
    if(idx < size) 
     c[idx] = a[idx] + b[idx]; 

} 
+2

カーネル実行の戻りコードを確認していますか?たぶん500で、カーネルは起動に失敗しました – flipchart

+1

どのようにブロックを計算していますか? –

+0

cudaDeviceSynchronizeなしで試しましたか?タイミングに必要ではなく、結果に影響を与える可能性があります(記述した方法ではない場合でも)。そして、他のコメントに+1してください。 – jmsu

答えて

3

NVIDIA Tesla M2090を搭載した最近のGPUクラスタでテストしました。基本的に私は異なるサイズのベクトル加算を実行しています。結果は以下のとおりです。

Size  Kernel time (msec) 
=========================== 
2  0.04 
4  0.010912 
8  0.012128 
16  0.012256 
32  0.011296 
64  0.01248 
128  0.012192 
256  0.012576 
512  0.012416 
1024  0.012736 
2048  0.
4096  0.011968 
8192  0.011264 
16384 0.007296 
32768 0.007776 
65536 0.009728 
131072 0.018304 
262144 0.031392 
524288 0.055168 
1048576 0.10352 

あなたが見ることができますどのような膝は基本的にあなたの観察結果に似ている16384のベクトルの大きさ、であることが、あります。これはではなく、ですが、パフォーマンスを表示するためにGPUを使用する必要があるため、通常の動作ですがエラーです。利用のポイントは、Tesla M2090の場合、約16384パラレル加算に達しました。

カーネルパフォーマンスを測定する方法は完全にokです。 CUDAの「ベストプラクティスガイド」からこれを選択したと仮定します。

お知らせ:示すデータは、私は、単一カーネルの実行を使用して生成されることをご検討ください。 e。代表的なものではありません。一般に、正確な時間測定のためには、カーネルは同じ問題で複数回実行され、カーネルの時間は実行の平均です。

+0

+1魔法のない巧みな答えのために –

+0

+1のデータを提供していますが...測定は素晴らしいですが、なぜそれが起こるのかまだ説明していません。サイズ2が4よりも大きいのはなぜですか? 2を除いて、他のすべての有効な値については、予想されるサイズは1024でピークに達します。 2048で、最初の不良カーネルのパラメータは時間が減少し始めますが、なぜそれらは一定ではありませんか?カーネルは失敗しませんか? – jmsu

+0

データを提供していただき、ありがとうございます。私は2000を超えて実行すると障害が発生する問題にぶつかりつつありますが、私は現在その問題を解決しようとしています。あなたが16384並行加算を言うとき、それはテスラが持っているスレッドの最大量ですか? – Dan

0

:カーネルを更新しました

のスレッド。

100×100ですでに計算能力の2.xの

のために1536あるブロックあたりのスレッドの最大数を超えると、ちょうどあなたが間違っているthreadsPerBlockのいくつかの種類を計算していることに気づいて、あなたが使用していないことをされていますそれ。ブロックあたりのスレッド数を選択します。次に、処理するエレメントの総数で割り、余りが0でない場合に1を追加して、起動するブロック数を取得します。

+0

しかし、これは彼の尺度が500x500と1000x1000の方が低い理由を説明していません。または何かが欠けている? –

+0

カーネルの起動に失敗したか、無効なパラメータエラーなどが発生したためです。なぜ100x100でも低くはないのですが、エラーでは信頼できる結果が期待できません。 – jmsu

+0

私は同意しますが、彼はすべてのカーネルがエラーなく実行されると述べています –