LINUX.ORG.RU

Оптимизация в C++

 ,


0

1

Привет всем.Есть выражения: 1)a=b+c+d+e+f+g; 2)a=b*c*d*e*f*g; 2)a=(b+c)/(b-c)

Предлагаю для оптимизации заменить на:

1)a=b;a+=c;a+=d;a+=e;a+=f;a+=g; 2)a=b;a*=c;a*=d;a*=e;a*=f;a*=g; 3)int BpC=b;int BmC=b;BpC+=c;BmC-=c;BpC/=BmC;a=BpC;

Есть ли в этом смыл? Или лучше никогда на подобном не париться и давать оптимизационные параметры компилятору?

Есть ли в этом смыл?

нет /thread

Pavval ★★★★★
()
Последнее исправление: Pavval (всего исправлений: 1)
Ответ на: комментарий от mix_mix

но тебе об этом еще думать рано

Имеете в виду просто опыт или завершенность программы( обычно проводят оптимизацию всей программы после ее готовности или при разработке?).

this

в смысле?

Eclipse IDE по умолчанию дает такие команды компилятору -O0 -g3 -Wall -c -fmessage-length=0. Один из параметров, я припоминаю, точно должен быть оптимизация. А что приблизительно компилятор делает при таком параметре оптимизации?

Nerevarino
() автор топика
Ответ на: комментарий от Nerevarino

Эклипс по умолчанию у тебя собирает дебаг версию.-O0 значит никаких оптимизаций проведено не будет.

twentypercentcooler
()
Ответ на: комментарий от Nerevarino

в смысле?

В смысле «лучше никогда на подобном не париться и давать оптимизационные параметры компилятору».

Имеете в виду просто опыт или завершенность программы

Опыт. Лет через 5-10 можешь начать задумываться.

mix_mix ★★★★★
()

Не заморачивайся, плюс ко всему

a=b+c+d+e+f+g;

Будет работать быстрее чем

a=b;a+=c;a+=d;a+=e;a+=f;a+=g;

а

a=b*c*d*e*f*g;

быстрее чем

a=b;a*=c;a*=d;a*=e;a*=f;a*=g;

и конечно же

a=(b+c)/(b-c)

намного быстрее чем

int BpC=b;int BmC=b;BpC+=c;BmC-=c;BpC/=BmC;a=BpC;

zaz ★★★★
()

Если кто знает, по возможности, скажите чем именно будет заниматься компилятор, при задания ему такой команды?

Будет ли переупорядочивать группу не влияющих друг на друга от своей позиции команд, чтобы на проц шли порции однотипных команд (как на конвеер)?

Или будут оптимизации типа, как я написал?

Я где-то читал, что свои собственные оптимизационные поправки к коду могу мешать компилятору понять, как ЕМУ лучше оптимизировать код.

Nerevarino
() автор топика
Ответ на: комментарий от Nerevarino

Если кто знает, по возможности, скажите чем именно будет заниматься компилятор, при задания ему такой команды?

Ничем. Это сделано для удобства отладки. Релизную версию стоит собирать с -O2.

Будет ли переупорядочивать группу не влияющих друг на друга от своей позиции команд, чтобы на проц шли порции однотипных команд (как на конвеер)?

Без оптимизации нет, с ней да. Вообще, если хоть немного знаешь ассемблер, изучи выхлоп с опцией -S, большинство вопросов отпадут сами собой.

Я где-то читал, что свои собственные оптимизационные поправки к коду могу мешать компилятору понять, как ЕМУ лучше оптимизировать код.

В большинстве случаев мешать не будут, но читающих твой код людей еще как.

mix_mix ★★★★★
()

Возьми да проверь сам, что ты как не мужик?
Напиши сишную программу, в которой попробуй изобразить свои оптимизации. Собери ее с ключами -O0 -S, это даст тебе асмовый выхлоп.
В первом случае, разницы абсолютно никакой. По крайней мере по количеству команд.
Я более чем уверен, что современные компиляторы умеют оптимизировать подобные штуки, поэтому заморачиваться над такими мелочами не стоит.

Deleted
()
Ответ на: комментарий от zaz

В интернете я видел совсем наоборот, все ссылку не могу найти.

Но там была фишка в том, что нужно избегать выражений, где будут создаваться локальные (для самого выражения, не видные программисту) переменные. То есть a=b+c+d+e+f+g будет давать такие команды:

invisibleVariable1=f+g; invisibleVariable2=e+invisibleVariable1; invisibleVariable3=d+invisibleVariable2; invisibleVariable4=c+invisibleVariable3; a=b+invisibleVariable4;

что вроде как влечет лишние операции с памятью.

А в случае с a=b;a+=c;a+=d;a+=e;a+=f;a+=g;

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

Про кэш я ,может, загнул, но тем не менее.

Nerevarino
() автор топика
Ответ на: комментарий от Nerevarino

что вроде как влечет лишние операции с памятью

http://en.wikipedia.org/wiki/Processor_register
http://en.wikipedia.org/wiki/Register_allocation

работа идет с одной переменной, на которую больше шансов, что раскошелится кэш память процессора

Ты пока абсолютно не понимаешь как работает компилятор, а главное процессор. Почитай какую-нибудь хорошую книгу по архитектуре.

mix_mix ★★★★★
()
Ответ на: комментарий от Nerevarino

Короче делаю заключение: писать читабельный код, при релизе ставить оптимизацию.Если тормозно - фиговый алгоритм, алгоритм нормальный, но хочется побыстрее - курить ассемблер.

Nerevarino
() автор топика
Ответ на: комментарий от Nerevarino

Посчитай количество команд в нужной тебе функции, это даст тебе какое-то представление.
Компиляторы в настоящее время умеют творить чудеса, поэтому экономить на спичках не стоит. Я бы уделил внимание читаемости кода.

Deleted
()
Ответ на: комментарий от Nerevarino

Если тормозно - фиговый алгоритм, алгоритм нормальный, но хочется побыстрее - курить ассемблер.

Почти правильно. Лучше не курить ассемблер, а курить то, как код исполняется на процессоре, чтобы постараться адаптировать алгоритм под фичи процессора.

Deleted
()
Ответ на: комментарий от Nerevarino

Верное заключение. На практике курить ассемблер (для практических нужд) не понадобится, если ты только не пишешь аудио/видеокодеки, только для самообразования. Ну и после ассемблера изучи http://lwn.net/Articles/250967/ обязательно.

mix_mix ★★★★★
()

раз уж тут такая пьянка.. что по x86 железякам и асму читать, есть какая обязательная классика? (на амазоне посмотрел, книг есть туча, но в компетентности/адекватности авторов не уверен)

unt1tled ★★★★
()
Последнее исправление: unt1tled (всего исправлений: 1)
Ответ на: комментарий от Nerevarino

Обсалютно не верное утверждение, рассмотрим два примера:

1. s = a + b +c;

2. s  = a;
   s += b;
   s += c;

Первый вариант развернется в

movl    12(%ebp), %eax  ; Прочитали b в EAX
movl    8(%ebp), %edx   ; Прочитали a в EDX
addl    %eax, %edx      ; Прибавили к EDX EAX
movl    16(%ebp), %eax  ; Прочитали c в EAX
addl    %edx, %eax      ; Прибавили к EAX EDX
movl    %eax, -4(%ebp)  ; Записали результат в s

Второй вариант развернется в

movl    8(%ebp), %eax   ; Прочитали a в EAX
movl    %eax, -4(%ebp)  ; Записали EAX в s
movl    12(%ebp), %eax  ; Прочитали b в EAX
addl    %eax, -4(%ebp)  ; Прибавили EAX к s
movl    16(%ebp), %eax  ; Прочитали c в EAX
addl    %eax, -4(%ebp)  ; Прибавили EAX к s

С одной стороны к-во инструкций одинаковое (6 штук), но с другой стороны в первом случае мы имеем 4 операции чтения/записи в память а две инструкции оперируют только с внутренними регистрами процессора. Во втором случае у нас каждая инструкция требует обращения к памяти - а работа с памятью намного более ресурсоемкая задача чем с внутренними регистрами. Поэтому можно сказать что первый вариант будет работать на два условных такта быстрее второго.

Проблема в том что в первом случае компилятор сам выбирал временное хранилище для промежуточных результатов - и естественно наиболее оптимальное хранилище (не явная переменная) это внутренний регистр процессора. Во втором случае вы лишили компилятор такой возможности и явно указали порядок вычисления выражения.

Но это все не имеет большого значения - потомучто при полноценной оптимизации (-O2) ассемблерный код в обоих случаях будет выглядеть абсолютно одинаково:

 movl    b, %eax
 addl    a, %eax
 addl    c, %eax
 movl    %eax, s

zaz ★★★★
()
Ответ на: комментарий от zaz

Это получается, что последний вариант еще и экономит электроэнергию.

Nerevarino
() автор топика
Ответ на: комментарий от Nerevarino

Даже немного не так, в первом варианте у нас будет 3 операции чтения из памяти и 1 операция записи в память.

А во втором варианте у нас получится 5 операций чтения из памяти и 3 операции записи. А все потому что инструкция

addl %eax, -4(%ebp)
Вначале производит чтение из памяти, затем прибавляет к ней EAX а потом записывает полученный результат назад в память. Конечно у процессоров есть всевозможные кеши и тд. но все равно по сравнению с
addl    %eax, %edx
она будет выполнятся целую вечность ...

zaz ★★★★
()

видимо тебе совсем заняться нечем

umren ★★★★★
()

Есть ли в этом смыл?

ты для начала свои посты на ЛОРе оптимизируй, что-бы их читать можно было без рвотного эффекта.

emulek
()

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

invy ★★★★★
()

a=(b+c)/(b-c)

алсо за это выражение в целых числах нужно гнать из профессии.

1. b намного больше(меньше) c. В этом случае получаем что-то вроде 101/99 или 99/101. Т.е. результат 1 или 0, причём прямо зависит от фазы луны.

2. b примерно равно c. Тут мы имеем 146% переполнение, ну или деление на ноль (если b точно равно c).

emulek
()

Ну кто в тему помогать, а кто блевать заходит.

я помочь хотел, а тут такое…

И да, по теме: не нужно оптимизировать вычисления, поверь, компилятор это сделает лучше. Это же сишка, тут у компилятора свобода полная, он может твоё выражение крутить как угодно, даже так, как ты и подумать не мог. В стандарте _специально_ понаставили UB, дабы компилятор всегда мог выбрать оптимальный путь.

Лучше Д.Кнута почитай, он там про алгоритмы много букв писал.

emulek
()
Ответ на: комментарий от emulek

И чем я вызвал такой рвотный рефлекс, тем что посмел не посмотреть на выражение-пример со всех позиций, а не только с позиции скорости, при том, что только касательно нее спрашивал? Да, а еще я догадываюсь, что одни и те же уравнения, записав по-разному, могут дать разные погрешности.

алсо за это выражение в целых числах нужно гнать из профессии.

Предлагаешь мне заплакать, спросить себя «О нет! Как я мог этим заниматься!Я же так туп для этого!Пойду срочно напьюсь и в дворники!

ты для начала свои посты на ЛОРе оптимизируй, что-бы их читать можно было без рвотного эффекта.

Мало того, что непонятно к чему сказанный оффтоп, так еще согласись, в сравнении с остальными, твой пост меньше похож на помощь.Но за два других спасибо.Буду иметь в виду.

P.S.Вообще я не люблю подобные оффтопные дискуссии,last time.

Nerevarino
() автор топика
Ответ на: комментарий от Nerevarino

И чем я вызвал такой рвотный рефлекс

читать первый пост невозможно. Странно тебе рассчитывать на помощь, если ты даже вопрос понятно и красиво оформить не осилил? И да, большинство просто мимо пройдут, как раз те, кто может помочь. Останутся только тролли с ушатами говна и анонимусы вообще с чем-то непотребным.

только касательно нее спрашивал?

про скорость сказано достаточно. Разве что забыли добавить, что деление и скорость — несовместимы. Делай что хочешь, но деления быть не должно.

Предлагаешь мне заплакать, спросить себя «О нет! Как я мог этим заниматься!Я же так туп для этого!Пойду срочно напьюсь и в дворники!

нет. Я предлагаю переделать твой алгоритм так, что-бы там не было-бы такой формулы. А уж потом думать за оптимизацию.

Мало того, что непонятно к чему сказанный оффтоп

считай это просьбой. Говнокод разбирать тяжело, чужой — тяжело в квадрате, а уж если он ещё и не оформлен как код, а как говно…

emulek
()

Нет, серьезно, а как еще надо было написать....

1)a=b;a+=c;a+=d;a+=e;a+=f;a+=g; 2)a=b;a*=c;a*=d;a*=e;a*=f;a*=g; 3)int BpC=b;int BmC=b;BpC+=c;BmC-=c;BpC/=BmC;a=BpC;

vs

// 1)
a=b;
a+=c;
a+=d;
a+=e;
a+=f;
a+=g;

// 2)
a=b;
a*=c;
a*=d;
a*=e;
a*=f;
a*=g;

// 3)
int BpC=b;
int BmC=b;

BpC += c;
BmC -= c;

BpC /= BmC;
a = BpC;

З.Ы. Точки с запятой на форуме тоже нужно строго расставлять?

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

По делу: говоришь как можно меньше делений, то есть (a/b) + (c/d) лучше записать как (ad + bc)/bd ?

не нужно. Компилятору виднее, как на _этой_ платформе выгоднее.

Речь шла о скорости. Вот для скорости лучше тот алгоритм, где делений меньше. Желательно, что-бы их вообще не было. (только не нужно тривиальных оптимизаций, например x/2 это x/2. Не нужно писать x*½, и уж тем более сдвигать x на 1 бит вправо).

Ну и всё это касается исключительно внутренности циклов. Если у тебя одна формула, то её нужно максимально читаемо писать.

ЗЫЖ задолбал ты уже посты удалять

emulek
()

1. Make it work. 2. Make it right. И в последнюю очередь 3. Make it fast.

anonymous
()

Это же та самая «преждевременная оптимизация», которая корень всех проблем в программировании, как считали Кнут, Хоар и Дейкстра.

Deleted
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.