В конце января 2012 года компания-разработчик терминала MetaTrader 5 анонсировала нативную поддержку OpenCL в MQL5. В статье на конкретном примере изложены основы программирования на OpenCL в среде MQL5 и приведены несколько примеров "наивной" оптимизации программы по быстродействию.
This article focuses on some optimization capabilities that open up when at least some consideration is given to the underlying hardware on which the OpenCL kernel is executed. The figures obtained are far from being ceiling values but even they suggest that having the existing resources available here and now (OpenCL API as implemented by the developers of the terminal does not allow to control some parameters important for optimization - particularly, the work group size), the performance gain over the host program execution is very substantial.
私のコードのどの部分に興味があるのでしょうか?異なるファイルに依存することが多いのですが。
今抱えている問題は、テスターの1tickでバッファの書き込みと読み出しを行うだけで、チェックには十分なのです。
スクリプトによる実行。
2013.10.30 18:55:40 OpenCL_buffer_test (EURUSD,H1) デバイス#0 = Cypress
2013.10.30 18:55:40 OpenCL_buffer_test (EURUSD,H1) OpenCL: GPUデバイス 'Cypress' が選択されました。
2013.10.30 18:55:40 OpenCL_buffer_test (EURUSD,H1) build log =.
2013.10.30 18:55:40 OpenCL_buffer_test (EURUSD,H1) バッファサイズ(バイト) =240
テスターで2013.01.09から2013.10.10まで、M5で「OHLC on M1」を使ってエキスパートを実行中です。
2013.10.30 19:01:44 Core 1 2013.01.09 00:00:00 Device #0 = Cypress
2013.10.30 19:01:44 Core 1 2013.01.09 00:00:00 OpenCL: GPU デバイス 'Cypress' が選択されました。
2013.10.30 19:01:44 Core 1 2013.01.09 00:00:00 ビルドログ=。
2013.10.30 19:01:44 Core 1 2013.01.09 00:00:00 バッファサイズ(バイト) =240
2013.10.30 19:04:55 Core 1 EURUSD,M5: 1108637 ticks (55953 bars) generated within 192443 ms (total bars in history 131439, total time 192521 ms)
2013.10.30 19:04:55 Core 1 294 Mb メモリ使用量
テスターには1つのデバイスしかないことに注意してください。
もし
//CLBufferRead(hbuffer[1], price);
では
OHLCのデータで計算を行う必要がある場合は、あらかじめ大きめのバッファを作っておき、新しいデータが来たときだけ、新しい始まりとバッファの大きさをカーネルに伝えて上書きする、いわゆるスペアライティングが必須となるのです。
OHLC転送を最適化できたとしても(CLSetKernelArgを 使用して最後のバーを転送します)、結果バッファを読み込む際にクラッシュします。
では、誰がそれを阻んでいるのでしょうか?おとぎ話にならないようなリアルなものを書いてきてください。しかし、加速が起こるような例を探してみてください。ここが一番難しいところです。
私の記事についてなら...まあ、入門書を書いていたんですけどね。そして、行列の掛け算はなかなか便利な操作です。
追伸:ちなみに、CPUがIntelの場合、その CPUでのx86コアのエミュレーションは他社製CPUよりもはるかに高速になります。それは、コアごとに計算し直した場合です。
HD5850:基本的にはかなりまともなカードですが、最近のカードはより良くなっています - フライが増えただけでなく、OpenCLの最適化により、です。例えば、グローバルメモリアクセスタイムを大幅に短縮することができます。
P.P.S. OpenCL は万能ではなく、ごく稀に著しく高速化することができる実行可能なツールです。また、それ以外のあまり便利でないケースでは、加速度があまり印象的でない--あったとしても。
え...GPUでOpenCLを使った高速化に関する記事は、実際のタスクを扱っていないため、おとぎ話であることが判明しました :(
そうではありません。 おとぎ話では、「どんなアルゴリズムでもOpenCLで高速化できる」とされています。 どんなアルゴリズムでもというわけではありません。
OpenCLの最初のスレッドでは、アルゴリズムがOCLアクセラレーションの可能性を持つために持っていなければならない基準について、非常によく説明されています。
頑張ってください。
計算速度ではなく、2倍の高速化(0.02ms vs 0.05ms)を実現しました。
記事には情報がない、という主張です。
お約束を読んで、GPUを犠牲にしてでもテストを早くしたいと思ったのは、たぶん私が初めてだと思います...。
私の投稿をもう一度読んでみてください。
主な基準:「OpenCLスタイル」でのMQLコードの実行は、1tickで時間 =Number of_Buffers * 0.35300 msを 超える必要があります。
マイクロ秒(1000マイクロ秒=1ミリ秒)の精度でMQLのアルゴリズムの速度を知るには、テスターとTotal_Time / Number_of_Ticks(私のトップポスト)で何回か実行する必要があります。
これは、「OpenCLスタイル」のMQL(55秒)の2倍、通常のコード(320秒)の11倍の速さです。
他にどんな基準があるのでしょうか?
OpenCLを扱った経験から判断すると、すべてのアルゴリズムが直接的に高速化されるわけではないことは、すでに理解されているはずです。ここで大きな問題となるのが、グローバルメモリアクセスの最小化です。
ちなみに、今はグローバルデバイスメモリへのランダムアクセスについても同様の問題を解決しなければならない(このランダムアクセスがプライベートすぎて、クソオーバーヘッドになっている)。頭の回転が戻り次第、解決していきます。
テスターがOpenCL用のCPUを選択しない - これはどこにも報告されていません!
サービスデスクに、そのような機能が必要であることを説明する。
テスターを使わなければ、もう終わりです(これは私の用途です)。そして、テスターでの確認はまだしていません。
すべてのアルゴリズムが直接的に高速化されるわけではないことは、すでに述べたとおりである。ここで頭を使わなければならないのですが、大きな問題のひとつは、グローバルメモリアクセスを最小限にすることです。
さて、今度はグローバルメモリへのランダムアクセス(このランダムアクセスが頻繁すぎる)についても、同様の問題を解決しなければなりません。頭を働かせたらすぐに解決します。
0.35300msはまさにclEnqueue[Read/Write]Buffer()のことで、カーネル 内のグローバルメモリアクセスのことではないので、頭を使うときが来たのでしょう。
2つ目はカーネル自体の最適化で解決できますが、1つ目は鉄の限界です。