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

 
Igor Makanu:

最適化の際に、どの変換バリアントがより速く動作するのか

これは1パスにつき1回だけ呼び出されます。したがって、違いはありません。

 
fxsaber:

これは、全パッセージに対して一度だけ呼び出されます。だから、何の違いもないのです。

そうそうしかし、私は最適化のために数日間実行するつもりです、私は何らかの方法でパフォーマンスを測定したい......私はバリエーション1がより効率的であると思われるが、配列に100500回コピーされることはありません

 
Igor Makanu:

然りしかし、私は最適化のために数日間コンピュータを実行するつもりです、私は何らかの方法でパフォーマンスを測定したい......オプション1がより効率的であると思われるが、配列に100500回コピーされることはありません。

ですから、variant 2の方が速い可能性が高いのですが、上でご指摘のように、それは問題ではありません。
 
TheXpert:
unionは配列へのコピーではなく、同じメモリ空間に対する異なる解釈です。したがって、2番目のオプションはおそらく高速ですが、上記のように、それは問題ではありません。
ユニオンは、見た目ほど速くはありません。残念ながら。
私は1番に賭けています。
 
Igor Makanu:

然りしかし、私は最適化のために数日間コンピュータを実行するつもりです、私は何らかの方法でパフォーマンスを測定したい......オプション1がより効率的であると思われるが、配列に100500回コピーされることはありません。

速度の測り方に工夫がある

風に

for (int i=0; i< 1000000; i++) {our code1}...
for (int i=0; i< 1000000; i++) {our code2}...。

 
Nikolai Semko:
ユニオンは、言うほど速くない。最初の1枚に賭ける。

私も1番に賭けます!2番にはありませんが、二項演算子はif演算子より何倍も速いです。

 

をチェックしました。

#define    SpeedTest(count_x10,msg,EX)        {ulong mss=GetMicrosecondCount(); ulong count=(ulong)pow(10,count_x10);for(ulong _i=0;_i<count&&!_StopFlag;_i++){EX;} \
                                              printf("%s: loops=%llu ms=%llu",msg,count,GetMicrosecondCount()-mss);}
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
   ulong sum = 0;
   SpeedTest(10, "tst 1 : ",
   {
      ushort in01A = (ushort)rand();
      ushort in01B = (ushort)rand();
      ushort in02A = (ushort)rand();
      ushort in02B = (ushort)rand();
      ushort in03A = (ushort)rand();
      ushort in03B = (ushort)rand();
      ushort in04A = (ushort)rand();
      ushort in04B = (ushort)rand();
      ushort in05A = (ushort)rand();
      ushort in05B = (ushort)rand();
      uint param[5];
      param[0] = (uint)in01A << (sizeof(ushort) * 8) | in01B;
      param[1] = (uint)in02A << (sizeof(ushort) * 8) | in02B;
      param[2] = (uint)in03A << (sizeof(ushort) * 8) | in03B;
      param[3] = (uint)in04A << (sizeof(ushort) * 8) | in04B;
      param[4] = (uint)in05A << (sizeof(ushort) * 8) | in05B;
      for(int i = 0; i < 5; i++) sum += param[i];
   });
//--   
   sum = 0;
   union ushortTouint
   {
      uint param[5];
      ushort in[10];
   }U;
   SpeedTest(10, "tst 2 : ",
   {
      ushort in00 = (ushort)rand();
      ushort in01 = (ushort)rand();
      ushort in02 = (ushort)rand();
      ushort in03 = (ushort)rand();
      ushort in04 = (ushort)rand();
      ushort in05 = (ushort)rand();
      ushort in06 = (ushort)rand();
      ushort in07 = (ushort)rand();
      ushort in08 = (ushort)rand();
      ushort in09 = (ushort)rand();
      ushortTouint u;
      u.in[0] = in00;
      u.in[1] = in01;
      u.in[2] = in02;
      u.in[3] = in03;
      u.in[4] = in04;
      u.in[5] = in05;
      u.in[6] = in06;
      u.in[7] = in07;
      u.in[8] = in08;
      u.in[9] = in09;
      for(int i = 0; i < 5; i++) sum += u.param[i];
   });

}

2020.10.15 21:48:01.401 SpeedTst (EURUSD,H1) tst 1 : : loops=100000000 ms=10864370

2020.10.15 21:48:12.264 SpeedTst (EURUSD,H1) tst 2 : : loops=100000000 ms=10862287

この差が有意でない場合、テストの順番を逆にすれば、結果は逆になる可能性が高い。

ノットクリティカル

 
Igor Makanu:

を比較した場合、有意な差は見られませんが、入れ替えた場合は逆の結果になる可能性が高いです。

コンパイラが同じコードを生成している可能性が高いので、その場合は、主観的に好きな方を選んでください。

 
Igor Makanu:

をチェックしました。

2020.10.15 21:48:01.401 SpeedTst (EURUSD,H1) tst 1 : : loops=100000000 ms=10864370

2020.10.15 21:48:12.264 SpeedTst (EURUSD,H1) tst 2 : : loops=100000000 ms=10862287

この差が有意でなければ、テストの順番を逆にすれば、結果は逆になる可能性が高い。

ノットクリティカル

このスクリプトは、乱数生成の時間が不均一で、生成される変数の量に依存する可能性があることを実証しています))

そして、この繰り返し回数で必要なコードは0msで済みます。

まだ答えはない。

または、コードの最適化が不要なものをカットしている。
 
Alexandr Andreev:

乱数生成のタイミングが不等間隔になることを実証するスクリプトがあるようです

rand() は通常の関数であり、常に同じ動作をします。

しかし、速度をテストする場合、定数で初期化すれば、テストは実行中に「高速化」される - MQLの 実行中のコード最適化は良いことだ

一般に、何度も確認される

Alexandr Andreev:

と、作成された変数のサイズに大きく依存します)))

もちろん、メモリの確保には時間がかかります。私は、動的に作成されたオブジェクト(新しいポインタ)とローカルスコープの オブジェクトの両方をテストしており、テストは新規作成と削除ごとに100500回伸びることを確認しました。

全体の質問は、グローバルスコープのテスターでメモリが一度ではなく、すべてのパスに変数に割り当てられているため、 - しかし、私はuint配列を必要とするので、私はそれを最初に書いたとしてではなく、このスクリプトでテスト しました。

Alexandr Andreev:

そして、この繰り返し回数で必要なコードは、0msです。

でない

コードのオプティマイザーが不要なものをカットしているかのどちらかです。

私のスクリプトを使ったのですか?- テストの最後まで待たずに中断したか、ulong をオーバーフローさせたか - マクロの最初のパラメータは 10^ カウントです。



Andrei Trukhanovich:

この場合,主観的に好きな方を選べばよいでしょう.

ああ、そうかもしれない

最近のプロセッサは命令パイプラインを最適化することで、1クロックあたり1つ以上の初等演算を実行できると何度も読んだことがあるのですが.いろいろと、ぼちぼちと......。であり、ポイントは、演算命令がプロセッサによって予測不可能なクロックサイクルで実行されることです

分岐やメモリ割り当て操作については、プロセッサの最適化が非常に悪いので、演算の単純化に最適化を求めず、最小限の分岐で最大限の線形コードを書くようにし、変数は計算の直前に宣言して値を割り当てる方が良い、これにより命令パイプラインとキャッシュサンプリングの予測がこのコードを最適化することができるようになる


つまり、配列の要素の値をサンプリングすること(アドレス指定)は、速度にとって重要ではない可能性が高いのです。