| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Что дороже - вызов ф-ии или условный оператор |
| Автор: minyor 6.4.2010, 01:38 | ||||
| Давно меня мучает вопрос. может и глупый немного К примеру: (псевдокод)
или так:
Может быть пример я выбрал и неочень удачный, может при чтении из потока это и не актуально. Но бывают разные ситуации, к примеру при написании движка к какой-нибудь игрухе, где нужно все оптимизировать, где динамически нужно выбрать как считать физику и т.п. Без использования ассемблерных вставок. Хотел услышать ваше мнение, быстрее-ли будет такой выверт? .. может быть вариант где функтор вообще без параметров, на занесение которых в стек надо время. Или полюбому "if" или "switch" быстрее вызова ф-ии, даже если она без параметров и ничего не возвращает. |
| Автор: нуп 6.4.2010, 02:14 |
| inline же для switch не прокатит |
| Автор: minyor 6.4.2010, 02:21 |
| хм, а че?, switch же просто должен будет вставиться вместо вызова ф-ии |
| Автор: W4FhLF 6.4.2010, 04:13 |
| У тебя же в обоих случаях идёт вызов функции. Просто в одном случае она будет вызвана косвенно (+1 обращение к памяти), а в другом напрямую. В данном случае вряд ли заинлайнится. Хотя, может я недооцениваю компилятор. Но switch он тоже разный бывает. Например, если твои константы FILE, ZIP идут подряд (0, 1, 2...), то переход в switch'e будет осуществляться через таблицу смещения без единого условного оператора, что в общем равносильно косвеному вызову через указатель на метод. |
| Автор: borisbn 6.4.2010, 06:01 |
| W4FhLF, покажите asm- код switch'а, который переходит по таблице смещения. Не свой, конечно, а сгенерённый компилятором. А если константы идут подряд, но так: 800, 801, 802 ... ? minyor, Вы, конечно же, знаете, что преждевременная оптимизация - корень зла. Т.е. ваша программа уже выполняет все функции идеально правильно, а не хватает только производительности? IMHO как теоретический вопрос - да, интересно, но нужно доверять компиляторам. Нередко они оптимизируют лучше, чем мы с вами, а читаемость кода - очень немаловажная вещь |
| Автор: minyor 6.4.2010, 06:26 |
| W4FhLF - да правда, цена это +1 обращение к памяти. Но ведь еще вроде при условной операции конвеер прерывается. Вот интересно это преревание дороже наверное чем вызов адреса ф-ии без параметров. Но если там таблица смещения тогда ладно. borisbn, да это у меня чисто теоритический интерес, хотя частенько, когда что-то писал бывало так и хотелось что-то подобное оформить, но как-раз удобочитабельность меня и останавливала Но если действительно быстрее то возможно в некоторых особо редких случаях удобочитабельностью можна будет и пожертвавать. Если константы начинаются с 800, то компилятор мог-бы сделать подобное: int tblInd = val - 800; а потом уже обратится к табл. смещения. Но врядли он такое делает, если и делает то не каждый. |
| Автор: borisbn 6.4.2010, 07:00 |
один конвеер - да. но у современных процессоров их до 128-ми (могу ошибаться с цифрой, но точно больше 16-ти). В одном конвеере выполняется код для true, в другом - для false, а когда наступает час X, просто переходится на нужный конвеер. |
| Автор: GoldFinch 6.4.2010, 08:15 |
| borisbn, для 800, 801, 802 компилятор вычтет 800 и сгенерит таблицу из 3х элементов, для 800, 802, 803 компилятор вычтет 800 и сгенерит таблицу из 4х элементов, один из которых будет переходом на default возьмите дизассемблер и посмотрите %) алсо темы про switch не раз поднимались на форуме |
| Автор: GoldFinch 6.4.2010, 08:31 |
| а для сильно разреженных констант, например 1, 8, 23, ... 211 компилятор сгенерит две таблицы: первую для трансляции номера метки в порядковый номер перехода, вторую для самих адресов перехода |
| Автор: minyor 6.4.2010, 09:13 |
| W4FhLF, GoldFinch, Ну тогда можно спокойно юзать switch и не заморачиваться Спасибо что прояснили, а то я про таблицу смещения неподумал. Switch это есть гуд! Попробую сам поизучать asm-код, генерируемый gcc и vc ради интереса borisbn - буду больше доверять компиляторам, спасибо |
| Автор: borisbn 6.4.2010, 12:49 | ||||
W4FhLF, GoldFinch, про какой компилятор вы говорите? Я проверил на vc2008 (другого нет под рукой)
даёт результат
опции компилятора: /O2 /Ot и т.д. |
| Автор: W4FhLF 6.4.2010, 13:15 | ||||||||||||||||
| borisbn, ну во-первых я не знаю с чего GoldFinch взял, что компилятор вообще всегда будет преобразовывать switch/case в таблицу. У меня такого не наблюдалось. Компилятор у меня VC++ 2008. C++:
asm:
Смещение считается по таблице. А вот пример с if/else:
asm:
Никакой таблицы ессно нет. Всё на основе кучи cmp/jx. На такие случаи будет генерится таблица:
Если в последнем примере 60 на 600 заменить для него будет генериться отдельное сравнение. А на такой будут генерится сравнения:
В общем компилер умный. И единого правила у него нет. Скорее всего какое-то комплексное решение принимается. Добавлено @ 13:16 Мы это с http://forum.vingrad.ru/users/zkv проверяли. |
| Автор: GoldFinch 6.4.2010, 13:22 |
| я это взял из практики реверсирования программ, в том числе написанных на С++ разумеется компилятор выбирает из всех вариантов тот который кажется ему более оптимальным %) |
| Автор: GoldFinch 6.4.2010, 13:37 | ||||||
| однако, это воспроизводится на раз. для разреженных значений меток:
(в листинге который выводит компилятор написан явный бред, по этому привожу листинг IDA
jumpIdxTable - таблица трансляции значений меток в индекс таблицы переходов jumpAddrTable - таблица адресов переходов опции компилятора
|
| Автор: borisbn 6.4.2010, 13:51 | ||
W4FhLF, странно, компиляторы у нас одинаковые, примеры похожие, однако у меня
а у вас м.б. это из-за моих asm-вставок ? или из-за опций оптимизации ? |