Что означает эта конструкция __builtin_expect(!!(x), 1)

В частности, я спрашиваю о двойном '!' в параметрах файла __built_in.

Это двойное отрицание, согласно языку 'C'?

Спасибо-


person user3342339    schedule 28.07.2014    source источник
comment
Его можно использовать для преобразования любого значения в логическое значение 0 или 1. Пример. !!(42) == 1   -  person Colonel Thirty Two    schedule 28.07.2014
comment
Связанный: заголовок stackoverflow.com/questions/7346929/   -  person Mihai Todor    schedule 28.07.2014
comment
if(x) и if (__builtin_expect(!!(x), 1)) должны воспроизводить один и тот же порядок в сгенерированном коде. Тот, кто написал это, неправильно выполняет преждевременную оптимизацию.   -  person Havenard    schedule 28.07.2014
comment
@Havenard на самом деле, это оптимизация для прогнозирования ветвлений. Он говорит, что x более чем вероятно не равен нулю, но это может быть и не так. Если это часть часто проверяемого условного оператора, дополнительная производительность от успешного предсказания переходов может быть существенной.   -  person Drew McGowen    schedule 28.07.2014
comment
Да, но если он может быть ненулевым, то if(x) будет достаточно. Глядя с точки зрения сборки, единственное, что это делает, - это преобразование x либо в 0, либо в 1 перед test x,x вместо того, чтобы делать test x,x сразу. Может даже заставить компилятор использовать вместо этого cmp x,1, что еще хуже.   -  person Havenard    schedule 28.07.2014
comment
if(x) — это общий тест на то, равно ли x нулю. Компилятор не делает предположений о том, какое значение более вероятно, поэтому он должен полагаться на динамическое прогнозирование ветвлений и может неправильно угадать первые несколько итераций. Однако использование __builtin_expect вставит подсказку относительно того, каким должно быть начальное предположение для предсказания ветвления.   -  person Drew McGowen    schedule 28.07.2014
comment
Да, он не делает никаких предположений и просто генерирует код в том порядке, в котором вы его написали, сначала с блоком для ненулевого значения, как в этом случае __builtin_expect.   -  person Havenard    schedule 28.07.2014
comment
Я не говорю, что __builtin_expect бесполезен, я просто говорю, что в данном конкретном случае он не выполняет свою задачу.   -  person Havenard    schedule 28.07.2014


Ответы (1)


!! — это просто два оператора ! рядом друг с другом. Это простой способ преобразовать любое ненулевое значение в 1 и оставить 0 как есть.

person Drew McGowen    schedule 28.07.2014
comment
Таким образом, в примере (логический контекст) он излишен. - person Deduplicator; 28.07.2014
comment
Это необходимо для заданного __builtin_expect, потому что оно принимает два значения, которые должны быть равными. Если бы было просто if(x), то да, было бы лишним. - person Drew McGowen; 28.07.2014
comment
Скажите это ребятам из ядра Linux: > stackoverflow.com/questions/109710/ Хотя похоже, что они добавили это и позже... - person Deduplicator; 29.07.2014