![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
minyor |
|
||||
Новичок Профиль Группа: Участник Сообщений: 5 Регистрация: 22.10.2009 Репутация: нет Всего: нет |
Давно меня мучает вопрос. может и глупый немного
![]() К примеру: (псевдокод)
или так:
Может быть пример я выбрал и неочень удачный, может при чтении из потока это и не актуально. Но бывают разные ситуации, к примеру при написании движка к какой-нибудь игрухе, где нужно все оптимизировать, где динамически нужно выбрать как считать физику и т.п. Без использования ассемблерных вставок. Хотел услышать ваше мнение, быстрее-ли будет такой выверт? .. может быть вариант где функтор вообще без параметров, на занесение которых в стек надо время. Или полюбому "if" или "switch" быстрее вызова ф-ии, даже если она без параметров и ничего не возвращает. |
||||
|
|||||
нуп |
|
|||
![]() Ботокодер ![]() ![]() Профиль Группа: Участник Сообщений: 987 Регистрация: 22.6.2009 Где: Кременчуг Репутация: нет Всего: 33 |
inline же для switch не прокатит
|
|||
|
||||
minyor |
|
|||
Новичок Профиль Группа: Участник Сообщений: 5 Регистрация: 22.10.2009 Репутация: нет Всего: нет |
хм, а че?, switch же просто должен будет вставиться вместо вызова ф-ии
Это сообщение отредактировал(а) minyor - 6.4.2010, 02:27 |
|||
|
||||
W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 20 Всего: 121 |
У тебя же в обоих случаях идёт вызов функции. Просто в одном случае она будет вызвана косвенно (+1 обращение к памяти), а в другом напрямую.
В данном случае вряд ли заинлайнится. Хотя, может я недооцениваю компилятор. ![]() Но switch он тоже разный бывает. Например, если твои константы FILE, ZIP идут подряд (0, 1, 2...), то переход в switch'e будет осуществляться через таблицу смещения без единого условного оператора, что в общем равносильно косвеному вызову через указатель на метод. -------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
W4FhLF, покажите asm- код switch'а, который переходит по таблице смещения. Не свой, конечно, а сгенерённый компилятором. А если константы идут подряд, но так: 800, 801, 802 ... ?
minyor, Вы, конечно же, знаете, что преждевременная оптимизация - корень зла. Т.е. ваша программа уже выполняет все функции идеально правильно, а не хватает только производительности? IMHO как теоретический вопрос - да, интересно, но нужно доверять компиляторам. Нередко они оптимизируют лучше, чем мы с вами, а читаемость кода - очень немаловажная вещь Это сообщение отредактировал(а) borisbn - 6.4.2010, 06:03 -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
minyor |
|
|||
Новичок Профиль Группа: Участник Сообщений: 5 Регистрация: 22.10.2009 Репутация: нет Всего: нет |
W4FhLF - да правда, цена это +1 обращение к памяти. Но ведь еще вроде при условной операции конвеер прерывается. Вот интересно это преревание дороже наверное чем вызов адреса ф-ии без параметров. Но если там таблица смещения тогда ладно.
borisbn, да это у меня чисто теоритический интерес, хотя частенько, когда что-то писал бывало так и хотелось что-то подобное оформить, но как-раз удобочитабельность меня и останавливала ![]() Но если действительно быстрее то возможно в некоторых особо редких случаях удобочитабельностью можна будет и пожертвавать. Если константы начинаются с 800, то компилятор мог-бы сделать подобное: int tblInd = val - 800; а потом уже обратится к табл. смещения. Но врядли он такое делает, если и делает то не каждый. Это сообщение отредактировал(а) minyor - 6.4.2010, 06:56 |
|||
|
||||
borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
один конвеер - да. но у современных процессоров их до 128-ми (могу ошибаться с цифрой, но точно больше 16-ти). В одном конвеере выполняется код для true, в другом - для false, а когда наступает час X, просто переходится на нужный конвеер. -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
W4FhLF |
|
|||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 20 Всего: 121 |
При вызове процедуры (операнд) конвеер вообще сбрасывается потому что начинает выполняться код, который расположен на другом участке памяти. А при условном переходе может и "угадать". Но как уже сказали, влияние данного вызова или mispredicting может быть несущественно. У вас компилятор работать перестал? Скомпилируйте и посмотрите. Я когда исследовал этот вопрос всё проверял, смотрел. -------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
|||
|
||||
GoldFinch |
|
|||
![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2141 Регистрация: 30.11.2008 Репутация: 15 Всего: 26 |
borisbn,
для 800, 801, 802 компилятор вычтет 800 и сгенерит таблицу из 3х элементов, для 800, 802, 803 компилятор вычтет 800 и сгенерит таблицу из 4х элементов, один из которых будет переходом на default возьмите дизассемблер и посмотрите %) алсо темы про switch не раз поднимались на форуме |
|||
|
||||
GoldFinch |
|
|||
![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2141 Регистрация: 30.11.2008 Репутация: 15 Всего: 26 |
а для сильно разреженных констант, например 1, 8, 23, ... 211 компилятор сгенерит две таблицы:
первую для трансляции номера метки в порядковый номер перехода, вторую для самих адресов перехода |
|||
|
||||
minyor |
|
|||
Новичок Профиль Группа: Участник Сообщений: 5 Регистрация: 22.10.2009 Репутация: нет Всего: нет |
W4FhLF, GoldFinch, Ну тогда можно спокойно юзать switch и не заморачиваться
![]() Спасибо что прояснили, а то я про таблицу смещения неподумал. Switch это есть гуд! Попробую сам поизучать asm-код, генерируемый gcc и vc ради интереса borisbn - буду больше доверять компиляторам, спасибо ![]() |
|||
|
||||
borisbn |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
W4FhLF, GoldFinch, про какой компилятор вы говорите? Я проверил на vc2008 (другого нет под рукой)
даёт результат
опции компилятора: /O2 /Ot и т.д. -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
||||
|
|||||
W4FhLF |
|
||||||||||||||||
![]() found myself ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2831 Регистрация: 2.12.2006 Репутация: 20 Всего: 121 |
borisbn, ну во-первых я не знаю с чего GoldFinch взял, что компилятор вообще всегда будет преобразовывать switch/case в таблицу. У меня такого не наблюдалось.
Компилятор у меня VC++ 2008. C++:
asm:
Смещение считается по таблице. А вот пример с if/else:
asm:
Никакой таблицы ессно нет. Всё на основе кучи cmp/jx. На такие случаи будет генерится таблица:
Если в последнем примере 60 на 600 заменить для него будет генериться отдельное сравнение. А на такой будут генерится сравнения:
В общем компилер умный. И единого правила у него нет. Скорее всего какое-то комплексное решение принимается. Добавлено @ 13:16 Мы это с zkv проверяли. ![]() Это сообщение отредактировал(а) W4FhLF - 6.4.2010, 13:18 -------------------- "Бог умер" © Ницше "Ницше умер" © Бог |
||||||||||||||||
|
|||||||||||||||||
GoldFinch |
|
|||
![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2141 Регистрация: 30.11.2008 Репутация: 15 Всего: 26 |
я это взял из практики реверсирования программ, в том числе написанных на С++
разумеется компилятор выбирает из всех вариантов тот который кажется ему более оптимальным %) |
|||
|
||||
GoldFinch |
|
||||||
![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2141 Регистрация: 30.11.2008 Репутация: 15 Всего: 26 |
однако, это воспроизводится на раз.
для разреженных значений меток:
(в листинге который выводит компилятор написан явный бред, по этому привожу листинг IDA
jumpIdxTable - таблица трансляции значений меток в индекс таблицы переходов jumpAddrTable - таблица адресов переходов опции компилятора
Это сообщение отредактировал(а) GoldFinch - 6.4.2010, 13:51 |
||||||
|
|||||||
borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
W4FhLF, странно, компиляторы у нас одинаковые, примеры похожие, однако у меня
а у вас м.б. это из-за моих asm-вставок ? или из-за опций оптимизации ? -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |