Новая версия платформы MetaTrader 5 build 3620: улучшения веб-терминала, поддержка ONNX и ускоренное умножение матриц в MQL5 - страница 13

 
fxsaber #:

SHIFT+L?

<Delete>

 
fxsaber #:

Повторяю вопрос.

Вот такое в конце лога Агента.

После этого Старт не нажимается. Нигде ничего не пишется. Происходит несколько раз в день. Приходится перегружать Терминал - временно помогает.

Странно, что до этого у вас всё было хорошо а теперь не работает, то есть или с компьютером или с обновлением терминала дело.

Понаблюдаем в дальнейшем.

 
fxsaber #:

b3624 - актуально.

Компилятор имеет множество различных отсечек (threshold), чтобы не "убиться" во время оптимизаций.

Вы нашли одну из них -  loop unrolling threshold (срабатывает для внутреннего цикла)

Данные по отсечкам мы не публикуем, потому что они могут поменяться в будущем.


Опубликованный код вырожденный = ничего не делает
При разворачивании внутреннего цикла, оптимизатор успешно распространяет нули из массива, после чего внутренний цикл сокращается полностью, что приводит и к удалению внешнего пустого цикла.
В результате, тело функции OnTick оказывается пустым, т.е. вы получаете время выполнения тестором пустой функции.

Может возникнуть вопрос почему 75?
Число получено эксперементальным путём, но для кода, который выполняет реальную нагрузку на CPU (не вырождается при разворачивании цикла).

Для информации, в реальности, при развёртке, оценивается не количество итераций цикла, а его "мощность" (условно, количество итераций * размер тела)

 
Ilyas #:

Для информации, в реальности, при развёртке, оценивается не размер цикла, а его "мощность" (условно, размер * тело)

Спасибо за исчерпывающий ответ!

 
Ilyas #:

Опубликованный код вырожденный = ничего не делает

Вроде, оригинальный код не является вырожденным:

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Новая версия платформы MetaTrader 5 build 3550: улучшения и исправления

fxsaber, 2023.03.01 23:53

double OnTesterValue = 0;
double OnTester() { return(OnTesterValue); }

#define SIZE 74

void OnTick()
{
  static const double Array[SIZE] = {};
     
  for (int j = 0; j < 74 * 75 * 10 / SIZE; j++)
    for (int i = 0; i < SIZE; i++)
      OnTesterValue += Array[i];
}
 
fxsaber #:

Вроде, оригинальный код не является вырожденным:

вот же пояснение, почему код вырожденный

При разворачивании внутреннего цикла, оптимизатор успешно распространяет нули из массива, после чего внутренний цикл сокращается полностью, что приводит и к удалению внешнего пустого цикла.


 

Ilyas #:

...

Для информации, в реальности, при развёртке, оценивается не размер цикла, а его "мощность" (условно, размер * тело)

Здесь под размером имелось в виду количество итераций

Переписал это предложение в оригинальном посте

 
Ilyas #:

При разворачивании внутреннего цикла, оптимизатор успешно распространяет нули из массива, после чего внутренний цикл сокращается полностью, что приводит и к удалению внешнего пустого цикла.

Если бы 74 элемента были бы заполнены данными в момент инициализации, эффект был бы тот же?

 
fxsaber #:

Если бы 74 элемента были бы заполнены данными в момент инициализации, эффект был бы тот же?

Да, по времени, 74/75 будут отличаться, но уже не так сильно.

Как и с нолями в массиве, внутренний цикл будет развёрнут, но внешний останется, т.к. внутренний уже не будет пустым

 
Renat Fatkhullin #:

В четверке на самом деле сам терминал для каждого эксперта создает и обновляет фоновую копию/снапшот текущего чарта, чтобы робот потом мог по ней бегать без блокировок.

Преставьте себе, что перед вызовом OnTick происходит CopyRates всей истории в фоновой буфер робота. Конечно, с массой трюков для ускорения. В любом случае, это затратно по памяти и достаточно дорого. Обновление буфера добавляет латенси у реакции на OnTick.

Так как эти фоновые затраты идут вне контекста выполнения робота на MQL4, вам кажется, что скорость внутри MQL4 высока и бесплатна. Но удар по памяти и CPU все равно остается из-за расходов на фоновой буфер.

Причем учтите, то копируется только текущий чарт, что позволяет достаточно быстро работать iOpen/iHigh/iLow/iClose функциям на своем чарте. А вот доступ к другим таймфреймам и символам уже через Copy семантику, что выливается в синхронизированный доступ к базе истории как в пятерке.


Пятерка в этом отношении более честна и экономна:

  1. Нет фоновых буферов и фоновой работы вне пределов MQL5
  2. Экономнее расход памяти
  3. Никто не добавляет задержек при реакции на OnTick
Так как пятерка имеет на порядок больше данных, то попытка делать и обновлять фоновые буферы просто убила бы систему.

Подскажите пожалуйста еще немного.

  1. Я запрашиваю данные баров чужого графика с помощью ArrayCopyRates()
  2. Приходит новый тик
  3. Я вызываю iCustom() для того-же чужого графика

Эти 3 пункта происходят в пределах одного и того-же исполнения OnTick().

В iCustom будет учтен этот пришедший тик? Или индикатор будет вычислен на тех-же данных, которые скопировала ArrayCopyRates()?