GFLOPSで性能を計算したいのは、ほぼ同じ2つのOpenCLカーネルです。カーネル#1は、次のとおりです。2つのほぼ同じOpenCLカーネル間のパフォーマンスの差
__kernel void Test41(__global float *data, __global float *rands, int index, int rand_max){
float16 temp;
int gid = get_global_id(0);
temp = data[gid];
temp = (float) rands[1] * temp;
temp = (float) rands[2] * temp;
temp = (float) rands[3] * temp;
temp = (float) rands[4] * temp;
.
.
.
temp = (float) rands[497] * temp;
temp = (float) rands[498] * temp;
temp = (float) rands[499] * temp;
data[gid] = temp.s0;
}
二カーネルは次のとおりです。
__kernel void Test42(__global float *data, __global float *rands, int index, int rand_max){
float16 temp[500];
int gid = get_global_id(0);
temp[0] = data[gid];
temp[1] = (float) rands[1] * temp[0];
temp[2] = (float) rands[2] * temp[1];
temp[3] = (float) rands[3] * temp[2];
temp[4] = (float) rands[4] * temp[3];
.
.
.
temp[497] = (float) rands[497] * temp[496];
temp[498] = (float) rands[498] * temp[497];
temp[499] = (float) rands[499] * temp[498];
data[gid] = temp[index].s0;
}
あなたは、私はすべてのカーネルは、オペレーション、それぞれの500行を持っている16のストリームサイズを使用しているコードで見ることができるようにそのうちの1つだけが浮動小数点演算を行います。私は合計で約1048576のカーネルをデプロイするので、並列に実行するために約1048576の作業項目が必要になります。私はプを計算するために
:私の周り1.4 TFLOPSを得るが、2番目のカーネルのため、私は38 GFLOPSを取得する最初のカーネルのため残念ながら
flops = #numWorkItems(1048576) * (500) * StreamSize(16)/timeTaken;
。私はこの大きなギャップを説明することができませんでした。単一の温度の代わりにtempのベクトルを使用することは大きな問題になります。また、実際のアプリケーションはほとんどが第2カーネルに似ているようです。最初のカーネルは実際のアプリケーションでは単純すぎます。
ここで何が起こっているのか、そして第2カーネルのパフォーマンスが最初のものに到達する方法を理解する助けになれますか?一般的に、デバイスのベンチマークを行う場合、理論値に近いパフォーマンスが期待できますか?
P.S.私はランドを__localメモリにコピーする必要があることを理解していますが、今のところそれをスキップしましょう。
2番目のカーネルには500個のfloat16値の配列のために多数のレジスタが割り当てられているため、カーネル占有率が低下してカーネルが低速になる可能性があります。 – sgarizvi
500 * 16 * 4 = 32kBです。ワークグループごとに1つのワークアイテムであっても、メモリ使用量のために遅くなります。 –
作業項目あたりの妥当なメモリ使用量はいくらですか?私はちょうど私のベンチマークを設計している間、より良い把握をしたいと思う。 – saman