Оптимизация числодробилки
Apr. 6th, 2016 10:12 amРабочая программа для моделирования эволюции тройной звездной системы с учетом общей теории относительности непрерывно улучшалась и модифицировалась в течение последних десяти лет. В результате ее код превратился в такую кашу, что дальнейшая его поддержка стала невозможной.
Пришлось заняться рефакторингом, а заодно и оптимизацией.
В итоге код сократился в полтора раза, а быстродействие выросло в два раза. Интересно, что основной прирост быстродействия удалось получить, заменив везде где только можно деление умножением. Например, простая замена выражения a/(b/c+d/e) выражением a*c*e/(b*e+c*d) дает выигрыш в скорости выполнения в три раза.
Upd.: оптимизация компилятора отключена по причинам, которые обсуждаются далее в комментариях.
Upd2.: впрочем, для случая замены выражения a/(b/c+d/e) выражением a*c*e/(b*e+c*d) включение или выключение оптимизации не играет роли.
Пришлось заняться рефакторингом, а заодно и оптимизацией.
В итоге код сократился в полтора раза, а быстродействие выросло в два раза. Интересно, что основной прирост быстродействия удалось получить, заменив везде где только можно деление умножением. Например, простая замена выражения a/(b/c+d/e) выражением a*c*e/(b*e+c*d) дает выигрыш в скорости выполнения в три раза.
Upd.: оптимизация компилятора отключена по причинам, которые обсуждаются далее в комментариях.
Upd2.: впрочем, для случая замены выражения a/(b/c+d/e) выражением a*c*e/(b*e+c*d) включение или выключение оптимизации не играет роли.
(no subject)
Date: 2016-04-06 07:14 am (UTC)(no subject)
Date: 2016-04-06 07:22 am (UTC)(no subject)
Date: 2016-04-06 07:30 am (UTC)(no subject)
Date: 2016-04-06 07:50 am (UTC)(no subject)
Date: 2016-04-06 08:04 am (UTC)Я несколько раз свои числодробилки сравнивал с включенной и выключенной оптимизацией. Разница только в скорости счёта. Но у меня Монте-Карло, никакого долгого численного интегрирования.
(no subject)
Date: 2016-04-06 08:31 am (UTC)Включение оптимизации приводит к тому, что итоговый результат отличается. Понятно, что из-за потерь точности, результат после 10 миллионов оборотов всё равно не соответствует точному, но при отключенной оптимизации я, по крайней мере, способен контролировать код, а копаться каждый раз в ассемблерном коде, порожденном оптимизатором, у меня просто нет времени и сил.
(no subject)
Date: 2016-04-06 08:40 am (UTC)(no subject)
Date: 2016-04-06 08:53 am (UTC)(no subject)
Date: 2016-04-06 11:38 am (UTC)В данном случае вообще непонятно, из-за чего происходит ускорение. Кажется, что деление на 2. и умножение на 0.5 должно занимать одинаковое время.
(no subject)
Date: 2016-04-06 11:40 am (UTC)(no subject)
Date: 2016-04-06 12:03 pm (UTC)#include <iostream> #include <time.h> #include <stdio.h> using namespace std; double secnds() { return clock()*1./CLOCKS_PER_SEC; } void div() { double a=1,b=2,c=3,d=4,e=5,f=0; for (int i=0;i<1000;i++) for (int j=0;j<1000;j++) for (int k=0;k<1000;k++) { a+=0.00000001; b+=0.00000002; c+=0.00000003; d+=0.00000004; e+=0.00000005; f+=a/(b/c+d/e)+i+j+k; } printf("f = %21.13e\n",f); } void mul() { double a=1,b=2,c=3,d=4,e=5,f=0; for (int i=0;i<1000;i++) for (int j=0;j<1000;j++) for (int k=0;k<1000;k++) { a+=0.00000001; b+=0.00000002; c+=0.00000003; d+=0.00000004; e+=0.00000005; f+=a*c*e/(b*e+c*d)+i+j+k; } printf("f = %21.13e\n",f); } int main(int argc, char *argv[]) { double t = secnds(); mul(); cout << "mul, t = " << secnds() - t << "\n"; t = secnds(); div(); cout << "div, t = " << secnds() - t << "\n"; return 0; }(no subject)
Date: 2016-04-06 11:35 am (UTC)(no subject)
Date: 2016-04-06 12:04 pm (UTC)(no subject)
Date: 2016-04-06 02:56 pm (UTC)(no subject)
Date: 2016-04-06 09:54 pm (UTC)https://stackoverflow.com/questions/4125033/floating-point-division-vs-floating-point-multiplication
И это никак не зависит от оптимизатора, если только он не сможет заменить деление на что-то более быстрое.
В вашем случае видимо не может :(
Возможно стоит поискать алгоритм, который сделает необходимое вам вычисление с минимальной потерей
точности и с максимальной скоростью.
Для таких задач есть немало численных трюков, которые много лучше, чем простое решение "в лоб".
Я, к сожалению, их учил уже очень давно и забыл более чем все :(