Уже давно я заметил, что с компилятором MQL при выполнении бенчмарков происходит что-то странное,
Если количество сравниваемых функций превышает определенный предел ?!, то вы не получаете правильных результатов (т.е. функции в конце mq5 файла получают лучшие результаты с наименьшим временем выполнения, а верхние функции имеют плохие результаты). Такое уже случалось со мной, поэтому лучше ограничить сравниваемые функции до 3/4 максимума. Если у кого-то есть объяснение этому странному явлению, пожалуйста, просветите меня.
Это произошло и здесь, когда версия Доминика была добавлена в файл скрипта бенчмарка.
Чтобы получить более наглядное представление, я просто сохранил в исходном коде только две функции, и вот мои результаты в сравнении:
Одинаковая производительность, и обеим удалось опуститься ниже 5 наносекунд.
О, я помню ту дискуссию, где я сказал, что добавление комментария меняет поведение производительности функций в одном и том же mqh-файле...
Не было ли это связано с алгоритмом радиксной сортировки?
В качестве объяснения я пришел к выводу, что дело в подкачке памяти. Но это было неудовлетворительно, так как я только добавлял комментарии.
Редактировать:
Итак, вывод: функции работают одинаково, примерно.
О, я помню ту дискуссию, где я сказал, что добавление комментария меняет поведение функций в одном и том же mqh-файле...
Разве это не было связано с алгоритмом радиксной сортировки?
В качестве объяснения я пришел к выводу, что это связано с подкачкой памяти. Но это было неудовлетворительно, так как я только добавил комментарии.
Редактировать:
В итоге, функции работают одинаково, примерно.
Да, точно, мы столкнулись с той же проблемой при тестировании радиксной сортировки. Проблема до сих пор существует.
Я не знаю, проблема ли это с оптимизациями, применяемыми компилятором, или процессор увеличивает тактовую частоту (прогрев, турбо-ускорение или что-то еще...).
Да, точно, мы столкнулись с той же проблемой при тестировании radix sort. Проблема все еще существует.
Я не знаю, является ли это проблемой применяемых компилятором оптимизаций, или процессор увеличивает тактовую частоту (прогрев, турбо-ускорение или что-то еще...).
Вот версия с минимальным объемом памяти, но почему-то я не могу заменить const uint t на переменную из структуры. - Если я это делаю, то получаю ошибку "array out of range". - Есть идеи?
Да, это немного странно, хотя у меня есть проблемы с воспроизведением... - Та же история, что и тогда, у меня была проблема, но никто другой не мог ее воспроизвести.
Вот версия с минимальным объемом памяти, но по какой-то причине я не могу заменить const uint t на переменную из структуры. - Если я это делаю, то получаю ошибку "массив вне диапазона". - Есть идеи?
Вот так (возможно, для цифровых часов с ограниченной памятью):
после 2038 года счетчик секунд (временная метка unix) достигнет INT_MAX, поэтому вы должны продолжать использовать тип uint для секунд (чтобы избежать отрицательных значений).
Обратите внимание, что поля MqlDateTime - это ints, поэтому вам придется приводить повторно используемое поле. Приведение к тому же количеству битов или большему (расширяющее приведение) не изменяет биты. Меняется только интерпретация знакового бита (2'complement).
Вот она (возможно, для цифровых часов с ограниченной памятью):
после 2038 года счетчик секунд (временная метка unix) достигнет INT_MAX, поэтому вы должны продолжать использовать тип uint для секунд (чтобы избежать отрицательных значений).
Обратите внимание, что поля MqlDateTime - это ints, поэтому вам придется приводить повторно используемое поле. Приведение к тому же количеству битов или большему (расширяющее приведение) не изменяет биты. Меняется только интерпретация знакового бита (2'complement).
Спасибо. Да, я видел это сегодня утром. Вчера я был слишком измотан.
Теперь эта функция занимает 2 строки кэша, а вытаскивать нужно только одну, так как вторая уже будет содержать структуру MqlDateTime. Всего 92 байта, MqlDateTime, предварительно загруженный стеком функции, плюс datetime. Все вместе - 40 байт. А статический массив - 13*4 = 52 байта.
Я не думаю, что можно еще больше оптимизировать эту функцию в ее нынешнем виде.
Спасибо. Да, я видел его сегодня утром. Вчера я был слишком измотан.
Теперь эта функция занимает 2 строки кэша, а вытаскивать нужно только одну, так как вторая уже содержит структуру MqlDateTime. Всего 92 байта, MqlDateTime, предварительно загруженный стеком функции, плюс datetime. Все вместе - 40 байт. А статический массив - 13*4 = 52 байта.
Я не думаю, что можно еще больше оптимизировать эту функцию в ее нынешнем виде.
У вас на компьютере не хватает памяти?!
Редактировать:
Переменные будут оптимизированы в регистры процессора, а не в кэш.
Код будет оптимизирован в регистры процессора, а не в кэш.
Да, разницы больше нет. - Или, по крайней мере, не поддается измерению.
Это было из любопытства.
EDIT: В виртуальной машине он действительно показывает небольшую тенденцию к минимально лучшей производительности, когда кэш-линия и память оптимизированы. - Хотя этот тест очень синтетический. И это всего лишь тенденция... не гарантия, так что это может быть связано с планировщиком ОС, или с тем, что находится между кодом и процессором...
BTW: Я удалил закомментированные строки из функции, что дало ей немного edge..... - Почему так происходит, но поскольку мы находимся в области пикосекунд, то и выводы из этого сделать невозможно.
Для авторизации и пользования сайтом MQL5.com необходимо разрешить использование файлов Сookie.
Пожалуйста, включите в вашем браузере данную настройку, иначе вы не сможете авторизоваться.
Вы вошли в аккаунт. Двухфакторная аутентификация отключена. Настройте её заново и отсканируйте новый QR-код или продолжите с отключённой двухфакторной аутентификацией.
Уже давно я заметил, что с компилятором MQL при выполнении бенчмарков происходит что-то странное,
Если количество сравниваемых функций превышает определенный предел ?!, то вы не получаете правильных результатов (т.е. функции в конце mq5 файла получают лучшие результаты с наименьшим временем выполнения, а верхние функции имеют плохие результаты). Такое уже случалось со мной, поэтому лучше ограничить сравниваемые функции до 3/4 максимума. Если у кого-то есть объяснение этому странному явлению, пожалуйста, просветите меня.
Это произошло и здесь, когда версия Доминика была добавлена в файл скрипта бенчмарка.
Чтобы получить более наглядное представление, я просто сохранил в исходном коде только две функции, и вот мои результаты в сравнении:
Одинаковая производительность, и обеим удалось опуститься ниже 5 наносекунд.
Да, точно, мы столкнулись с той же проблемой при тестировании радиксной сортировки. Проблема до сих пор существует.
Я не знаю, проблема ли это с оптимизациями, применяемыми компилятором, или процессор увеличивает тактовую частоту (прогрев, турбо-ускорение или что-то еще...).
Да, точно, мы столкнулись с той же проблемой при тестировании radix sort. Проблема все еще существует.
Я не знаю, является ли это проблемой применяемых компилятором оптимизаций, или процессор увеличивает тактовую частоту (прогрев, турбо-ускорение или что-то еще...).
Вот версия с минимальным объемом памяти, но почему-то я не могу заменить const uint t на переменную из структуры. - Если я это делаю, то получаю ошибку "array out of range". - Есть идеи?
EDIT:
Да, это немного странно, хотя у меня есть проблемы с воспроизведением... - Та же история, что и тогда, у меня была проблема, но никто другой не мог ее воспроизвести.
Результаты из прикрепленного файла:
Вот версия с минимальным объемом памяти, но по какой-то причине я не могу заменить const uint t на переменную из структуры. - Если я это делаю, то получаю ошибку "массив вне диапазона". - Есть идеи?
Вот так (возможно, для цифровых часов с ограниченной памятью):
после 2038 года счетчик секунд (временная метка unix) достигнет INT_MAX, поэтому вы должны продолжать использовать тип uint для секунд (чтобы избежать отрицательных значений).
Обратите внимание, что поля MqlDateTime - это ints, поэтому вам придется приводить повторно используемое поле. Приведение к тому же количеству битов или большему (расширяющее приведение) не изменяет биты. Меняется только интерпретация знакового бита (2'complement).
Вот она (возможно, для цифровых часов с ограниченной памятью):
после 2038 года счетчик секунд (временная метка unix) достигнет INT_MAX, поэтому вы должны продолжать использовать тип uint для секунд (чтобы избежать отрицательных значений).
Обратите внимание, что поля MqlDateTime - это ints, поэтому вам придется приводить повторно используемое поле. Приведение к тому же количеству битов или большему (расширяющее приведение) не изменяет биты. Меняется только интерпретация знакового бита (2'complement).
На вашем компьютере не хватает памяти?!
Да, разницы больше нет. - Или, по крайней мере, не поддается измерению.
Это было из любопытства.
EDIT: В виртуальной машине он действительно показывает небольшую тенденцию к минимально лучшей производительности, когда кэш-линия и память оптимизированы. - Хотя этот тест очень синтетический. И это всего лишь тенденция... не гарантия, так что это может быть связано с планировщиком ОС, или с тем, что находится между кодом и процессором...
BTW: Я удалил закомментированные строки из функции, что дало ей немного edge..... - Почему так происходит, но поскольку мы находимся в области пикосекунд, то и выводы из этого сделать невозможно.Я удалю эту функцию из бенчмарка, так как она ненадежна:
Я скомпилировал его на своей машине как обычный X64, без оптимизаций, после чего получил такой результат
Небольшое исправление (приведение datetime к uint), но увеличивающее производительность в два раза:
Обновленные бенчмарки v1.10:
Я удалю эту функцию из бенчмарка, так как она не является надежной:
Я скомпилировал его на своей машине как обычный X64, без оптимизаций, после чего получил такой результат