ここで私が取り組んでいるOpenCLカーネルの2つのコードがあります。彼らは大幅に異なるランタイムを表示します。OpenCL:なぜこれらの2つのケースでパフォーマンスが大きく異なるのですか?
コードはかなり複雑なので、私はすぐに簡略化しました。
このバージョンでは、1秒の下で実行されます:
for (int ii=0; ii<someNumber;ii++)
{
for (int jj=0; ii<someNumber2;jj++)
{
value1 = value2 + value3;
value1 = value1 * someFunction(a,b,c);
double nothing = value1;
}
}
と、このバージョンを実行するために周りに38秒かかる:私が言うように
for (int ii=0; ii<someNumber;ii++)
{
for (int jj=0; ii<someNumber2;jj++)
{
value1 = value2 + value3;
value1 = value1 * someFunction(a,b,c);
}
double nothing = value1;
}
、コードがあります(これよりも多少複雑ですループ内では他にも多くのことが起こっています)、変数 "nothing"はブレースの直前から直後に移動します。
私はOpenCLにとって非常に新しく、何が起こっているのか、それを修正する方法ははるかに少ないです。言うまでもなく、遅いケースは実際に私の実装で必要なものです。私はアドレス空間(ここではすべての変数は__privateにあります)を使いこなそうとしました。
私は何らかの理由で、ブレースが閉じたときに、GPUが変数 "value1"をより遅いメモリにプッシュしていることが想像できます。これは可能性のある説明ですか?私に何ができる?
ありがとうございます!
更新:これも1秒未満で実行されます(ただし、どちらの行のコメントも付いていないので、極端に遅くなります)。これはループに他の変更を加えることなく、value1は以前と同じ場所で宣言されています。
for (int ii=0; ii<someNumber;ii++)
{
for (int jj=0; ii<someNumber2;jj++)
{
// value1 = value2 + value3;
// value1 = value1 * someFunction(a,b,c);
}
double nothing = value1;
}
UPDATE 2:示されるようにコードが実際value1
の宣言と、このような別のループ内にネストされた:
double value1=0;
for (int kk=0; kk<someNumber3;kk++)
{
for (int ii=0; ii<someNumber;ii++)
{
for (int jj=0; ii<someNumber2;jj++)
{
value1 = value2 + value3;
value1 = value1 * someFunction(a,b,c);
}
double nothing = value1;
}
}
value1
が宣言される移動はまた、迅速な場合に私たちを取り戻します。
for (int kk=0; kk<someNumber3;kk++)
{
double value1=0;
for (int ii=0; ii<someNumber;ii++)
{
for (int jj=0; ii<someNumber2;jj++)
{
value1 = value2 + value3;
value1 = value1 * someFunction(a,b,c);
}
double nothing = value1;
}
}
OpenCLは非常にトリッキーなアートです!私はまだ何が起こっているのか本当に理解していないが、少なくとも私はそれを今修正する方法を知っている!
これはかなり奇妙です。より低速なバージョンを使用する必要がありますか?これらのスニペットから、機能的には同じように見えます。 – Chriszuma
ご返信ありがとうございます。はい、私は確信していますが、私が与えた例は機能的に同一であるということは間違いありません。内側の中括弧内のコードは+ =を持つべきです。 – carthurs
これらのコードスニペットに基づいて、2番目のものが遅くなる必要はありません。私は、割り当てを移動すると、分岐の増加(1つのワークユニットが 'if'を実行し、次にelseが' else'を実行する)などの副作用があるはずだと推測します。 –