Вопрос про быстродействие MQL5 - страница 2

 
Renat писал(а) >>

Дело в том, что оптимизатор не имеет права выбрасывать блоки, где идет вызов других функций (да еще и WinAPI). Кроме того, переменная b, изменяющаяся в циклах, используется в расчете скорости.

Переменная b да, но что до a то она вообще негде не используется. :)

Что касается GetTickCount... Хм, ну а где в доке на эту функцию написанно что это WinApi ? :) Это такая ваша внутрення функция по описанию в доке. Ну да ладно, это уже не принципивально для меня лично. Обьяснение что вызовы внешних функций не обьявленные как константные требует вызова принимется. Но вот этот-то код вообще весь ваш.

input double   Input1;
input int      Input2;

int fff ( )
{
   return 2;
}

int OnInit()
  {

   
   
   int a=0;
   int b=0;
   
   int t0=GetTickCount() ;
   
   for ( int i=0; i< 200000000; i++ ){
      a=a + fff();
      b++;
   }
   
   int t1 = GetTickCount() ;
   
   double t = t1 - t0;
   
   double it = ((double)t/b)/1000;
   
   printf("1 =============>dt=%d,iter time = %0.20f sec %010.0f cycle per sec",t,it,1/it);   
   
   a=0;b=0;
   
   t0=GetTickCount() ;
   
   for ( int i=0; i< 200000000; i++ ){
      a = a + 2;
      b++;
   }
   
   t1=GetTickCount();  
   
   t=t1-t0;
   
   
   it = ((double)t/b)/1000;
    
   
   printf("2 =============>dt=%d,iter time = %0.20f sec %010.0f cycle per sec",t,it,1/it);   
   
   
   
   return(0);
}

void OnDeinit ( const int reason )
  {
   
  }
  
void OnTick()
  {
   
   
  
   
  }

Но результат тот же.

2009.10.12 22:09:12 a1 (EURUSD,H1) 2 =============>dt=0,iter time = 0.00000000764500000000 sec 0130804447 cycle per sec
2009.10.12 22:09:10 a1 (EURUSD,H1) 1 =============>dt=0,iter time = 0.00000002488000000000 sec 0040192926 cycle per sec

И даже еще хуже.

Разница аж 3,2544146500981033355134074558535 :) хотя уж тут-то ...

 

Тут снова вызов функции против одной команды add eax,2


Я еще раз повторю - сейчас оптимизатор кода практически полностью отключен (в нем есть ряд ошибок, не позволяющих его включать на публичной бете). Функция fff() будет заинлайнена и также сведется к константе.


Вообще результаты лучше всего показывать в сыром виде в миллисекундах как есть, а не в виде вычисляемых и малопонятных значений:

int fff()
  {
   return 2;
  }
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   int a=0;
   int b=0;
//--- первый тест
   int t0=GetTickCount();
   for(int i=0;i<200000000;i++)
     {
      a=a+fff();
      b++;
     }
   Print("1) ",GetTickCount()-t0," ms, b=",b);
//--- второй
   a=0;
   b=0;
   t0=GetTickCount();
   for(int i=0;i<200000000;i++)
     {
      a=a+2;
      b++;
     }
   Print("2) ",GetTickCount()-t0," ms, b=",b);
  }

и результат (чем меньше. тем лучше/быстрее):

1)  3328  ms, b=20000000
2)   594  ms, b=20000000


Тот же самый код в Visual Studio 2005 C++:

int fff()
  {
   return(2);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void start2()
  {
   int a=0;
   int b=0;
//---
   int t0=GetTickCount();
   for( int i=0; i< 200000000; i++ )
     {
      a=a + fff();
      b++;
     }
   printf("1) %d ms, b=%d\n",GetTickCount()-t0,b);
//---
   a=0;
   b=0;
   t0=GetTickCount() ;

   for( int i=0; i< 200000000; i++ )
     {
      a=a + 2;
      b++;
     }
   printf("2) %d ms, b=%d\n",GetTickCount()-t0,b);
  }

В неоптимизированной Debug версии результаты следующие:

1) 6813 ms, b=200000000
2)  562 ms, b=200000000

Фактически на вызове пустой функции fff компилятор Visual C++ умудрился в 2 раза проиграть MQL5. Но это не важно - оптимизатор отключен ради отладки.


Запустим код в Release версии со всеми оптимизациями:

1) 0 ms, b=200000000
2) 0 ms, b=200000000

Здесь компилятор эффективно провел оптимизацию, выкинул все лишнее и сгенерировал код, где вообще убраны все циклы (свернуты в константы):

  00000	56		 push	 esi

  00001	8b 35 00 00 00	 mov	 esi, __imp__GetTickCount@0
  00007	57		 push	 edi
  00008	ff d6		 call	 esi
  0000a	68 00 c2 eb 0b	 push	 200000000
  0000f	8b f8		 mov	 edi, eax
  00011	ff d6		 call	 esi
  00013	2b c7		 sub	 eax, edi

  00015	50		 push	 eax
  00016	68 00 00 00 00	 push	 OFFSET str
  0001b	e8 00 00 00 00	 call	 _printf
  00020	83 c4 0c	 add	 esp, 12

  00023	ff d6		 call	 esi
  00025	68 00 c2 eb 0b	 push	 200000000
  0002a	8b f8		 mov	 edi, eax
  0002c	ff d6		 call	 esi
  0002e	2b c7		 sub	 eax, edi
  00030	50		 push	 eax
  00031	68 00 00 00 00	 push	 OFFSET str
  00036	e8 00 00 00 00	 call	 _printf
  0003b	83 c4 0c	 add	 esp, 12

  0003e	5f		 pop	 edi
  0003f	5e		 pop	 esi


Мы постараемся довести свой оптимизатор до такого же результата. Все возможности для этого у нас есть.

 

Да именно в debug версии мс-овского компилятора оптимизатор выключен... совсем, для возможности отладки. Ну и если у вас он также отключен совсем, в этой бетте, то тогда понятно, откуда такие результаты. Ну что же будем надеяться что в вашем релизе, когда оптимизатор будет работать, он будет лучше чем мс-овский или даже лучше чем интеловый.

Да... результаты в виде миллисекунд, вообще мало кому интересны, так как это зависит.... от частоты процессора например, а вот сравнение времени выполнения разного кода, на одном и том же процессоре - правильный подход.

Но ответ получен - спасибо.