MT5とスピードの関係 - ページ 45

 
Andrey Khatimlianskii:

いや、CentOSでバーチャライザーが回ってるんですよ。しかし、私はこの対話を続ける能力がない。

どうせ二重仮想化なんだから。

CentOS → VirtualBox → Windows 7


また、CPUが8コアのときに2コアに削減すると、スレッドシェジュラーの動作や割り当てリソースが大きく変化します。

この2コアを、切り詰めたWindows 7でも必然的に1000スレッドに割り当てる必要があります。つまり、端末はレイテンシーが増加することが保証されているのです。

 
Renat Fatkhullin:

あなたは、相関関係や合理性をコントロールせずにストレステストを行う名人です。

もちろん、マイクロ秒計測には、ミリ秒の1000分の1のギャップを計測できるリソースが必要です。

超精密な間隔を測定する必要がある 場合は、マイクロ秒 を使用します。そして、そのコストは0マイクロ秒になります。

マイクロ秒が足かせになるのに、どうやって使うんだ!?ここでは、合計20のコールを紹介します。様々な実用的なタスクのために、このようなばかげた数の呼び出しに 1/4ミリ秒をかける。

2020.10.06 00:50:44.491 Alert: Time[Test6.mq5 15: for(inti=0;i<20;i++)GetMicrosecondCount();] = 254 mсs.
2020.10.06 00:50:44.491 Alert: Time[Test6.mq5 20: for(inti=0;i<20;i++)GetTickCount();] = 19 mсs.

息苦しいVPSでは、timeBeginPeriodを使ったシステムタイマーのオーバークロックは危険と隣り合わせです。単純にCPUのオーバーヘッドが増えるだけでしょう。

そうでなければ、とっくにOSでGetTickCount/GetTickCount64を正確にして、自由な精度を喜んでいることでしょう。しかし、いや、このタイマーの精度は有料なのです。


GetTickCountは決して速度が劣っているわけではありません。GetMicrosecondsCountの代わりに遅いVPSで使う ように変更しました。実取引で50%から2%に負荷が下がった。

2020.10.06 00:50:44.491 Alert: Time[Test6.mq5 26: for(inti=0;i<20;i++)winmm::timeGetTime();] = 13 mсs.
 
fxsaber:

減速しているのはマイクロ秒なのに、どうやって使うんだ!?ここでは、わずか20のコールを紹介します。様々な実用的なタスクのために、このようなばかげた数の呼び出しで 1/4ミリ秒。

そして、この20本の電話がある。

   ulong ticks=GetMicrosecondCount();
   for(int i=0; i<20; i++)
      GetMicrosecondCount();
   Print("GetMicrosecondCount: ",GetMicrosecondCount()-ticks);

   ticks=GetMicrosecondCount();
   for(int i=0; i<20; i++)
      GetTickCount();
   Print("GetTickCount: ",GetMicrosecondCount()-ticks);


2020.10.06 01:04:44.068 5555 (CAT.NYSE,M5)      GetMicrosecondCount: 1
2020.10.06 01:04:44.068 5555 (CAT.NYSE,M5)      GetTickCount: 0


GetTickCountは決して速度が劣っているわけではありません。GetMicrosecondsCountの代わりに遅いVPSで使う ように変更しました。実取引で負荷が50%から2%に下がった。

GetMicrosecondsCount -> GetTickCountに置き換えても、実際のプログラムでは得られないと思います。理論的にも現実的にも根拠がない。

この2つの機能のストレステストでは、このような結果を容易に導き出すことができます。CPU負荷の48%はマイクロ秒単位で計測していたと自分で結論付けているのでしょうか?これはストレステストではないのですか?もちろん、そうです。


マルチメディアタイマーアクセラレーションについてですが、これは全体の性能劣化を見ずに、またストレステストをしています。タスクシャフラーをオーバークロックすると、OSのシステムオーバーヘッドが増加します。

 
Renat Fatkhullin:

まだデュアル仮想化。

CentOS → VirtualBox → Windows 7


また、CPUが8コアの時に2コアに減らすと、スレッドシェジュラーの動作や割り当てリソースが大幅に変わります。

この2コアを、切り詰めたWindows 7でも必然的に1000スレッドに割り当てる必要があります。つまり、端末はレイテンシーが増加することが保証されているのです。

私もその結論に達しました、確認ありがとうございます。VirtualBoxは邪道 ですね。

ハードウェア上の純粋なオペレーティングシステムのみで、できればLinuxが望ましいです。Wine経由ですが、同じ仮想化でも、ターミナルのGUIは一度もラグなく飛びますね。

そして、GetMicrosecondsCountは、何のラグもなく転がっていく。

 
Renat Fatkhullin:

そして、この20本の電話がある。

まあ、私にとってもゼロマイクロ秒ですからねー。自宅のマシンのみ。

GetMicrosecondsCount -> GetTickCountに置き換えても、実際のプログラムでうまくいくとは思えません。理論的にも現実的にも、証明するものはないのです。

ストレステストでは、この2つの関数を使うことで、このようなエラーを簡単に描くことができます。CPU負荷の48%はマイクロ秒単位で計測していたと自分で結論付けているのでしょうか?これはストレステストではないのですか?もちろん、そうです。

このスレッドをきっかけに、私はBenchmarkライブラリを書き、ソースに実行時のチェックを簡単に挿入できるようにしました。そして、そのことを大いに利用し、多くの悪いものを明らかにし、排除していったのです。

そのため、このような改造を施したExpert Advisor(正確には20個のEAを並列に使用)は、自宅のコンピュータに1.5%の影響を与える。でも、VPSは50%以上です。調べ始めたら、マイクロ秒のタイマーが遅くなっているのが目につきました。ホームマシンでアラートが発生しなかった場合、VPSは 失敗します。


しかし、それすらも十分とは言えなかった。このブランチのおかげで、スナップショットの仕組みが開発されたのだが、その基本はこうである。

  ulong Snapshot( const uint &RefreshTime, const MAGIC_TYPE &Magic, bool HistoryInit = false )
  {
    if (SNAPSHOT::SnapshotLifeTime() < RefreshTime)
      return(0);
// ....

  ulong SnapshotLifeTime( void ) const
  {
    static const bool IsTester = ::MQLInfoInteger(MQL_TESTER);

    return(IsTester ? ULONG_MAX : (::GetMicrosecondCount() - this.TimeData)); // Обязуем любой вызов снепшота в Тестере делать полноценным.
  }

これはすべてのスナップショットの基本です。最後のスナップショットから指定された時間未満しか経過していない場合は、何もしません。このようなアプローチで、リソースを大幅に節約することができるのです。

もちろん、更新時間は短く、デフォルトでは1ミリ秒である。そのため、マイクロ秒のタイマーが使われているのです。


このタイマーの遅さによって、本格的なスナップショットが一桁/二倍の頻度で取られるようになり、スナップショット機構が崩壊してしまったのです。


マイクロセカンドタイマーのブレーキから、そういうパイがある。しかし、ミリ秒タイマーに切り替えたところ(16msではなく)、遅いVPSでもすべてが飛ぶようになったのです。

マルチメディアタイマーの高速化についてですが、全体の性能低下を無視してまたストレステストをしています。タスクマスターのオーバークロックは、OSのシステムオーバーヘッドを増加させます。

このような理屈はどうでもよくて、実際には膨大な利益が得られるのです。おそらく、一部のゲームに影響があるのでしょう。しかし、VPSでは救いの手が差し伸べられたのです。

 
fxsaber:

まあ、私もゼロマイクロ秒なんですけどね~。自宅のマシンのみ。

このスレッドを見て、私はBenchmarkライブラリを書き、ソースに実行時のチェックを挿入するだけで済むようにしました。そして、このことを大いに利用し、多くの悪いものを明らかにし、排除していったのです。

このように書かれたExpert Advisor(正確には20個のExpert Advisorを並列に配置)は、家庭用コンピュータに1.5%の負荷をかけることになります。でも、VPSは50%以上です。調べ始めたら、マイクロ秒のタイマーが遅くなっているのが目につきました。ホームマシンでアラートが発生しなかった場合、VPSは 失敗します。


しかし、それすらも十分とは言えなかった。このブランチのおかげで、スナップショットの仕組みが開発されたのだが、その基本はこうである。

これはすべてのスナップショットの基本です。最後のスナップショットから指定された時間未満しか経過していない場合は、何もしません。このようなアプローチで、リソースを大幅に節約することができるのです。

もちろん、更新時間は短く、デフォルトでは1ミリ秒である。そのため、マイクロ秒のタイマーが使われているのです。


つまり、このタイマーの遅さのせいで、本格的なスナップショットが、本格的なマシンよりもはるかに頻繁に取られるため、スナップショット機構がクラッシュしてしまったのです。


そんな、マイクロ秒タイマーのブレーキのパイオニアです。しかし、ミリ秒タイマーに切り替えたところ(16msの代わりに)、遅いVPSでもすべてが飛ぶようになったのです。

こういう理屈はどうでもよくて、実利が莫大であればいいんです。ゲームによっては影響があるのかもしれませんね。しかし、VPSでは救いの手が差し伸べられたのです。

いかに美しく言われたかをご覧ください。

GetMicrosecondsCountの代わりに遅いVPSで使う ように変更しました。実取引で50%から2%に負荷が下がった。

結論は、「すべてはマイクロ秒単位のメーターブレーキが原因、スピードアップとはそういうものだ」と必然的になった。

それが突然、「私自身が論理的なミスで一桁大きい計算をしてしまった」と判明するのです。そしてGetMicrosecondsCountはこのエラーのトリガーに過ぎなかったのです。

GetTickCountへのReworkは、このエラーの修正・クラックであり、修正のコードは表示されませんでした。GetMicrosecondsCount → GetTickCountの置き換えだけではないから?

なぜ、すぐに言えなかったのでしょうか?


このロジックは、会計の明らかなブートストラップ(マイクロ秒からミリ秒へのジャンプ)と、スナップショット作成の多重軽減によって加速されたようです。
 
それを避けるためにSymbolInfoTickを スナップショットにするかどうかはまだ考え中です。
2020.10.05 12:52:35.963         Alert: Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 599 mсs.
2020.10.05 12:52:45.904         Alert: Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 245 mсs.
2020.10.05 12:52:45.904         Alert: Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 470 mсs.
2020.10.05 12:52:45.904         Alert: Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 722 mсs.
2020.10.05 12:52:45.904         Alert: Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 901 mсs.
2020.10.05 12:52:45.905         Alert: Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1726 mсs.
2020.10.05 12:53:00.123         Alert: Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 864 mсs.
2020.10.05 12:53:03.218         Alert: Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 112 mсs.
2020.10.05 12:53:04.493         Alert: Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 2134 mсs.
2020.10.05 12:53:10.013         Alert: Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1826 mсs.
2020.10.05 12:53:13.119         Alert: Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 114 mсs.
2020.10.05 12:53:18.008         Alert: Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 116 mсs.
2020.10.05 12:53:20.010         Alert: Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1095 mсs.
2020.10.05 12:55:55.033         Alert: Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 359 mсs.

CPU1.5%で20個のEAを挽くマシンでの話です。どのLatencyMonで見ても問題ないことがわかります。

MT5のアーキテクチャの何かが、実行中のすべてのEAに同時にこれらのラグを与えています。そして、私の分はありません。

 
Renat Fatkhullin:

GetTickCountへの変換は、このバグの修正・クラックであり、修正コードは表示されませんでした。GetMicrosecondsCount → GetTickCountの置き換えだけではないから?

なぜ、すぐに言えなかったのでしょうか。

私とのディスカッションは、見せるものの存在で区別されるのですが。何も隠さず、それどころかオープンに公開して いるのです。

確かにストレステストはありますね。他にビジュアルで見せる方法がなかったのです。


マトリョーシカ人形の形をした関数を想像してください。外側のマトリョーシカの寸法を測定します。同時に、内部の入れ子人形も測定しています。その結果、マイクロ秒ブレーキにより、外部の入れ子人形は実行時間に乱高下を見せ、一種アラートが乱発されることになる。明らかに、GetMicrosecondsCountの1回の呼び出しに10マイクロ秒はひどく高価です。だから、アラートを急いだんです。


フリーラフミリセコンドタイマーは、0μs、1000μs、2000μsのいずれかを出し始めた。これにより、Alertsの数が大幅に減少し、タイマー機能呼び出し時のブレーキが軽減されました。


ロジックから判断すると、明示的に会計をブートストラップし(マイクロ秒からミリ秒にジャンプ)、スナップショットの作成を何倍かに減らすことで高速化を実現した。


しかも、スナップショットなら、最高です。ロードアウトは、家庭用機と比べると(そこはマイクロ秒)、イマイチです。でも、VPSにあったものと比べたら、天と地ほどの 差がありますね。


SZZ 今、MQLのミリ秒タイマーが実現可能かどうかという話をしているのですが、残念ながらミリ秒タイマーは存在しません。これがないとVPSでスナップショットができない。

 
fxsaber:
こういうのを避けるために、SymbolInfoTickのスナップショットを検討中です。

CPU1.5%で20個のEAを挽くマシンでの話です。どのLatencyMonで見ても問題ないことがわかります。

MT5のアーキテクチャの何かが、実行中のすべてのEAに同時にこれらのラグを与えています。そして、私の分はありません。

以下は私のコードと安定した実行時間です:20のチャートを並行して数百または数千のマイクロ秒を発生させない。

   MqlTick Tick;
   ulong   ticks=GetMicrosecondCount();
   
   SymbolInfoTick(_Symbol,Tick);
   Print("SymbolInfoTick: ",GetMicrosecondCount()-ticks);


2020.10.06 02:14:18.234	5555 (CADJPY,H1)	SymbolInfoTick: 2
2020.10.06 02:14:18.765	5555 (EURNZD,H1)	SymbolInfoTick: 2
2020.10.06 02:14:19.063	5555 (EURNZD,H1)	SymbolInfoTick: 2
2020.10.06 02:14:19.180	5555 (CADJPY,H1)	SymbolInfoTick: 2
2020.10.06 02:14:19.180	5555 (EURCAD,H1)	SymbolInfoTick: 1
2020.10.06 02:14:19.245	5555 (EURNZD,H1)	SymbolInfoTick: 2
2020.10.06 02:14:19.523	5555 (CHFJPY,H1)	SymbolInfoTick: 1
2020.10.06 02:14:19.659	5555 (EURNZD,H1)	SymbolInfoTick: 2
2020.10.06 02:14:20.037	5555 (CADCHF,H1)	SymbolInfoTick: 2
2020.10.06 02:14:20.037	5555 (EURNZD,H1)	SymbolInfoTick: 2
2020.10.06 02:14:20.137	5555 (EURMXN,H1)	SymbolInfoTick: 2
2020.10.06 02:14:20.138	5555 (EURNOK,H1)	SymbolInfoTick: 2
2020.10.06 02:14:20.226	5555 (EURNZD,H1)	SymbolInfoTick: 2
2020.10.06 02:14:20.227	5555 (CHFJPY,H1)	SymbolInfoTick: 2
2020.10.06 02:14:20.525	5555 (AUDNZD,H1)	SymbolInfoTick: 1
2020.10.06 02:14:20.645	5555 (EURNZD,H1)	SymbolInfoTick: 2
2020.10.06 02:14:20.919	5555 (EURNZD,H1)	SymbolInfoTick: 2
2020.10.06 02:14:21.123	5555 (EURNZD,H1)	SymbolInfoTick: 1
2020.10.06 02:14:21.129	5555 (EURAUD,H1)	SymbolInfoTick: 2
2020.10.06 02:14:21.234	5555 (EURNOK,H1)	SymbolInfoTick: 1
2020.10.06 02:14:21.441	5555 (EURAUD,H1)	SymbolInfoTick: 2
2020.10.06 02:14:22.299	5555 (EURNZD,H1)	SymbolInfoTick: 2
2020.10.06 02:14:22.383	5555 (AUDNZD,H1)	SymbolInfoTick: 2


コア数とプロセッサーの種類は?i7-2600?

何百万ものリクエストを並行して行う、もうひとつの隠れたストレステスト?


より透明性を高める。単純な_Bコールを数回掲載しただけで、他の主張の証拠にはなりません。突拍子もない主張をした途端、コードや実際の条件の説明を急に忘れるんですね。

頭の中で何も想像する必要はありません。実際に電話をかけてテストしたことを伝え、見せてください。未知のストレステストを実行し、世界に示すアラートを待つ」という破廉恥な結果ではなく、まさにテストの全コードを表示します。

また、計測ライブラリそのものに対する疑問もあります。オーバーヘッドをはじめ、不要なものが多い。

 
fxsaber:

今、MQLにミリ秒タイマーがあると便利だという話をしているのですが、残念ながら存在しないのです。これがないとUPUでスナップショットができない。

ずっと前にミリ秒タイマーがある: EventSetMillisecondTimer()

Документация по MQL5: Работа с событиями / EventSetMillisecondTimer
Документация по MQL5: Работа с событиями / EventSetMillisecondTimer
  • www.mql5.com
Указывает клиентскому терминалу, что для данного эксперта или индикатора необходимо генерировать события таймера с периодичностью менее одной секунды. нужно получать события таймера чаще, чем один раз в секунду. Если вам достаточно обычного таймера с периодом более 1 секунды, то используйте EventSetTimer(). В тестере стратегий используется...