OpenCL:真のチャレンジ - ページ 7

 

1) Pragmasはコンパイル時のサポート要件であり、サポートの活性化そのものではない(とお考えのようです)。そのため、お使いのVisがサポートしていれば、cl_khr_fp64はすでに関与しています。

2) 実行時に配列のサイズが変化した場合は?もちろん、この特殊なコードでも可能ですが、状況は改善されません。

早速ですが、私はAMD CodeXLで プロファイリングをしていました。

3)カーネル自体の計算時間だけを 考えれば、GPU上で並列化されたタスクは、CPUのコアをより多く利用することで利益を得ることができます。だから、8つのタスクでも十分にスピードアップできる。

4)私自身、Localの計算式について、いろいろと疑問があります。work_dim=1 のときに、タスクをウィジェットの全コアに分散させると、最大の効果が得られました。

また、バッファの要素数を分割すべきなのに、なぜ一般的にバッファサイズを分割するのでしょうか?- を、実際にやってみた。

Mathemat: 要するに、あなたのコードは何をしなければならないのか?

計算の準備段階が瞬時でないこと、バッファの転送に多くの時間がかかることを示すために、燃料を使うタスクであってもOpenCLを使う ことの実用性を問うているのです。

また、テスターでCPUが選択されていないことも表示されます。

 
Roffild:

計算の準備段階が瞬時でないこと、バッファの転送に十分な時間がかかることを示し、大げさなタスクであってもOpenCLを使う ことの実用性に疑問を投げかけているのです。

つまり、それを叫ぶのは非常に愚かなことで、一方、それを測定することは全く別の問題であり、実際的に役に立つかもしれないのです。

また、テスターでCPUが選択されていないことも表示されます。

テストプロセス自体の効率化というか、最適化(マルチスレッド化)を意識してのことでしょう。 テストと最適化の概念を(政党政治のレベルで)明確かつ完全に分離する、つまり、テスターの使用方法を異なる論理タイプとして定義すれば、インクルージョン達成のチャンスが訪れるかもしれません。 それに対応する(公式に異なる)ソフトウェアのサポートがあれば。(これは多くの点で良いことで、私はこのような分離/区別を長年支持しています。 最適化とテストを開始するための異なるボタンに至るまで)。

理論的には、テスト時にはCPUの選択を許可し、最適化時には不許可にすることができます(これは正しいです)。

 
Roffild: 1) プラグマはコンパイル時のサポート要件であり、サポート自体の活性化ではありません(あなたが考えているようなことです)。つまり、内臓がサポートしていれば、cl_khr_fp64はすでに関与しているのです。

ええ、プラグマはやりすぎましたね。もし、あなたが自分のウィジェットに取り組み続け、コードを他の人に渡さないのであれば、問題はありません。しかし、もし誰かがBartsカード(例えば6870)で読みたければ、問題が発生するでしょう。カーネルコードは、エラーを表示せずに実行しようとします。

4)Localの計算式については、私自身、疑問が多いのです。最大の効果は work_dim=1 がタスクをウィジェットの全コアに分散させた場合であり、これは UNITS である。

必ずしもそうではありません。カーネル自体の作業を増やす方がよっぽど有益なことが多い。データ転送に伴うオーバーヘッドを平準化するためです。

そして、UNITSはSIMDエンジンの数に過ぎないのですね。ドキュメントに よると

local_work_size[] は、 指定されたOpenCLプログラムカーネルで実行されるタスクのサブセットを設定 します。 その次元は work_items[] 同じ であり 分割残余なしに タスクの総サブセットをより小さなサブセットに切断することができる。実際、配列 local_work_size[]のサイズは グローバルなタスクセット work_items[] より小さなサブセットにスライス される ように選択する必要が ある。 この例では 配列 local_items[10, 10, 10] から work_items[40, 100, 320] 残らずに組み立て られるのでlocal_work_size[3]={10, 10, 10} よい

SIMDエンジン数は、厳密にはハードウェア定数であり、グローバルタスクを分割する必要は全くない。

しかし、その前にグローバルな問題そのものをきちんと評価する必要があります。

テスターのCPUについてですが、なるほど、納得です。

 
MetaDriver:

まあ、これは全くニュースではないのですが。 つまり、それを叫ぶのは愚かなことですが、測定することは全く別の問題で、実用上役に立つことがあるのです。

ただし、なぜかこのような計測をすることになったのですが...。伝送遅延がある」と読んでも、それがどの程度の大きさなのか、見当がつかない。

数学:そして、あなたのUNITSはSIMDエンジンの数に過ぎません。ドキュメントに よると

SIMDエンジンの数は、厳密にはハードウェアの定数であり、グローバルタスクを分割する必要は全くないのです。

公式ドキュメントを もっと活用しよう。

CL_DEVICE_MAX_COMPUTE_UNITS cl_uint OpenCLデバイスの並列計算ユニット数です。ワークグループは1台のコンピュートユニットで実行されます。 最小値は1である。
local_work_size。
カーネルで指定されたカーネルを実行するワークグループを 構成するワークアイテムの数(ワークグ ループのサイズとも いう)を記述した work_dim unsigned 値の配列を指す。
つまり、私の結論は正しく、AMD CodeXL の 実行によって確認されたのです。
 

ポイントが違うんです。しかし、あなたのコードのunitsはグローバルタスクを整数で割らないという事実は変わりません(私のは確かにそうです:240/28は整数ではありません;あなたのもunits=18なのでそうです)。これはバグです。

そして第二に、今ここであなたはMQL5用のOpenCLを扱って いる(まあ、それは正しくないのですが、でも、あなたは私を理解しました)。

追伸:ハイパーリンクは私が作ったのではなく、私が勝手につけたものです :)

Roffild:
CL_DEVICE_MAX_COMPUTE_UNITS cl_uint OpenCLデバイスの並列計算ユニット数です。ワークグループは1台のコンピュートユニットで実行されます。 最小値は1である。

計算単位の定義については、他の資料を参照してください。

ちなみに、2回目の記事で紹介した表がこちら。コンピュートユニット(18)、ストリームコア(288)、プロセッシングエレメント(1440)、最大波面/GPU(496)、ワークアイテム/GPU(31744)、これらすべてを理解していればいいのですが...。まだ、わかっていないんです。


 
Mathemat:

ポイントが違うんです。しかし、あなたのコードのunitsはグローバルタスクを整数で割らないという事実は変わりません(私のは確かにそうです:240/28は整数ではありません;あなたもunits=18なのでそうです)。これは不具合です。

では、なぜ240バイトを基準にしたのでしょうか?できるかもしれないが、グラフィックカードはできない。つまり、240/8=30倍。

240バイトは、30ダブルのバッファ全体のサイズです。

また、「仕切りごとを選ぶ」というのは、あくまで 公式のドキュメントからの推奨 事項です。そして、その推奨が完璧に機能するわけではありません。

また、UNITSについてどうこうというのは、私自身のものではなく、OpenCLのフォーラムからのアドバイスに過ぎません。テストしてみたら、最高速度が出た...。

数学

そしてもうひとつは、今ここでMQL5用のOpenCLを扱って いますが、これは結局のところ、Khronosによるものとは異なるOpenCLなのです(まあ、それは正しいとは言えませんが、ご理解いただけたでしょうか)。

そして、「もうひとつ」とは何でしょうか?

独自実装と単純なラッパーを混同しているのでは?OpenCL MQLは、KhronosのOpenCL APIのラッパーに過ぎません。OpenCL MQLとKhronosの違いについて。

 
Mathemat: ちなみに、2回目の記事の表はこちらです。コンピュートユニット(18)、ストリームコア(288)、プロセッシングエレメント(1440)、最大波面/GPU(496)、ワークアイテム/GPU(31744)、これらすべてを理解していればいいのですが...。まだ、わかっていないんです。

コンピュートユニットは、同時に実行されるタスクの数です。

max wavefronts/GPU (496) と work-items/GPU (31744) が実行されるキューです。

AMD CodeXLは、これらの疑問に対してすでに答えを出しています。

 
Roffild:

コンピュートユニットは、同時に実行されるタスクの数です。

max wavefronts/GPU (496) と work-items/GPU (31744) が実行キューになります。

AMD CodeXLは、これらの質問にすべて答えてくれるのです。

すまないが、君はアレクセイを個人的に知っているか?でも、傍から見たら、そんな風には見えませんね......生意気なことを言う、人より賢い? 賢いことは罪ではありません。

 

私は単純な男なので、要領よく答えます。

思い込みではなく、本当にOpenCLを理解したいのであれば、AMD CodeXLを入れて、自分でC/C++のラッパーを作るしかないでしょう。

私のラッパーを掲載することができますが、私のC/C++の練習不足のため、非論理的な行がいくつかあります。

 
Roffild: では、なぜ240バイトを基本数値としたのでしょうか?できるかもしれないが、ビデオカードはできない。つまり、240/8=30倍の倍率。

240バイトは30ダブルのバッファ全体のサイズです。

自分のコードを見てください。

uint units = (uint)CLGetInfoInteger(hcontext, CL_DEVICE_MAX_COMPUTE_UNITS);
uint global_work_offset[] = {0};
uint global_work_size[1];
uint local_work_size[1];
global_work_size[0] = ArraySize(price);
Print( "Глобальная задача = ", global_work_size[0] );  /// Это я добавил, вышло 240. Но это и так легко подсчитать: 30*double = 240
local_work_size[0] = global_work_size[0] / units;

さらに、最後の行では、あなた自身が240を18で割っています(これはマップの単位です)。

また、「仕切り板ごと拾う」というのは、あくまで 公式資料からの推奨 事項です。そして、この推奨は完璧には機能しない。

MQL5 OpenCLに取り組んでいます。弊社ホームページのドキュメントを参考にしています。もちろん、クロノスも見ています。

また、UNITSに関しては、私自身の言葉ではなく、OpenCLのフォーラムからのアドバイスです。テストして最高速度が出たのですが・・・。

まあ、パラメータを変えても最高速は出ましたけどね。それで?

ざっくりとしたイメージで結構です。GPUフライで18個のタスクが同時進行するのは、4~5ストリングのCPUでできる最大値です。そして、x86エミュレーションのCPUは、もっと多くのスレッドを整理することができます。少なくともインテルであれば。以前使っていたPentium G840(2コア)では、2台で約70倍という加速度を実現しましたもちろん、今の自分がどうなのかは言うまでもないが...。i7、いわば

うまく並列化されたタスク(最初のoclブランチのMetaDriver スクリプトを見てください)は、GPU上で1000以上の速度に達することができます(MQL5ではCPU上の1スレッドと比較して)。もし見つからない場合は、私がダウンロードして、あなたのカードで試してみることもできます。

もし、本当にOpenCLを理解したいのであれば、推測するだけでなく、AMD CodeXLを入れて、自分でC/C++のラッパーを作る必要があります。

OK、見てみますね、ありがとうございます。