私はプログラムスコープで宣言したので、生成後に多くのスレッドで読み込まれる行列を生成したいと思います。それは一定でなければならないので、私は値を一度割り当てているだけです。OpenCLは定数空間で変数の初期化を遅らせることができません
1)なぜopenClは宣言中に初期化を求めていますか?
2)この問題を解決するにはどうすればよいですか?
私はプログラムスコープで宣言したので、生成後に多くのスレッドで読み込まれる行列を生成したいと思います。それは一定でなければならないので、私は値を一度割り当てているだけです。OpenCLは定数空間で変数の初期化を遅らせることができません
1)なぜopenClは宣言中に初期化を求めていますか?
2)この問題を解決するにはどうすればよいですか?
1)どのスレッドがどの要素を書いているのかをgpuに伝えることはできません。定数は、パラレルエンジンではなくスカラーエンジンを使用するプリプロセッサによって準備されます。パラレル・エンジンでは、それを達成するためにN×N回の同期が必要です。ここで、Nは定数バッファーの作成に関与するスレッドの数です。
2-a)定数メモリを扱う場合は、カーネル内に単純な(__グローバルで定数ではない)バッファを用意し、次のカーネルで定数バッファとして使用します(エンジンは定数メモリ空間に配置します)。しかし、一定のスペースは小さいので、マトリックスは小さくなければなりません。これにはカーネルオーバーヘッドを意味する2つのカーネルが必要です。
2-b)キャッシュのパフォーマンスが十分であれば、バッファを使用してください。したがって、単一のカーネル内に存在することができます(最初のスレッドグループは行列を作成し、残ったものはそれを使って計算し、最初のグループはアトミック関数を使って信号を与えます)
2-c)ローカルメモリが定数メモリより大きい場合、ローカルメモリを使用して、各計算単位ごとにそのマトリックスを構築することができます。したがって、同じ量のサイクル(おそらくすべてのコアを使用する場合はそれよりも少ない)を取る必要があります。これはスレッドグループ間の通信を必要としないので、高速になります。
2-d)行列が大きく、ほとんどの帯域幅が必要な場合は、すべてのメモリスペースに配布します。例:行列の1/4を定数メモリ(5倍の帯域幅)に入れ、行列の1/4をローカルメモリ(10倍の帯域幅)に入れ、行列の1/4を大域メモリ(キャッシュの性能から2倍)に置き、残りのデータを複数のスレッドが4つの異なる場所で同時に動作し、すべての帯域幅(定数+ローカル+キャッシュ+命令キャッシュ)を使用するようになりました。