エラー、バグ、質問 - ページ 2284

 
Nikolai Semko:

テロップはRAMに保存されません。必要に応じて、断片的にダウンロードされると理解しています。

実際の刻みでなら、そうです。

一度のパスで、ティックストレージにどれだけのメモリが費やされているかの統計情報を見ることができます。最適化する場合、一度に320メガを超えてメモリに保存されることはありません。残りはディスクに保存されます。

現在、すべてのティックを共有メモリに保持し、すべてのローカルエージェントがこのメモリから読み取れるようにする解決策を検討しています。そうすると、ディスクアクセスがなくなり、最適化が速くなります。

 
Slava:

実際のダニによる場合は、そうです。

1回のパスでティックストレージにどれだけのメモリが費やされたかの統計を見ることが可能です。最適化された場合、一度に320メガを超えるメモリは保存されません。それ以外はすべてディスクに収めています。

現在、すべてのティックを共有メモリに保持し、すべてのローカルエージェントがこのメモリから読み出せるようにする解決策を検討しています。そうすると、ディスクアクセスがなくなり、最適化が速くなります。

そう、これはアーカイブなんです。私の理解が正しければ、現在、ティックと分バーはディスクとメモリにアンパックされて保存されており、すなわちバー(MqlRates構造体)は60バイト、ティック(MqlTick構造 体)は52バイトになります。
恐るべし!とっくにどうにかしているはずだ。

圧縮配列の主な問題は、配列の各項目への高速アクセスを整理することだと理解しています。

しかし、配列の256番目の要素だけをアンパックしておき、それ以外の要素にはアンパックした要素の増分だけを格納したとしても、配列のサイズは4〜5倍になり、各要素へのアクセス時間はそれほど増加しない(1〜2ナノ秒程度)ことがわかりますが、ディスクからの保存とディスクへの読み込みにかかる時間は大幅に短縮されることになります。

 
fxsaber:
最適化中にSSDが常にアドレスされている(ランプが高速で点滅している)のはなぜですか?

そのため、ティックを使わず、対数データ構造(すでにお話しました)を使っています。ある時点で、数千のティック、数千の分バー、2000 M2, 2000 M5 , M10, M30, H1, H3, H6, H12, D1, W1... からなります。全てのMN1バーを対象としています。
この全履歴データの構造は、1ミリ秒未満の任意の瞬間に形成され、RAMでわずか1.5MBを占める(実際にはRAMですらなく、プロセッサのキャッシュの中である)。そして、この構造に対して接地されたすべてのアルゴリズムが、ただ飛ぶだけなのです。

視力は、遠くを見れば見るほど、細かいところに気がつかなくなるという、対数的な構造になっているのです。

そう遠くない将来、コンピュータの物理メモリデバイス(ハードディスク、RAM、プロセッサキャッシュ)が1つだけになり、プロセッサキャッシュに13個のゼロが入るようになったら、私もティックに切り替えようと思っています :))

...

とはいえ、最適化の際にこのようなデータ構造では電球もチカチカするので、邪魔なのかもしれませんが。結局のところ、ティックはまだ搭載されることになる :(

 
Slava:

実際のダニによる場合は、そうです。

1回のパスでティックストレージにどれだけのメモリが費やされたかの統計を見ることが可能です。最適化された場合、一度に320メガを超えるメモリは保存されません。それ以外はすべてディスクに収めています。

現在、すべてのティックを共有メモリに保持し、すべてのローカルエージェントがこのメモリから読み取れるようにする解決策を検討しています。すると、ディスクへのアクセスがなくなり、最適化が高速化されます。

まず、Optimizationのログから説明します。

Tester  optimization finished, total passes 714240
Statistics      optimization done in 7 hours 31 minutes 06 seconds
Statistics      local 714240 tasks (100%), remote 0 tasks (0%), cloud 0 tasks (0%)
Core 1  connection closed
Core 2  connection closed
Core 3  connection closed
Core 4  connection closed
Core 5  connection closed
Core 6  connection closed
Core 7  connection closed
Core 8  connection closed
Tester  714240 new records saved to cache file 'tester\cache\Test.FILTER_EURUSD.rann_RannForex.M1.20180226.20180909.40.2D734373DF0CAD251E2BD6535A4C6C84.opt'

この7.5時間の間、SSDには膨大な頻度でアクセスがあった。仮に1回ごとにダニを読み取った場合、1秒間に平均26回、7.5時間の計算になる。それゆえ、このような乱暴な瞬き-70万回以上も読まれたのである。


シングルランログ

Core 1  FILTER_EURUSD.rann_RannForex,M1: 132843 ticks, 60283 bars generated. Environment synchronized in 0:00:00.140. Test passed in 0:00:00.827 (including ticks preprocessing 0:00:00.109).
Core 1  FILTER_EURUSD.rann_RannForex,M1: total time from login to stop testing 0:00:00.967 (including 0:00:00.140 for history data synchronization)
Core 1  322 Mb memory used including 36 Mb of history data, 64 Mb of tick data

見ての通り、130Kティックと60Kバーが使用されています(Testerでは "Entire history "モードが選択されています)。つまり、ごくわずかな歴史しかないのです。

端末のカスタムシンボルの 履歴は、以下の量の履歴データが含まれています。

Saved ticks = 133331
Generated Rates = 60609

すなわち、シンボルの歴史において、テスターが使用するものよりも非常に少ないものです。


ZS SSDを見るのは残念ですが...。Optimiseはどこまで速くなるのでしょうか?非圧縮で7MB弱の刻みなので、OSがこのデータをキャッシュしないのは不思議です。

 
Nikolai Semko:

しかし、配列の256番目の要素だけをアンパックして保存し、アンパックしていない要素には増分だけを保存したとしても、配列のサイズは4-5倍になり、各要素へのアクセス時間はそれほど増加しない(1-2ナノ秒程度)ものの、ディスクからの保存とディスクへの読み込みにかかる時間は大幅に短縮されることになるのです。

レナーテだけでは物足りないあなたへ )履歴保存の最適化は何度提案されたことか。特に、一番リソースを消費する圧縮には何も費やす必要がありません。なぜなら、データは最初に圧縮されてサーバーから送られてきて、常に使用されるキャッシュだけが解凍された状態で保管されるからです...。しかし、そこで必ず出てくるのが、「もっと大きい、もっと速いハードディスクが買えないと、MTではどうしようもない」という講義です。 そして、遅いVPSがなぜか必ず出てきます。

 
Alexey Navoykov:

レナーテだけでは物足りないあなたへ )履歴保存の最適化は何度提案されたことか。特に、元々データは圧縮されてサーバーから送られてくるので、(最もリソースを消費する)圧縮に何も費やす必要がなく、常に使用されるキャッシュのみが解凍された状態で保持されるからです...。しかし、そこで必ず出てくるのが、「もっと大きい、もっと速いハードディスクが買えないと、MTではどうしようもない」という講義です。 そして、遅いVPSがなぜか必ず出てきます。

繰り返しになりますが、パックアレーの主な問題は、配列の要素を 順次読み込むのではなく、任意の要素に素早くアクセスできるように整理することです。だからこそ、ここでは別の圧縮形式(というか保存形式)が必要なのです。そう、解凍したり梱包したりする必要がないような。zipやpngなどのように〜10倍圧縮はもちろん無理ですが、5倍は可能だと思います。

まあ、実際、考えてみると、MqlRatesでは1分足の小節の情報を格納するために8*4=32バイトが割り当てられているが(一方、1分足の小節だけが格納されている)、99%の場合、これらの値は1バイト以下の情報しか違わず、つまり8+1+1+1=11バイトで、前の小節と結合しないとしてもほぼ十分なのだ。そして、99%の場合、時間は前の値とちょうど60だけ異なる(つまり、99%の場合、1ビットの情報で十分である-60か60でないか)。そして、このためにも8バイトが割り当てられている。

 
Nikolai Semko:

繰り返しになりますが、パックアレーの主な問題は、配列の要素を 順次読み込むのではなく、任意の要素に素早くアクセスできるように整理することです。だからこそ、ここでは別の圧縮形式(というか保存形式)が必要なのです。そう、解凍したり梱包したりする必要がないような。もちろん、zipやpngなどは〜10倍の圧縮は無理ですが、5倍は可能だと思います。

ディスク上のストレージの場合、ファイル操作自体にコストがかかるため、特定の項目へのアクセスは意味がない。 そのため、大きな塊を一度に読み込む。 例えば、バーヒストリーのファイルは年単位、ティックは月単位で分解される。また、履歴をメモリにパックした状態で保持し、常に各要素をその場で解凍していくということであれば、残念ながら誰にも合いませんね。

 

つまり、2900/256= ~12バイトがMqlRates構造体 ごとに割り当てられ、これは思ったより5倍少ない。

MqlRates構造体の各要素へのアクセスは十分速い(2-3回の合計、2-3回のチェック、2-3回のシフト、つまり1ナノ秒以上にはならない)。

 
Alexey Navoykov:

ディスクに保存する場合、特定の要素にアクセスすることは、ファイル操作自体にコストがかかるため意味がない。 そのため、大きな塊を一度に読む。 例えば、バーヒストリーのファイルは年単位、ティックは月単位で分割される。また、履歴をメモリにパックした状態で保持し、常に各要素をその場で解凍していくということであれば、残念ながら誰にも合いませんね。

ディスクに「圧縮」された形で保存され、また同じ形式でメモリに読み込まれることになります。完全なフォーマットへの変換は行われず、MqlRates構造体の 特定の要素を読み込んだ瞬間に計算が行われるだけである。また、ディスクの作業が5倍少なくなることを考慮すると、より高速になることでしょう。

 
Nikolai Semko:

パックされたMqlRates構造体の各要素へのアクセスは非常に高速です。

...

ディスクに「圧縮」された形で保存され、同じ形式でメモリに読み込まれることになります。完全なフォーマットへの変換は行わず、MqlRates構造の 特定の要素を読み込んだ瞬間の計算結果のみを表示することになる。

しかし、この場合の「速い」という概念は非常に相対的なものです。 一つは、ユーザーがバーの配列を要求した場合、彼は単にメモリの一部をコピーした、またはいくつかの特定の時系列の要求、それはまた、構造のサイズと同じ、一定のステップでデータをコピーする単純なものであることです。そしてもうひとつは、各数値の上に計算や変換を追加していることです。

とはいえ、個人的には、どうせ保存用のアレイを自前で整理しているのだから、メモリを無駄にしないためにも、履歴は圧縮しておきたいところです。だから、少々の遅れは大目に見ています。しかし、他のほとんどのユーザーは、そのためにあなたを切り刻むでしょう )

p.s. 理想的なのは、端末で履歴のメモリへの保存方法を選択できるようなオプションがあるといいのですが。例えば、RAMが少なくても高速なプロセッサを搭載している場合、非常に有効な手段です。