오류, 버그, 질문 - 페이지 2879

 
Igor Makanu :

조금 수정했어요

(그래서 매크로를 사용하지 않는 것이 좋다 ;)

 #define   SpeedTest(count_x10,msg,EX)        { ulong mss= GetMicrosecondCount (); ulong count=( ulong ) pow ( 10 ,count_x10); for ( ulong _i= 0 ;_i<count;_i++){EX;} \
                                               printf ( "%s: loops=%llu ms=%llu" ,msg,count, GetMicrosecondCount ()-mss);}
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart ()
{
{
   ulong sum = 0 ;
   uint in01A = ( uint ) rand ();
   uint in01B = ( uint ) rand ();
   uint in02A = ( uint ) rand ();
   uint in02B = ( uint ) rand ();
   uint in03A = ( uint ) rand ();
   uint in03B = ( uint ) rand ();
   uint in04A = ( uint ) rand ();
   uint in04B = ( uint ) rand ();
   uint in05A = ( uint ) rand ();
   uint in05B = ( uint ) rand ();
   uint param[ 5 ];
   SpeedTest( 22 , "tst 1 : " ,
   {
      sum += in01A << ( sizeof ( ushort ) * 8 ) | in01B;
      sum += in02A << ( sizeof ( ushort ) * 8 ) | in02B;
      sum += in03A << ( sizeof ( ushort ) * 8 ) | in03B;
      sum += in04A << ( sizeof ( ushort ) * 8 ) | in04B;
      sum += in05A << ( sizeof ( ushort ) * 8 ) | in05B;
   //   for(int i = 0; i < 5; i++) sum += param[i];
   });
   Print (sum);
   }
//--  

   ulong sum = 0 ;
   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 (); 
   sum = 0 ;
   union ushortTouint
   {
       uint param[ 5 ];
       ushort in[ 10 ];
   }U;
      ushortTouint u;
   SpeedTest( 22 , "tst 2 : " ,
   { 
      u.in[ 0 ] = in00;
      u.in[ 1 ] = in01;
      sum +=u.param[ 0 ];
      u.in[ 2 ] = in02;
      u.in[ 3 ] = in03;
      sum +=u.param[ 1 ];
      u.in[ 4 ] = in04;
      u.in[ 5 ] = in05;
      sum +=u.param[ 2 ];
      u.in[ 6 ] = in06;
      u.in[ 7 ] = in07;
      sum +=u.param[ 3 ];
      u.in[ 8 ] = in08;
      u.in[ 9 ] = in09;
      sum +=u.param[ 4 ];
     //  Comment(121);
   //  for(int i = 0; i < 5; i++) sum += u.param[i];
   });
Print (sum);
}
 
Alexandr Andreev :

조금 수정했어요

(그래서 매크로를 사용하지 않는 것이 좋다 ;)

테스트할 때 옵티마이저가 빈 주기를 버리지 않도록 최대한 코드를 혼동합니다.

 //  for(int i = 0; i < 5; i++) sum += u.param[i];

MQL 실행의 최적화는 일정보다 먼저 첫 번째 주기를 종료할 수 있습니다. 계산된 값은 사용되지 않으므로 결과로 SpeedTest() 이후에 뭔가를 해야 합니다 - 이 루프

주석 처리된 루프로 확인했지만 버리지는 않았지만 다른 테스트에서는 중단할 수 있습니다.


매크로는 취향의 문제입니다. 이 매크로를 반복해서 확인했는데 작동합니다. 같은 것을 손으로 쓸 이유가 없습니다



UPD: 현대 컴파일러가 어떻게 작동하는지 읽었으며 매우 유익한 정보를 얻었습니다.

https://habr.com/ru/post/431688/

https://habr.com/en/post/47878/

 

코드는 핸들의 iRSI 값을 제공하는 등 항상 10에 불과하지만 가격과 차트는 동일하게 변경됩니다.

iRSI(_기호, PERIOD_H1,14 ,PRICE_CLOSE)


빌드 2652

Документация по MQL5: Константы, перечисления и структуры / Константы графиков / Периоды графиков
Документация по MQL5: Константы, перечисления и структуры / Константы графиков / Периоды графиков
  • www.mql5.com
Все предопределенные периоды графиков имеют уникальные идентификаторы. Идентификатор PERIOD_CURRENT означает текущий период графика, на котором запущена mql5-программа.
 
Aleksei Skrypnev :

코드는 핸들의 iRSI 값을 제공하는 등 항상 10에 불과하지만 가격과 차트는 동일하게 변경됩니다.

iRSI(_기호, PERIOD_H1,14 ,PRICE_CLOSE)


빌드 2652

표시기 핸들이 있습니다. 10입니다.

다음으로 원하는 막대에서 값을 가져와야 합니다.

 //--- создадим хэндл индикатора
   if (type==Call_iRSI)
      handle= iRSI (name,period,ma_period,applied_price);

//--- индикаторный буфер
double   rsi_buffer[];

//--- заполняем часть массива iRSIBuffer значениями из индикаторного буфера под индексом 0
   if ( CopyBuffer (ind_handle, 0 , 0 ,amount,rsi_buffer)< 0 )
     {
       //--- если копирование не удалось, сообщим код ошибки
       PrintFormat ( "Не удалось скопировать данные из индикатора iRSI, код ошибки %d" , GetLastError ());
       //--- завершим с нулевым результатом - это означает, что индикатор будет считаться нерассчитанным
       return ( false );
     }

도움말 을 읽거나 포럼에서 답변을 찾으십시오.

Документация по MQL5: Технические индикаторы / iRSI
Документация по MQL5: Технические индикаторы / iRSI
  • www.mql5.com
//|                                                    Demo_iRSI.mq5 | //|                        Copyright 2011, MetaQuotes Software Corp. | //|                                             https://www.mql5.com | //| Перечисление способов создания хэндла                            |  Creation             type=Call_iRSI;               ...
 
Vitaly Muzichenko :

표시기 핸들이 있습니다. 10입니다.

다음으로 원하는 막대에서 값을 가져와야 합니다.

도움말 을 읽거나 포럼에서 답변을 찾으십시오.

이해했다. 버퍼에 대해 공부하겠습니다. 어쨌든 모든 것이 작동한다는 이상한 느낌이 들었습니다. 아마도 mql4와 혼동했을 것입니다.

요청 시 Google을 통해 찾을 수 없다는 것이 이상합니다. mql5의 표시기에서 데이터 가져오기


예, 귀하의 예에 따라 내가 이해하는 것처럼 RSI 표시기의 값은 궁극적으로 다음 형식의 변수에 있습니다.

rsi_buffer[0] 
 
Igor Makanu :

확인:

2020.10.15 21:48:01.401 SpeedTst (EURUSD,H1) tst1 : : 루프=10000000000 ms=10864370

2020.10.15 21:48:12.264 SpeedTst (EURUSD,H1) tst2 : : 루프 = 10000000000 ms = 10862287

큰 차이는 아니지만 테스트를 바꾸면 결과가 반대일 가능성이 높습니다.

일반적으로 중요하지 않습니다.

테스트에 rand()를 포함하는 것은 거의 정확하지 않습니다. 이 기능은 다른 명령보다 훨씬 더 많은 리소스를 소비합니다.
나는 이것이 더 나은 테스트라고 생각합니다.

 #define Num 1000000
#define SpeedTest(msg,s,EX)  { ulong mss= GetMicrosecondCount (); EX \
                                    mss= GetMicrosecondCount ()-mss;\
                                     printf ( "%-22s%llu µs; Сумма - %llu" ,msg,mss,s);}
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart ()
{
   ulong sum = 0 ;
   ushort in[];
   ArrayResize (in,Num* 2 );
   for ( int i= 0 ; i<Num* 2 ; i++) in[i] = ( ushort ) rand ();
   SpeedTest( "test binary shift : " , sum,
   for ( int i = 0 ;i<( 2 *Num- 1 ) && ! _StopFlag ;i+= 2 )
   {
      sum+=in[i]<<( sizeof ( ushort )* 8 ) | in[i+ 1 ];
   });
//--   
   sum = 0 ;
   union ushortTouint
   {
       uint param;
       ushort in[ 2 ];
   } u;
   SpeedTest( "test union : " , sum,
   for ( int i = 0 ;i<( 2 *Num- 1 ) && ! _StopFlag ;i+= 2 )
   {
      u.in[ 0 ]=in[i+ 1 ];
      u.in[ 1 ]=in[i];
      sum+=u.param;
   });
}

결과:

 2020.10 . 15 17 : 14 : 03.168 TestMakanu (USDCAD,M1)  test binary shift :   1384 µs; Сумма - 1074434582054198
2020.10 . 15 17 : 14 : 03.169 TestMakanu (USDCAD,M1)  test union :           1209 µs; Сумма - 1074434582054198
2020.10 . 15 17 : 14 : 19.370 TestMakanu (USDCAD,M1)  test binary shift :   1891 µs; Сумма - 1073924616844949
2020.10 . 15 17 : 14 : 19.371 TestMakanu (USDCAD,M1)  test union :           1289 µs; Сумма - 1073924616844949
2020.10 . 15 17 : 14 : 20.949 TestMakanu (USDCAD,M1)  test binary shift :   1342 µs; Сумма - 1073194788831653
2020.10 . 15 17 : 14 : 20.950 TestMakanu (USDCAD,M1)  test union :           1178 µs; Сумма - 1073194788831653
2020.10 . 15 17 : 14 : 27.141 TestMakanu (USDCAD,M1)  test binary shift :   1365 µs; Сумма - 1075017290553168
2020.10 . 15 17 : 14 : 27.142 TestMakanu (USDCAD,M1)  test union :           1362 µs; Сумма - 1075017290553168
2020.10 . 15 17 : 14 : 28.202 TestMakanu (USDCAD,M1)  test binary shift :   1354 µs; Сумма - 1075051817914563
2020.10 . 15 17 : 14 : 28.203 TestMakanu (USDCAD,M1)  test union :           1105 µs; Сумма - 1075051817914563

다행히도 나는 여전히 잘못된 말에 내기를 걸고 있습니다. 노동조합이 조금 더 빠릅니다. 그들과 함께 작업하는 것이 더 편리하고 코드가 더 읽기 쉽습니다.

 
Nikolai Semko :

테스트에 rand()를 포함하는 것은 거의 정확하지 않습니다. 이 기능은 다른 명령보다 훨씬 더 많은 리소스를 소비합니다.

일반적으로 무비판적인

rand()의 런타임은 일정합니다. 대부분의 경우 일반 C++ 함수인 Google "rand C++ 소스 코드"입니다.

초기화가 필요하지만 상수로 초기화하면 최적화에 빠질 수 있습니다.

일반적으로 rand()에 대한 혐오감은 분명하지 않습니다.

다음과 같이 초기화하는 옵션으로:

 void OnStart ()
{
   for ( int i= 0 ;i< 20 ;i++) Print (Myvalue());

}
//+------------------------------------------------------------------+
int Myvalue()
{
   const static int arr[] = { 3 , 1 , 4 , 1 , 5 , 9 , 2 , 6 };
   static int cnt = ArraySize (arr);
   if (--cnt < 0 ) cnt = ArraySize (arr) - 1 ;
   return (arr[cnt]);
}

빠를 것이다


스크립트를 시작했습니다. IMHO가 올바르지 않습니다.

주요 시간은 코드를 캐시에 로드한 다음 프로세서에 로드하는 것입니다.

음, 시스템 타이머 의 불연속성을 추가하십시오.

우리는 ... 거의 임의의 숫자를 얻습니다.

IMHO에 대해 약 100500 시간 동안 테스트해야합니다.

 
Nikolai Semko :

테스트에 rand()를 포함하는 것은 거의 정확하지 않습니다. 이 기능은 다른 명령보다 훨씬 더 많은 리소스를 소비합니다.
나는 이것이 더 나은 테스트라고 생각합니다.

결과:

다행히도 나는 여전히 잘못된 말에 내기를 걸고 있습니다. 노동조합이 조금 더 빠릅니다. 그들과 함께 작업하는 것이 더 편리하고 코드가 더 읽기 쉽습니다.


한 번에 하나씩, 첫 번째 승리의 거리에서 (첫 번째 방법은 변환 라인을 짧은 것에서 무언가로 제거한 것 같습니다)

 
Igor Makanu :

일반적으로 비판적

rand()의 런타임은 일정합니다. 대부분의 경우 일반 C++ 함수인 Google "rand C++ 소스 코드"입니다.

초기화가 필요하지만 상수로 초기화하면 최적화에 빠질 수 있습니다.

일반적으로 rand()에 대한 혐오감은 분명하지 않습니다.

다음과 같이 초기화하는 옵션으로:

빠를 것이다

측정할 때 불필요한 것 없이 필요한 만큼 정확하게 측정해야 한다는 것이었습니다.

 
Alexandr Andreev :

측정할 때 불필요한 것 없이 필요한 만큼 정확하게 측정해야 한다는 것이었습니다.

아니요

반복되는 코드 섹션이 있는 경우 - 최적화 테스트를 받으십시오!

rand() 실행 시간은 어떤 차이가 있습니까?

예, 테스트 시간의 2/3를 실행합니다. 중요한 것은 rand()의 실행 시간이 일정하다는 것입니다.

IMHO, 시스템 기능을 실행하려면 컨텍스트를 전환해야 하지만 MQL 코드가 시스템 MQL 기능을 사용할까요? - 테스트할 이상적인 코드의 의미는?