defineの専門家に質問 - ページ 6

 
Igor Makanu:

ループの本体で配列のサイズを変更した場合、オンザフライの最適化は機能しない

ので、コードを変更します。

))) 単にsize変数の値も変更しなければならないので、ArraySIzeを使った 名前付きファーストメソッドが有利になります。

 
Alexandr Andreev:

まあIMHOに対しては何も言えませんけどね。

非常に大きなリプレイで、1回目と2回目の方法で勝敗がランダムになってしまった...。おそらく、現在のCPUキャッシュと全体の負荷に依存するようになったのでしょう。

私の質問は、ループについてではなく、関数がどのように展開されるかということでした。ArraySizeが例として使われただけです。

それはいいとして)高級言語の完成は、まさに便利な文章が便利でなく、本来は安いものであるときです。いつもそうとは限らないのが残念、初心者向けのヘルパーさんとのヘルプも全くないとは限らない...疑問はないだろう)))

 
Igor Makanu:

ループの本体で配列のサイズを変更した場合、オンザフライの最適化は機能しない

そこで、コードを変更します。


ノーマーク

ランタイム最適化がリード

プロファイラが ないとこんな簡単なマシンコマンドのテストはできないし、ループで書いたり、テスターでテストしたり、そのためにはスピードが重要です。

ループの話ではなく、コンパイラがどのように関数を展開するかという話だったのですが......さあ、どうでしょう。

では、失礼します。

 
Alexandr Andreev:

))) では、size 変数の値を変更することも許可されているので、ArraySIze を使用する 最初のメソッドが勝ちになります。

私は上に書きました - このような単純なコードは、単純な測定でテストすることはできません、多くの要因があります - コードは小さい - それはプロセッサのキャッシュに収まるでしょう、コードはプロセッサのパイプラインで並列マイクロコマンドにプロセッサでよく分解されなければなりません、すなわち、レジスタは、データのプリフェッチによって迅速にロードされるでしょう。

で、おそらく rand() もどこかにキャッシュされるでしょう。


デバッガを使わずにテストする方法がわからない - 少なくともそこでは、命令の実行時間を正確に見ることができる

 
Alexandr Andreev:

では、私が間違っていることを証明してください)。

なぜなら、私のテストではなぜか同じになってしまうからです。

投稿を変更しました。
今のArraySizeは cnt変数より速いような気がします。
以前はその逆でした。インクリメント cnt-- が影響しているのか、ループ本体が違っているのか、ロードのために何か工夫が必要なのかもしれません。

void OnStart()
{
   int arr[];
   int sz = ArrayResize(arr, 100000000);  
   
   ulong t = GetMicrosecondCount();
   
   for(int i=0; i < ArraySize(arr); i++) 
   {
      ArrayResize(arr, sz--); //какая то нагрузка
   }   
   
   t = GetMicrosecondCount() - t;
   
   PrintFormat("Total time: %.3f ms", t / 1000.0);
}
2020.11.02 21:33:22.863 TestScript (USDJPY,M1)  Total time: 451.200 ms


void OnStart()
{
   int arr[];
   int sz = ArrayResize(arr, 100000000);  
   int cnt = ArraySize(arr);
   
   ulong t = GetMicrosecondCount();
   
   for(int i=0; i < cnt; i++) 
   {
      ArrayResize(arr, sz--);
      cnt--;
   }
      
   t = GetMicrosecondCount() - t;
   
   PrintFormat("Total time: %.3f ms", t / 1000.0);
}
2020.11.02 21:56:26.591 TestScript (USDJPY,M1)  Total time: 531.872 ms
 
Roman:

これは不思議なことです。
ループ条件内でArraySize(arr)を使用 すると、cnt変数を使用するよりも短い時間で表示されます。
以前はその逆でした。もしかして、エラー?そんなことはないはずです。

あなたはコードに何も混ぜていないのに、誰があなたのために値を変えてくれるのですか?

cnt

は、最初のバリアントで起こるように、あなたのためにそれを変更します。

 
void OnStart()
  {
   int mas[];
   int size=1000000;
   ArrayResize(mas,size);
   ulong r=0;
   ulong r1=0;
   ulong r2=0;
   int random;
   ulong max=100;
   uint t1=GetTickCount();
   int t=0;
   int tr=0; 
   MathSrand(10);
   for(ulong z=0; z<max; z++)
     {
      for(ulong i=0; i<ArraySize(mas); Funk(i))
        { 
         FunkRand(r1); 
         Funk(r);// мы сюда написали вызов еще одной функции чтобы усложить ситуацию
        }
     }
   tr=r;
   uint t2=GetTickCount();
   for(ulong z=0; z<max; z++)
     {
     int v=size;
      for(ulong i=0; i<v; i++)
        { 
         r2+=rand();
         r--;
        }

     }

   uint t3=GetTickCount();
   Print(t2-t1,"  ",t3-t2," ",r," ",r1," ",r2," ",t1," ",tr);
// Templ();
  }

//+------------------------------------------------------------------+
//|                                           
  
void Funk(ulong &a){a++;}
void FunkRand(ulong &a){a+=rand();}

//+------------------------------------------------------------------+

500pの問題(ノーチェック)、どちらが速いか。トップメソッドで外部関数が いくつ呼ばれているかを見る。

Документация по MQL5: Основы языка / Функции / Описание внешних функций
Документация по MQL5: Основы языка / Функции / Описание внешних функций
  • www.mql5.com
Внешние функции, определенные в другом модуле, должны быть явно описаны. Описание включает в себя тип возвращаемого значения, имя функции и набор входных параметров с их типами. Отсутствие такого описания может привести к ошибкам при компиляции, компоновке или выполнении программы. При описании внешнего объекта используйте ключевое слово С...
 

のように、それぞれのテストに異なる配列だけを挿入することもできます。

すなわち、tst1_arr1[],tst1_arr2[] ................................となる。とtst2_arr1[],tst2_arr2[] があります。


というのが、より公平なテストになるのではないでしょうか。

私はオフ、非常に気が散る - イモ、便利な、それを使用します。

 
Igor Makanu:

デバッガを使わないでテストする方法がわからない。少なくとも、命令の実行時間をクロックサイクルで見ることはできる。

そうですね。デバッガがないとどうしようもないですね。そして、そこにある時計の時間では...。

 
Roman:

これは不思議なことです。
ループ条件内でArraySize(arr)を使用 すると、cnt変数を使用するよりも短い時間で表示されます。
以前はその逆でした。もしかして、エラー?そんなことはないはずです。

そこにはランダムな結果がある。コンパイル時には、配列サイズの 値を持つメモリセルへのアクセスは展開されますが、配列が形成される際には、あらかじめ配列サイズを受け取ってメモリセルに入れるため、配列が動的であっても、配列サイズと変数の値を持つセルには同じアクセス時間が発生することになります。

そして、3~4年のコンピュータサイエンスコースでコンパイラが行うフレーズから判断すると・・・。一般的には、十分に必要なレベルのフレーミングが、MCLの環境ではあまり神経質にならないことを期待することにします)

理由: