Ветка на?: Оператор? - PullRequest
       29

Ветка на?: Оператор?

8 голосов
/ 20 августа 2011

Для типичного современного компилятора на современном оборудовании, оператор ? : приведет к ответвлению, которое влияет на конвейер команд?

Другими словами, что быстрее, вызывая оба случая, чтобы избежать возможного перехода:

bool testVar = someValue(); // Used later.
purge(white);
purge(black);

или выбор того, который действительно должен быть очищен, и только с оператором ?::

bool testVar = someValue();
purge(testVar ? white : black);

Я понимаю, что вы не представляете, как долго будет очищаться ()принять, но я просто задаю здесь общий вопрос о том, захочу ли я когда-нибудь дважды вызвать purge (), чтобы избежать возможной ветки в коде.

Я понимаю, что это очень крошечная оптимизация и может сделатьразницы нет, но все равно хотелось бы знать.Я ожидаю, что ?: не приведет к ветвлению, но хочу убедиться, что мое понимание верно.

Ответы [ 5 ]

5 голосов
/ 22 августа 2011

Инструкция CMOV (Conditional MOVe) была частью набора команд x86 начиная с Pentium Pro. Он редко генерируется автоматически GCC из-за часто используемых опций компилятора и ограничений, накладываемых языком Си. Последовательность SETCC / CMOV может быть вставлена ​​встроенной сборкой в ​​вашу C-программу. Это следует делать только в тех случаях, когда условная переменная является случайно колеблющимся значением во внутреннем цикле (миллионы выполнений) программы. В не колеблющихся случаях и в случаях простых моделей колебаний современные процессоры могут предсказывать ответвления с очень высокой степенью точности. В 2007 году Линус Торвальдс предложил здесь , чтобы избежать использования CMOV в большинстве ситуаций.

Intel описывает условное перемещение в Руководство разработчика программного обеспечения для архитектуры Intel, том 2, Справочное руководство по набору инструкций :

The CMOVcc instructions check the state of one or more of the status flags in the EFLAGS
register (CF, OF, PF, SF, and ZF) and perform a move operation if the flags are in a specified
state (or condition). A condition code (cc) is associated with each instruction to indicate the
condition being tested for. If the condition is not satisfied, a move is not performed and execution
continues with the instruction following the CMOVcc instruction.

These instructions can move a 16- or 32-bit value from memory to a general-purpose register or
from one general-purpose register to another. Conditional moves of 8-bit register operands are
not supported.

The conditions for each CMOVcc mnemonic is given in the description column of the above
table. The terms “less” and “greater” are used for comparisons of signed integers and the terms
“above” and “below” are used for unsigned integers.

Because a particular state of the status flags can sometimes be interpreted in two ways, two
mnemonics are defined for some opcodes. For example, the CMOVA (conditional move if
above) instruction and the CMOVNBE (conditional move if not below or equal) instruction are
alternate mnemonics for the opcode 0F 47H.
5 голосов
/ 20 августа 2011

Зависит от платформы.В частности, это зависит от размера таблицы прогнозирования переходов ЦП и от того, допускает ли ЦП условные операции (например, для ARM).

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

Реальный ответ (как и с любыми другими вопросами производительности): измерять и сравнивать.Иногда остальная часть кода бросает кривая, и обычно невозможно предсказать последствия некоторых изменений.

2 голосов
/ 20 августа 2011

Я не могу представить, что первый метод был бы быстрее.

С помощью первого метода вы можете избежать ветвления, но вы замените его вызовом функции, который обычно включает ветвь и многое другое (если он не был встроен).Даже если встроенный, если бы функция внутри функции purge () не была тривиальной, она почти наверняка была бы медленнее.

1 голос
/ 20 августа 2011

Вызов функции, по крайней мере, такой же дорогой, как выполнение логического теста + переход (и да, для троичного оператора ? : потребуется переход).

0 голосов
/ 20 августа 2011

в первом случае продувка вызывается дважды. Во втором случае продувка вызывается один раз

Трудно ответить на вопрос о ветвлении, потому что оно так зависит от компиляторов и набора команд. Например, в ARM (который имеет условное выполнение инструкций) он может не переходить. На x86 это почти наверняка будет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...