В попытке ускорения работы, когда создавал этот пример, совершенно случайно столкнулся с одной странностью, которую просто отложил на полку.
И сейчас, когда я попытался разобраться с этой странностью, запутался еще больше.
Итак, в расчете я использую функцию квадратного корня sqrt(), которую я решил обойти путем создания double массива.
Т.к. я беру квадратный корень всегда с целых чисел, то создание массива выглядит так:
double SQRT[];
int ss=Width*Width+Height*Height;
ArrayResize(SQRT,ss);
for(double w=0;w<ss;w++) SQRT[(int)w]=sqrt(w);
Логично предположить, что считывание из массива SQRT[x] выполняется быстрее, чем функция sqrt(x). И это подтверждается проверочным кодом:
double Sum1=0,Sum2=0;
ulong t=GetMicrosecondCount();
for(int i=0;i<ss;i++) Sum1+=sqrt(double(i)); // Находим сумму квадратных корней всех целых чисел от 0 до ss
t=GetMicrosecondCount()-t;
Print("Время на сумму "+IntegerToString(ss)+" значений функций = "+IntegerToString(t)+" мкс, Сумма = "+DoubleToString(Sum1));
t=GetMicrosecondCount();
for(int i=0;i<ss;i++) Sum2+=SQRT[(int)(i)]; // Находим сумму квадратных корней всех целых чисел от 0 до ss через сложение элементов массива SQRT[]
t=GetMicrosecondCount()-t;
Print("Время на сумму "+IntegerToString(ss)+" значений массива = "+IntegerToString(t)+" мкс, Сумма = "+DoubleToString(Sum2));
результат свидетельствует о выигрыше скорости ~ 1.5 раза:
Но когда я заменяю в коде функцию sqrt() на считывание элементов массива SQRT[], вместо ускорения работы, я получаю жуткие тормоза.
Считывание элемента из массиваа SQRT[] происходит в разы, может быть даже на порядок дольше, чем выполнение функции sqrt().
И я не понимаю, где происходит утечка скорости. Ведь вышеуказанный проверочный код говорит об обратном.
Можно предположить, что компилятор каким-то странным образом осуществляет доступ к большому массиву и на каждом витке цикла словно "забывает" о массиве и каждый раз проводит свою какую-то служебную индексацию.
Но тогда это внутренний логический или стратегический баг компилятора. Причем с этим нужно явно что-то делать, т.к. эта утечка скорости очень существенна и ее трудно обнаружить, т.к. она не очевидна.
Прилагаю код скрипта для демонстрации этой странности.
При запуске по умолчанию (arr=false) вычисляются функции sqrt(), а при изменении arr на true значение квадратного корня берется из массива.
В попытке ускорения работы, когда создавал этот пример, совершенно случайно столкнулся с одной странностью, которую просто отложил на полку.
Логично предположить, что считывание из массива SQRT[x] выполняется быстрее, чем функция sqrt(x).
Из динамического массива не факт.
Тем более, что взятие корня давно уже в есть на уровне команды процессора SQRTSD. То есть, с помощью заведомых расходов на доступ в динамическом массиве, выиграть у процессорной реализации уже не получится.
И это подтверждается проверочным кодом:
результат свидетельствует о выигрыше скорости ~ 1.5 раза:
Сомневаюсь, что подтверждается.
Код такого вида прям как из учебника по оптимизации циклов. Оптимизатор кода из него просто конфетку может сделать, так как случай очень простой:
for(int i=0;i<ss;i++)
Sum2+=SQRT[i];
То есть, замер производительности в случае применения заведомо идеально оптимизируемых случаев нужно четко соотносить с целями теста.
В данном случае тест неправильный.
Считывание элемента из массиваа SQRT[] происходит в разы, может быть даже на порядок дольше, чем выполнение функции sqrt().
И я не понимаю, где происходит утечка скорости. Ведь вышеуказанный проверочный код говорит об обратном.
Не видя финального ассемблерного кода, я склоняюсь к:
sqrt на самом деле быстро работает (у нас очень эффективный генератор в нативный код, sqrt превращается в чистый SQRTSD)
проверочный код слишком прост и компенсирует задержки оптимизацией
Код весь проверим внимательно. Интересно найти, в чем реальная причина.
Computes square root of the low double-precision floating-point value in xmm3/m64 and stores the results in xmm1 under writemask k1. Also, upper double-precision floating-point value (bits[127:64]) from xmm2 is copied to xmm1[127:64].
Нет чистых доказательств ваших расчетов, вы делаете предположения на основе очень замусоренного кода.
Вы пренебрегаете тонной вспомогательных расчетов, которые находятся в вашем коде и оказывают значительное влияние на результаты.
Я лишь вижу, что просто поменяв sqrt на простое чтение из массива, общая скорость расчета падает в 4 раза. А общая доля sqrt в этом достаточно большом расчете каждого пикселя вряд ли превышает 10%, а то и нескольких %.
Явная аномалия!
Я даже ошибся сказав, что время доступа к элементу массива больше в 10 раз времени sqrt. Гораздо больше с учетом того, что sqrt так быстр, а общее замедление так велико.
Я лишь вижу, что просто поменяв sqrt на простое чтение из массива, общая скорость расчета падает в 4 раза. А общая доля sqrt в этом достаточно большом расчете каждого пикселя вряд ли превышает 10%, а то и нескольких %.
Явная аномалия!
Я объяснил почему. Оптимизации математики девяностых годов уже не работают.
Но вы продолжаете делать следующие утверждения на основе реально замусоренного кода. Заводомо ошибочные.
На таком уровне технической [не]чистоты я не буду обсуждать вопросы.
Сообщение об ошибке не позволяет понять причину в обширном коде
ниже понятно
Нет сообщения об ошибке
более того - выполняется и даже результат есть (!)
В таком варианте:
не работает переход к строке ошибки (по Enter)
Ошибка при компиляции
В попытке ускорения работы, когда создавал этот пример, совершенно случайно столкнулся с одной странностью, которую просто отложил на полку.
И сейчас, когда я попытался разобраться с этой странностью, запутался еще больше.
Итак, в расчете я использую функцию квадратного корня sqrt(), которую я решил обойти путем создания double массива.
Т.к. я беру квадратный корень всегда с целых чисел, то создание массива выглядит так:
Логично предположить, что считывание из массива SQRT[x] выполняется быстрее, чем функция sqrt(x).
И это подтверждается проверочным кодом:
результат свидетельствует о выигрыше скорости ~ 1.5 раза:
Но когда я заменяю в коде функцию sqrt() на считывание элементов массива SQRT[], вместо ускорения работы, я получаю жуткие тормоза.
Считывание элемента из массиваа SQRT[] происходит в разы, может быть даже на порядок дольше, чем выполнение функции sqrt().
И я не понимаю, где происходит утечка скорости. Ведь вышеуказанный проверочный код говорит об обратном.
Можно предположить, что компилятор каким-то странным образом осуществляет доступ к большому массиву и на каждом витке цикла словно "забывает" о массиве и каждый раз проводит свою какую-то служебную индексацию.
Но тогда это внутренний логический или стратегический баг компилятора. Причем с этим нужно явно что-то делать, т.к. эта утечка скорости очень существенна и ее трудно обнаружить, т.к. она не очевидна.
Прилагаю код скрипта для демонстрации этой странности.
При запуске по умолчанию (arr=false) вычисляются функции sqrt(), а при изменении arr на true значение квадратного корня берется из массива.
ЧТО НЕ ТАК? ОТКУДА ТОРМОЗА?
В попытке ускорения работы, когда создавал этот пример, совершенно случайно столкнулся с одной странностью, которую просто отложил на полку.
Логично предположить, что считывание из массива SQRT[x] выполняется быстрее, чем функция sqrt(x).
Из динамического массива не факт.
Тем более, что взятие корня давно уже в есть на уровне команды процессора SQRTSD. То есть, с помощью заведомых расходов на доступ в динамическом массиве, выиграть у процессорной реализации уже не получится.
И это подтверждается проверочным кодом:
результат свидетельствует о выигрыше скорости ~ 1.5 раза:
Сомневаюсь, что подтверждается.
Код такого вида прям как из учебника по оптимизации циклов. Оптимизатор кода из него просто конфетку может сделать, так как случай очень простой:
То есть, замер производительности в случае применения заведомо идеально оптимизируемых случаев нужно четко соотносить с целями теста.
В данном случае тест неправильный.
И я не понимаю, где происходит утечка скорости. Ведь вышеуказанный проверочный код говорит об обратном.
Не видя финального ассемблерного кода, я склоняюсь к:
Код весь проверим внимательно. Интересно найти, в чем реальная причина.
Из динамического массива не факт.
Не видя финального ассемблерного кода, я склоняюсь к:
Пробовал статический массив - тоже самое.
Как бы sqrt не был бы быстр, но мне сложно поверить в то, что эта функция может быть в 10 раз быть быстрее простого чтения элемента массива.
Причем, если в моем примере уменьшить размер канваса, скажем 50х50 ( для этого существует входной параметр Size, нужно вместо 0 установить 50),
и массив будет значительно меньше (5000 элементов), то скоростная картина заметно меняется. Нет уже такого сильного контраста.
Но мне не понятно, разве от размера массива зависит скорость доступа к его элементам?
А насчет простоты проверочного кода, пожалуй, Вы правы.
Попробовал чуть усложнить и результат совсем другой:
Код весь проверим внимательно. Интересно найти, в чем реальная причина.
Круто! Спасибо! Мне тоже интересно.
А sqrt, действительно, очень быстр. Меньше наносекунды :)). Фантастика!
Пробовал статический массив - тоже самое.
Как бы sqrt не был бы быстр, но мне сложно поверить в то, что эта функция может быть в 10 раз быть быстрее простого чтения элемента массива.
На текущий момент множество старых оптимизационных техник уже не работают.
Причем, если в моем примере уменьшить размер канваса, скажем 50х50 ( для этого существует входной параметр Size, нужно вместо 0 установить 50),
и массив будет значительно меньше (5000 элементов), то скоростная картина заметно меняется. Нет уже такого сильного контраста.
Но мне не понятно, разве от размера массива зависит скорость доступа к его элементам?
Нет чистых доказательств ваших расчетов, вы делаете предположения на основе очень замусоренного кода.
Вы пренебрегаете тонной вспомогательных расчетов, которые находятся в вашем коде и оказывают значительное влияние на результаты.
Нет чистых доказательств ваших расчетов, вы делаете предположения на основе очень замусоренного кода.
Вы пренебрегаете тонной вспомогательных расчетов, которые находятся в вашем коде и оказывают значительное влияние на результаты.
Я лишь вижу, что просто поменяв sqrt на простое чтение из массива, общая скорость расчета падает в 4 раза. А общая доля sqrt в этом достаточно большом расчете каждого пикселя вряд ли превышает 10%, а то и нескольких %.
Явная аномалия!
Я даже ошибся сказав, что время доступа к элементу массива больше в 10 раз времени sqrt. Гораздо больше с учетом того, что sqrt так быстр, а общее замедление так велико.
Я лишь вижу, что просто поменяв sqrt на простое чтение из массива, общая скорость расчета падает в 4 раза. А общая доля sqrt в этом достаточно большом расчете каждого пикселя вряд ли превышает 10%, а то и нескольких %.
Явная аномалия!
Я объяснил почему. Оптимизации математики девяностых годов уже не работают.
Но вы продолжаете делать следующие утверждения на основе реально замусоренного кода. Заводомо ошибочные.
На таком уровне технической [не]чистоты я не буду обсуждать вопросы.