Ошибки, баги, вопросы - страница 2778

 
Alain Verleyen:

Еще один Терминал, но 20 графиков (разных символов), стартовал одновременно.

Я проверил на AUDUSD, где пик приходит:

2020.06.13 09: 16: 35.151 342152 (USDJPY, H1) Количество = 240
2020.06.13 09: 16: 35.151 342152 (USDJPY, H1) Мин = 38
2020.06.13 09: 16: 35.151 342152 (USDJPY, H1) Макс = 2235
2020.06.13 09: 16: 35.151 342152 (USDJPY, H1) Avg = 472
2020.06.13 09: 16: 35.151 342152 (CADCHF, H1) Количество = 240
2020.06.13 09: 16: 35.151 342152 (CADCHF, H1) Min = 48
2020.06.13 09: 16: 35.151 342152 (CADCHF, H1) Макс = 2323
2020.06.13 09: 16: 35.152 342152 (CADCHF, H1) Avg = 606
2020.06.13 09: 16: 35.152 342152 (EURAUD, H1) Количество = 240
2020.06.13 09: 16: 35.152 342152 (EURCHF, H1) Количество = 240
2020.06.13 09: 16: 35.152 342152 (GBPCHF, H1) Количество = 240
2020.06.13 09: 16: 35.152 342152 (EURCHF, H1) Мин = 141
2020.06.13 09: 16: 35.152 342152 (EURGBP, H1) Количество = 240
2020.06.13 09: 16: 35.152 342152 (CHFJPY, H1) Количество = 240
2020.06.13 09: 16: 35.152 342152 (AUDJPY, H1) Количество = 240
2020.06.13 09: 16: 35.152 342152 (AUDJPY, H1) Мин = 47
2020.06.13 09: 16: 35.152 342152 (EURUSD, H1) Количество = 240
2020.06.13 09: 16: 35.152 342152 (EURUSD, H1) Мин. = 23
2020.06.13 09: 16: 35.152 342152 (EURUSD, H1) Макс = 2368
2020.06.13 09: 16: 35.152 342152 (AUDUSD, H1) Количество = 240
2020.06.13 09: 16: 35.152 342152 (EURUSD, H1) Avg = 607
2020.06.13 09: 16: 35.152 342152 (AUDUSD, H1) Мин = 74
2020.06.13 09: 16: 35.152 342152 (GBPJPY, H1) Количество = 240
2020.06.13 09: 16: 35.152 342152 (AUDNZD, H1) Количество = 240
2020.06.13 09: 16: 35.152 342152 (USDCHF, H1) Количество = 240
2020.06.13 09: 16: 35.152 342152 (AUDNZD, H1) Min = 122
2020.06.13 09: 16: 35.152 342152 (AUDCHF, H1) Количество = 240
2020.06.13 09: 16: 35.152 342152 (AUDNZD, H1) Макс = 2402
2020.06.13 09: 16: 35.152 342152 (AUDNZD, H1) Avg = 660
2020.06.13 09: 16: 35.152 342152 (AUDCHF, H1) Min = 157
2020.06.13 09: 16: 35.152 342152 (AUDCHF, H1) Макс = 2354
2020.06.13 09: 16: 35.152 342152 (AUDCHF, H1) Avg = 663
2020.06.13 09: 16: 35.152 342152 (GBPCHF, H1) Min = 32
2020.06.13 09: 16: 35.152 342152 (GBPCHF, H1) Макс = 2380
2020.06.13 09: 16: 35.152 342152 (GBPCHF, H1) Avg = 616
2020.06.13 09: 16: 35.152 342152 (EURCHF, H1) Макс = 2327
2020.06.13 09: 16: 35.152 342152 (EURCHF, H1) Avg = 618
2020.06.13 09: 16: 35.152 342152 (EURGBP, H1) Min = 36
2020.06.13 09: 16: 35.152 342152 (EURGBP, H1) Макс = 2233
2020.06.13 09: 16: 35.152 342152 (EURGBP, H1) Avg = 503
2020.06.13 09: 16: 35.152 342152 (CHFJPY, H1) Мин = 11
2020.06.13 09: 16: 35.152 342152 (CHFJPY, H1) Макс = 2387
2020.06.13 09: 16: 35.152 342152 (CHFJPY, H1) Avg = 657
2020.06.13 09: 16: 35.152 342152 (AUDJPY, H1) Макс = 2292
2020.06.13 09: 16: 35.152 342152 (AUDJPY, H1) Avg = 612
2020.06.13 09: 16: 35.152 342152 (EURNZD, H1) Количество = 240
2020.06.13 09: 16: 35.152 342152 (EURNZD, H1) Min = 54
2020.06.13 09: 16: 35.152 342152 (EURNZD, H1) Макс = 2361
2020.06.13 09: 16: 35.152 342152 (EURNZD, H1) Avg = 612
2020.06.13 09: 16: 35.152 342152 (AUDCAD, H1) Количество = 240
2020.06.13 09: 16: 35.152 342152 (AUDCAD, H1) Min = 121
2020.06.13 09: 16: 35.152 342152 (EURCAD, H1) Количество = 240
2020.06.13 09: 16: 35.152 342152 (AUDCAD, H1) Макс = 2328
2020.06.13 09: 16: 35.152 342152 (AUDCAD, H1) Avg = 605
2020.06.13 09: 16: 35.152 342152 (AUDUSD, H1) Макс = 2361
2020.06.13 09: 16: 35.152 342152 (AUDUSD, H1) Avg = 611
2020.06.13 09: 16: 35.152 342152 (GBPJPY, H1) Мин = 13
2020.06.13 09: 16: 35.152 342152 (GBPJPY, H1) Макс = 2411
2020.06.13 09: 16: 35.152 342152 (GBPJPY, H1) Avg = 661
2020.06.13 09: 16: 35.153 342152 (GBPUSD, H1) Количество = 240
2020.06.13 09: 16: 35.153 342152 (GBPUSD, H1) Мин = 113
2020.06.13 09: 16: 35.153 342152 (GBPUSD, H1) Макс = 2362
2020.06.13 09: 16: 35.153 342152 (GBPUSD, H1) Avg = 667
2020.06.13 09: 16: 35.153 342152 (USDCAD, H1) Количество = 240
2020.06.13 09: 16: 35.153 342152 (USDCAD, H1) Min = 151
2020.06.13 09: 16: 35.153 342152 (USDCAD, H1) Макс = 2386
2020.06.13 09: 16: 35.153 342152 (EURAUD, H1) Min = 35
2020.06.13 09: 16: 35.153 342152 (USDCAD, H1) Avg = 671
2020.06.13 09: 16: 35.153 342152 (EURAUD, H1) Макс = 2233
2020.06.13 09: 16: 35.153 342152 (EURAUD, H1) Avg = 478
2020.06.13 09: 16: 35.153 342152 (EURJPY, H1) Количество = 240
2020.06.13 09: 16: 35.153 342152 (EURJPY, H1) Мин = 10
2020.06.13 09: 16: 35.153 342152 (EURCAD, H1) Min = 123
2020.06.13 09: 16: 35.153 342152 (EURCAD, H1) Макс = 2384
2020.06.13 09: 16: 35.153 342152 (EURCAD, H1) Avg = 658
2020.06.13 09: 16: 35.153 342152 (USDCHF, H1) Min = 32
2020.06.13 09: 16: 35.153 342152 (USDCHF, H1) Макс = 2369
2020.06.13 09: 16: 35.153 342152 (USDCHF, H1) Avg = 614
2020.06.13 09: 16: 35.153 342152 (EURJPY, H1) Макс = 2344
2020.06.13 09: 16: 35.153 342152 (EURJPY, H1) Avg = 658

И вот, когда наступят вершины:

2020.06.13 09: 17: 35.151 342152 (USDJPY, H1) Количество = 480
2020.06.13 09: 17: 35.151 342152 (USDJPY, H1) Min = 38
2020.06.13 09: 17: 35.151 342152 (USDJPY, H1) Макс = 17421
2020.06.13 09: 17: 35.151 342152 (USDJPY, H1) Avg = 533
2020.06.13 09: 17: 35.151 342152 (EURAUD, H1) Количество = 480
2020.06.13 09: 17: 35.151 342152 (EURAUD, H1) Min = 35
2020.06.13 09: 17: 35.151 342152 (EURAUD, H1) Макс = 17406
2020.06.13 09: 17: 35.151 342152 (EURAUD, H1) Avg = 518
2020.06.13 09: 17: 35.151 342152 (EURGBP, H1) Количество = 480
2020.06.13 09: 17: 35.151 342152 (EURGBP, H1) Min = 36
2020.06.13 09: 17: 35.151 342152 (EURGBP, H1) Макс = 17425
2020.06.13 09: 17: 35.151 342152 (EURGBP, H1) Avg = 515
2020.06.13 09: 17: 35.151 342152 (EURUSD, H1) Количество = 480
2020.06.13 09: 17: 35.151 342152 (EURUSD, H1) Мин = 18
2020.06.13 09: 17: 35.151 342152 (EURUSD, H1) Макс = 17366
2020.06.13 09: 17: 35.151 342152 (EURCHF, H1) Количество = 480
2020.06.13 09: 17: 35.151 342152 (EURUSD, H1) Avg = 618
2020.06.13 09: 17: 35.151 342152 (AUDCHF, H1) Количество = 480
2020.06.13 09: 17: 35.151 342152 (USDCHF, H1) Количество = 480
2020.06.13 09: 17: 35.151 342152 (AUDCHF, H1) Min = 126
2020.06.13 09: 17: 35.151 342152 (CADCHF, H1) Количество = 480
2020.06.13 09: 17: 35.151 342152 (AUDCHF, H1) Макс = 10477
2020.06.13 09: 17: 35.151 342152 (EURCAD, H1) Количество = 480
2020.06.13 09: 17: 35.151 342152 (GBPUSD, H1) Количество = 480
2020.06.13 09: 17: 35.152 342152 (EURCAD, H1) Min = 123
2020.06.13 09: 17: 35.152 342152 (GBPUSD, H1) Min = 112
2020.06.13 09: 17: 35.152 342152 (EURCAD, H1) Макс = 10485
2020.06.13 09: 17: 35.152 342152 (EURCAD, H1) Avg = 663
2020.06.13 09: 17: 35.152 342152 (GBPUSD, H1) Макс = 10435
2020.06.13 09: 17: 35.152 342152 (GBPUSD, H1) Avg = 661
2020.06.13 09: 17: 35.152 342152 (EURCHF, H1) Min = 71
2020.06.13 09: 17: 35.152 342152 (EURJPY, H1) Количество = 480
2020.06.13 09: 17: 35.152 342152 (USDCAD, H1) Количество = 480
2020.06.13 09: 17: 35.152 342152 (USDCAD, H1) Min = 54
2020.06.13 09: 17: 35.152 342152 (EURJPY, H1) Мин = 10
2020.06.13 09: 17: 35.152 342152 (EURJPY, H1) Макс = 10487
2020.06.13 09: 17: 35.152 342152 (EURJPY, H1) Avg = 664
2020.06.13 09: 17: 35.152 342152 (EURNZD, H1) Количество = 480
2020.06.13 09: 17: 35.152 342152 (EURNZD, H1) Min = 54
2020.06.13 09: 17: 35.152 342152 (EURNZD, H1) Макс = 17426
2020.06.13 09: 17: 35.152 342152 (EURNZD, H1) Avg = 620
2020.06.13 09: 17: 35.152 342152 (USDCHF, H1) Min = 32
2020.06.13 09: 17: 35.152 342152 (USDCHF, H1) Макс = 17427
2020.06.13 09: 17: 35.152 342152 (USDCHF, H1) Avg = 649
2020.06.13 09: 17: 35.152 342152 (GBPCHF, H1) Количество = 480
2020.06.13 09: 17: 35.152 342152 (GBPCHF, H1) Min = 32
2020.06.13 09: 17: 35.152 342152 (GBPCHF, H1) Макс = 17433
2020.06.13 09: 17: 35.152 342152 (GBPCHF, H1) Avg = 647
2020.06.13 09: 17: 35.152 342152 (AUDJPY, H1) Количество = 480
2020.06.13 09: 17: 35.152 342152 (AUDJPY, H1) Мин. = 47
2020.06.13 09: 17: 35.152 342152 (AUDJPY, H1) Макс = 17415
2020.06.13 09: 17: 35.152 342152 (AUDJPY, H1) Avg = 640
2020.06.13 09: 17: 35.152 342152 (CADCHF, H1) Min = 48
2020.06.13 09: 17: 35.152 342152 (CADCHF, H1) Макс = 17435
2020.06.13 09: 17: 35.152 342152 (CADCHF, H1) Avg = 637
2020.06.13 09: 17: 35.152 342152 (AUDCHF, H1) Avg = 662
2020.06.13 09: 17: 35.152 342152 (AUDUSD, H1) Количество = 480
2020.06.13 09: 17: 35.152 342152 (AUDUSD, H1) Мин = 43
2020.06.13 09: 17: 35.152 342152 (AUDUSD, H1) Макс = 17416
2020.06.13 09: 17: 35.152 342152 (AUDUSD, H1) Avg = 620
2020.06.13 09: 17: 35.152 342152 (GBPJPY, H1) Количество = 480
2020.06.13 09: 17: 35.152 342152 (GBPJPY, H1) Мин = 13
2020.06.13 09: 17: 35.152 342152 (GBPJPY, H1) Макс = 10468
2020.06.13 09: 17: 35.152 342152 (GBPJPY, H1) Avg = 660
2020.06.13 09: 17: 35.152 342152 (CHFJPY, H1) Количество = 480
2020.06.13 09: 17: 35.152 342152 (CHFJPY, H1) Min = 11
2020.06.13 09: 17: 35.152 342152 (CHFJPY, H1) Макс = 10474
2020.06.13 09: 17: 35.152 342152 (AUDNZD, H1) Количество = 480
2020.06.13 09: 17: 35.152 342152 (AUDNZD, H1) Min = 61
2020.06.13 09: 17: 35.152 342152 (AUDNZD, H1) Макс = 10491
2020.06.13 09: 17: 35.152 342152 (AUDNZD, H1) Avg = 663
2020.06.13 09: 17: 35.152 342152 (EURCHF, H1) Макс = 17414
2020.06.13 09: 17: 35.152 342152 (EURCHF, H1) Avg = 646
2020.06.13 09: 17: 35.152 342152 (AUDCAD, H1) Количество = 480
2020.06.13 09: 17: 35.152 342152 (AUDCAD, H1) Min = 100
2020.06.13 09: 17: 35.152 342152 (AUDCAD, H1) Макс = 17421
2020.06.13 09: 17: 35.152 342152 (AUDCAD, H1) Avg = 638
2020.06.13 09: 17: 35.152 342152 (USDCAD, H1) Макс = 10488
2020.06.13 09: 17: 35.152 342152 (USDCAD, H1) Avg = 666
2020.06.13 09: 17: 35.152 342152 (CHFJPY, H1) Avg = 656

Так что все произошло одновременно. Но это все еще может быть проблемой MT5. Я проверю с другими одновременными терминалами.

Судя по логам, замедление в одном не совпало с замедлением в другом, т.е. не одновременно. Значит, проблема в самом терминале.

 

Работа (Get/Set методы) с чартом у MQL5 программ идет через транзакционную очередь.

Это позволяет развязать работу GUI и самого терминала от неминуемых блокировок, которые устраивали(устраивают) бы MQL5 программы.

Транзакционная асинхронность позволяет массово быстро писать или читать в разделенных режимах и мгновенно включает режим синхронизации при смешении Set и Get методов.

То есть, лучше 1000 раз сделать асинхронные Set, а потом 1000 раз Get вместо того, чтобы делать поочередные Get & Set, превращая очередь в синхронный процесс. Потому что надо удостовериться, что предыдущий асинхронный Set точно наложился и теперь можно его читать.


Нужно аккуратно пользоваться системными функциями и кешировать их по возможности.

 
Renat Fatkhullin:

Нужно аккуратно пользоваться системными функциями и кешировать их по возможности.

Добрый день, проблема немного в другом - в ОЧЕНЬ медленном выполнении ChartGetInteger и подобных функций.
При переходе с 2009 билда на 2485 пиковое время выполнения ChartGetInteger увеличилось с 5 мс до 200-250 мс, особенно проявляется проблема при 50+ открытых чартах.
Система: Terminal Windows 10 build 18363, Intel Core i7-7700HQ  @ 2.80GHz, 19 / 31 Gb memory, 262 / 640 Gb disk, 4К монитор, NVidia 1050Ti 
Использовался код из описания проблемы: https://www.mql5.com/en/forum/342152

Возможные причины проблемы:

Ошибки, баги, вопросы

Sergey Dzyublik, 2020.06.13 19:20

Сравнил реализации функции ChartGetInteger для двух версий МТ5 2009 и МТ5 2485, возможно проблема в следующем:
1. В 2485 для чтения "атомарных" полей объекта чарта используются достаточно медленные операции:
mfence; lock mov eax,[rax+2C];
При этом в 2009 билде это делается с помощью: lock xadd [rcx+2C],eax

2. Так же похоже, что значительно изменилась логика и возможное время пребывания в ntdll_RtlEnterCriticalSection.
Раньше в 2009 в критической секции проверялась лишь пара полученных значений, без каких-либо атомарных операций.
А в 2485 может дополнительно выполняться перебор по linked-list объектам чарта.


Предположительно, проблема могла возникнуть, когда фиксили краш при работе с функциями чарта в рамках перехода на новый компилятор (месяца 2-3 назад).
Assembler-код для вызова ChartGetInteger в МТ5 (build 2485) находится во вложении.



 
Проверим.
 
Renat Fatkhullin:
Проверим.

Шаги для воспроизведения:

long chart_id;

int OnInit(){
   for(int i = 0; i < 95; ++i){
      ChartOpen(_Symbol, _Period);
   }

   chart_id = ChartID();
   EventSetMillisecondTimer(250);
   return(INIT_SUCCEEDED);
}

void OnTimer(){
  ulong t=GetMicrosecondCount();
  long autoscroll = ChartGetInteger(chart_id, CHART_AUTOSCROLL);
  ulong delay =(GetMicrosecondCount()-t)/1000;
  if (delay>0){
    Print("Execution delay: ",delay, " ms");
  }
}


1. Взять чистый МТ терминал, открыть на нем один чарт, запустить на этом чарте скомпилированный эксперт, приведенный выше.
2. После открытия всех 95 новых чартов, развернуть окно чарта на всю ширину пространства для чартов в МТ, если этого не было сделано ранее.
3. Переходить с вкладки чарта на другую и фиксировать из лога показатели времени выполнения функции ChartGetInteger.
Для закрытия всех открытых чартов можно зажать и держать комбинацию CTRL + W


Результат МТ5 (build 2009):

2020.06.14 15:33:43.173 Test123456 (EURUSD,H1)  Execution delay: 2 ms
2020.06.14 15:33:43.674 Test123456 (EURUSD,H1)  Execution delay: 3 ms
2020.06.14 15:33:44.177 Test123456 (EURUSD,H1)  Execution delay: 5 ms
2020.06.14 15:33:44.422 Test123456 (EURUSD,H1)  Execution delay: 4 ms
2020.06.14 15:33:44.673 Test123456 (EURUSD,H1)  Execution delay: 2 ms
2020.06.14 15:33:44.923 Test123456 (EURUSD,H1)  Execution delay: 3 ms
2020.06.14 15:33:45.173 Test123456 (EURUSD,H1)  Execution delay: 2 ms
2020.06.14 15:33:45.423 Test123456 (EURUSD,H1)  Execution delay: 2 ms
2020.06.14 15:33:45.672 Test123456 (EURUSD,H1)  Execution delay: 2 ms


Результат МТ5 (buidl 2485):

2020.06.14 15:33:12.947 Test123456 (EURUSD,H1)  Execution delay: 163 ms
2020.06.14 15:33:13.198 Test123456 (EURUSD,H1)  Execution delay: 1 ms
2020.06.14 15:33:13.293 Test123456 (EURUSD,H1)  Execution delay: 1 ms
2020.06.14 15:33:13.831 Test123456 (EURUSD,H1)  Execution delay: 287 ms
2020.06.14 15:33:14.702 Test123456 (EURUSD,H1)  Execution delay: 136 ms
2020.06.14 15:33:15.316 Test123456 (EURUSD,H1)  Execution delay: 3 ms
2020.06.14 15:33:15.677 Test123456 (EURUSD,H1)  Execution delay: 110 ms
2020.06.14 15:33:17.041 Test123456 (EURUSD,H1)  Execution delay: 221 ms


Сравнение результатов и выводы:
1. Количество записей которое выводится в 2009 билде значительно больше, чем записей в 2485 билде.
Функция ChartGetInteger в "обычных условиях" стала выполняться быстрее при переходе на билд 2485.

2. Пиковое время выполнения для 2009 билда - 15 мс, а для 2485 билда - 310 мс.
Функция ChartGetInteger в "неблагоприятных условиях" стала выполняться до 20 раз медленнее при переходе на билд 2485.

3. Так же на глаз можно оценить скорость открытия 95 чартов.
Для обоих билдов заметна "экспоненциальная" сложность от количества ранее открытых чартов, а также значительно более быстрое исполнение в 2009 билде.

 
Stanislav Korotky :

Судя по логам, замедление в одном не совпало с замедлением в другом, т.е. не одновременно. Значит, проблема в самом терминале.

Журнал печатается только каждую минуту (перевод испортил отметку времени !!), я мог бы проверить более точно, но это того не стоит.

Я пробовал на нескольких терминалах, и это ясно показывает, что пики НЕ являются одновременными. Это явно вещь МТ5.

 
Renat Fatkhullin :

Работа (Get/Set методы) с чартом у MQL5 программ идет через транзакционную очередь.

Это позволяет развязать работу GUI и самого терминала от неминуемых блокировок, которые устраивали(устраивают) бы MQL5 программы.

Транзакционная асинхронность позволяет массово быстро писать или читать в разделенных режимах и мгновенно включает режим синхронизации при смешении Set и Get методов.

То есть, лучше 1000 раз сделать асинхронные Set, а потом 1000 раз Get вместо того, чтобы делать поочередные Get & Set, превращая очередь в синхронный процесс. Потому что надо удостовериться, что предыдущий асинхронный Set точно наложился и теперь можно его читать.


Нужно аккуратно пользоваться системными функциями и кешировать их по возможности.

Это понятная и хорошая система. Но я думаю, что где-то есть сбой, что также продемонстрировал @Sergey Dzyubli.
Sergey Dzyublik
Sergey Dzyublik
  • www.mql5.com
Добавил тему Вход через MQL5.community (OAuth) В настройках профиля появилась новая вкладка Приложения (https://www.mql5.com/ru/users/USER_NAME/apps): Эта функция позволяет людям авторизоваться на вашем сайте или в приложении, используя аккаунт MQL5.community. Технология проста и безопасна. Она Добавил...
 
Alexey Navoykov:
Насколько я знаю, вызов ChartRedraw не приводит к немедленной перерисовке графика.  Перерисовка происходит только при вызове какого-нибудь Get-метода.
А ChartRedraw по сути такой же асинхронный метод.  Так что ваш замер BuildChart не достоверен.

попробуйте поменяйте эти две строчки местами

тогда не будет ничего асинхронного в замере и посмотрите что будет. Будет еще быстрее.

 
fxsaber:
Долго тупил, не понимая, что не нравится в этой строке компилятору.

Забыл if написать. Подумал, что для таких тупняков хорошо бы разжевать сообщение.

просил сделать описание и пример для всех ошибок и предупреждений компилятора еще лет 5 назад, может больше.

может быть у вас получится лучше.

 
Renat Fatkhullin:

Работа (Get/Set методы) с чартом у MQL5 программ идет через транзакционную очередь.

Это позволяет развязать работу GUI и самого терминала от неминуемых блокировок, которые устраивали(устраивают) бы MQL5 программы.

Транзакционная асинхронность позволяет массово быстро писать или читать в разделенных режимах и мгновенно включает режим синхронизации при смешении Set и Get методов.

То есть, лучше 1000 раз сделать асинхронные Set, а потом 1000 раз Get вместо того, чтобы делать поочередные Get & Set, превращая очередь в синхронный процесс. Потому что надо удостовериться, что предыдущий асинхронный Set точно наложился и теперь можно его читать.


Нужно аккуратно пользоваться системными функциями и кешировать их по возможности.

Я правильно понимаю, что асинхронными являются не только Set методы, но и Get? 
Т.е. Ильяс тут  был не прав?
При этом Слава здесь был прав, когда говорил о асинхронности метода ChartXYToTimePrice? Ведь метод ChartXYToTimePrice относится скорей всего к Get методам.

В документации  про асинхронность говорится только про Set методы.

Причина обращения: