Особенности языка mql5, тонкости и приёмы работы - страница 275
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Сравнение 3 имеющихся в моем распоряжении режимов компиляции (у меня нет AVX512).
Compiler Version: 4702 AVX2 + FMA3, optimization - true
Intel Core i7-9750H @ 2.60GHz, AVX2 + FMA3
Without hours (dt.hour+ dt.min+ dt.sec - off), random datetimes[].
1970.01.01 00:01:44 - 2097.11.29 23:59:41
6.29 ns, checksum = 1269354861838493 // TimeToStruct2100
5.90 ns, checksum = 1269354861838493 // TimeToStructFast
6.49 ns, checksum = 1269354861838493 // TimeToStructFast_fxsaber
3.60 ns, checksum = 1269354861838493 // TimeToCalendar
6.47 ns, checksum = 1269354861838493 // TimeToJulian
31.65 ns, checksum = 1269354861838493 /// MQL's TimeToStruct()
Compiler Version: 4702 AVX, optimization - true
Intel Core i7-9750H @ 2.60GHz, AVX2 + FMA3
Without hours (dt.hour+ dt.min+ dt.sec - off), random datetimes[].
1970.01.01 00:00:47 - 2097.11.29 23:59:41
6.30 ns, checksum = 1286714313014774 // TimeToStruct2100
5.92 ns, checksum = 1286714313014774 // TimeToStructFast
6.40 ns, checksum = 1286714313014774 // TimeToStructFast_fxsaber
6.46 ns, checksum = 1286714313014774 // TimeToCalendar
6.11 ns, checksum = 1286714313014774 // TimeToJulian
31.89 ns, checksum = 1286714313014774 /// MQL's TimeToStruct()
Compiler Version: 4702 X64 Regular, optimization - true
Intel Core i7-9750H @ 2.60GHz, AVX2 + FMA3
Without hours (dt.hour+ dt.min+ dt.sec - off), random datetimes[].
1970.01.01 00:00:09 - 2097.11.29 23:58:42
6.13 ns, checksum = 1257992266603185 // TimeToStruct2100
5.69 ns, checksum = 1257992266603185 // TimeToStructFast
6.37 ns, checksum = 1257992266603185 // TimeToStructFast_fxsaber
6.27 ns, checksum = 1257992266603185 // TimeToCalendar
13.06 ns, checksum = 1257992266603185 // TimeToJulian
31.63 ns, checksum = 1257992266603185 /// MQL's TimeToStruct()
Сравнение 3 имеющихся в моем распоряжении режимов компиляции (у меня нет AVX512).
Если интересно... Извиняюсь, не стал чистить.
Хорошо видно, что сильная зависимость от настроек компилятора. AVX2+FMA3 существенным образом влияет на TimeToCalendar.
Видимо, есть какие-то законы ускорения, когда много вот таких простых действий - выгоднее, чем мало сложных выражений.
Много простых.
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
Особенности языка mql5, тонкости и приёмы работы
amrali, 2024.11.26 18:33
Мало сложных.
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
Особенности языка mql5, тонкости и приёмы работы
fxsaber, 2024.11.27 14:32
Как по коду понять, какой из низ будет быстрее,- непонятно.
для чистоты, надо сравнивать с системной/библиотечной функций. (в системе несколько вариантов, что из них более "основное" затруднюсь ответить, кому интересно - выяснят)
вообще функций преобразования времени в структуры, всего 2: (1)Штатная от авторов терминала и MQL, (2) от авторов ОС и системных библиотек . И почти точно 1-я прямо или косвенно вызывает 2-ю.
PS/ ни в коем случае не буду использовать и никому не советую использовать их самопальные "быстрые" аналоги. Все измерения скорости это просто спорт ради соревнований и "чьё конфу круче" :-)
Как по коду понять, какой из низ будет быстрее,- непонятно.
Эх, где времена программирования на ассемблере... Я вычислял скорость, зная кол-во тактов каждой команды. Надо было, когда в 80х писал драйвер для нашей лабораторной аудиокарты и синтезатор речи для ГТС.
А по делу - если посчитать к-во мат. операций и оценить скорость каждого типа ( * / + - )?
А по делу - если посчитать к-во мат. операций и оценить скорость каждого типа ( * / + - )?
Считал. И не увидел причин такой разницы.
Эх, где времена программирования на ассемблере... Я вычислял скорость, зная кол-во тактов каждой команды. Надо было, когда в 80х писал драйвер для нашей лабораторной аудиокарты и синтезатор речи для ГТС.
А по делу - если посчитать к-во мат. операций и оценить скорость каждого типа ( * / + - )?
сейчас не увидишь и влёт не посчитаешь..ну или надо сильно вкурить конвееры, регистер-алиасинг,кеши и прочее.
это раньше было просто : вот процессор, он по одной исполняет команды. Общее время = сумма всех. Сейчас он всасывает пачку команд в кеш, внутри раскидывает в цепочки, планирует операции и одновременно всё это дело исполняет. примерно так
Сегодня вы этого не увидите и не вычислите... ну, или вам придется изучать конвекторы, сглаживание регистров, кэши и так далее.
Раньше все было просто: вот процессор, он выполняет команды одну за другой. Общее время = сумме всех. Теперь он засасывает кучу команд в кэш, выстраивает их в цепочки, планирует операции и выполняет все это одновременно. Примерно так
Мои наблюдения за результатами:
Этот код выполняется быстро, потому что:
* он использует наименьшее возможное количество делений и модуло (занимает много процессорных циклов).
* большинство переменных - 32-битные, беззнаковые типы.
* только одно ветвление (оператор conditionasl), поэтому конвейер процессора не перегружается.
* Код использует преимущества набора инструкций AVX2, который поддерживает FMA (fused multiply addition), в коде в основном используются * и +.
Посмотрите на контрасте, почему этот код медленнее:
без ветвлений, но с большим количеством div/модов.
Один трюк, который я недавно узнал о типе datetime -> приведение переменных datetime к ulong (или еще лучше к uint) дает огромное ускорение работы с переменными datetime (в зависимости от окружающего кода).
Здесь, в этом коде, вторая версия TimeHour() работает быстрее:
именно поэтому fxsaber обнаружил замедление в TimeToJulian, когда вычисляются hh:mm:ss. Потому что я забыл привести к ulong :-)
Использование предсказателя ветвей процессора может принести пользу микрооптимизации, см. здесь: https: //stackoverflow.com/a/11227902.
Хотя проверка isleap исключена из основного пути инструкций, она все равно выполняется в 84% случаев. (1 - 59/365). Поэтому большого улучшения здесь не произошло. Процессор предсказывает правильное ответвление в 84 % случаев при (doy < 59), но он находит там другое ответвление !(year & 3), поэтому конвейер инструкций приходится промывать и заполнять заново.
Наконец, я думаю, что это максимум, что мы можем оптимизировать, любая из первых 4 функций находится в пределах допустимой 10% вариативности, и любая из них даже быстрее встроенного TimeToStruct в 4-5 раз в MQL.
IMHO эти функции можно оптимизировать еще больше, добавив кэш, подобно встроенной функции TimeToStruct https://www.mql5.com/ru/forum/170952/page274#comment_55238816.
TimeToJulian может быть менее оптимизирована для работы.
Коэффициенты ускорения для подфункций (TimeYear, TimeDayOfWeek и т.д.) для извлечения компонентов времени, таких как yyyy/mm/dd hh:mm:ss, находятся в пределах 10-20 раз быстрее, чем TimeToStruct().
Высокопроизводительный код со сложными циклами for для сканирования истории котировок в поисках определенных паттернов или баров (начало торговых недель, другая статистика) только выиграет от этих оптимизаций.
Обычный код для торгового робота также может выиграть, но в меньшей степени.
С другой стороны медали, составление переменных datetime из компонентов времени (yyyy/mm/dd hh:mm:ss) с помощью пользовательской CreateDateTime() в качестве альтернативы StructToTime ускорится более чем в 30 раз.
Составление переменных времени действительно медленно на платформе MT5 и требует некоторого внимания со стороны разработчиков.
Для всех кэшированных версий я предлагаю следующее исправление возможной ошибки.
Изначально, когда функция вызывается несколько раз со временем 1970/1/1, она возвращает 000/00/00 для полей даты год, месяц.
-1 исправит эту ошибку, так что возвращаемые даты будут правильно 1970/1/1.