2017-01-15 9 views
1

Я просто что-то читал об атрибутах в C++ на cppreference. Они упоминали о возможном (истинном) атрибуте, и теперь мне интересно, для чего это полезно. К сожалению, я не смог найти дополнительную информацию в Интернете.Какой смысл атрибута (истинного)

Это какое-то предсказание ветвления, которое процессор использует во время выполнения?

+2

Это как раз то, что есть - видя предсказания аппаратной ветви – levengli

+0

, это просто пример того, как может выглядеть атрибут, применимый только к условным ветвям, он действительно не существует в этой форме (насколько мне известно) – Cubbi

+0

Я не уверен, правильно ли я понял вас, но я просто скомпилировал код с этим синтаксисом: '[[вероятно (правда)]] if (...) ... else ...' Я не сделал проверьте сгенерированный код, но он скомпилирован как минимум (с использованием msc и C++ 14) – Timo

ответ

5

Да, точно. Он используется для предоставления компилятору дополнительной информации о заявлении if, чтобы он мог генерировать оптимальный код в соответствии с целевой микроархитектурой.

Хотя каждая микроархитектура имеет свои способы информирования о вероятности ветвления, мы можем взять простой пример из руководства Intel Optimization

Assembly/Составитель кодирования Правило 3. (M воздействие, H общность) Устройте код соответствовать алгоритм статического предсказания ветвлений: сделать fall- через код, следующий за условной ветвью, будет вероятной целью для ветки с forw ard, и сделать код падения после условной ветви - это маловероятная цель для ветви с обратной целью.

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

Рассмотрим этот код для GCC:

#define probably_true(x) __builtin_expect(!!(x), 1) 
#define probably_false(x) __builtin_expect(!!(x), 0) 

int foo(int a, int b, int c) 
{ 
    if (probably_true(a==2)) 
     return a + b*c; 
    else 
     return a*b + 2*c; 
} 

Где я использовал встроенный в __builtin_expect для имитации [[problably(true)]].

Это компилируются в

foo(int, int, int): 
     cmp  edi, 2   ;Compare a and 2 
     jne  .L2    ;If not equals jumps to .L2 

     ;This is the likely path (fall-through of a forward branch) 

     ;return a + b*c; 

.L2: 
     ;This is the unlikely path (target of a forward branch) 

     ;return a*b + 2*c; 

     ret 

Где я избавлен вам некоторые сборки кода.
Если заменить probably_true с probably_false код становится:

foo(int, int, int): 
     cmp  edi, 2   ;Compare a and 2 
     je  .L5    ;If equals jumps to .L5 

     ;This is the likely path (fall-through of a forward branch) 

     ;return a*b + 2*c; 

.L5: 
     ;This is the unlikely path (target of a forward branch) 

     ;return a + b*c; 

     ret 

Вы можете играть с with this example at codebolt.org.

+0

Хороший ответ, спасибо!Таким образом, предсказание ветвления всегда использует побуждение, которое следует за выполняемой в настоящее время инструкцией как путь прогнозирования, и путь перехода в качестве пути отказа? – Timo

+1

@Timo. В зависимости от архитектуры (или, лучше, микроархитектуры), в x86 для прямых переходов (которые статически не прогнозируются) ваше утверждение верно, но только в первый раз, когда ветка видна. В первый раз предсказатель ветвления пытается определить шаблон принятого невзятого поведения ветви. См. [Относительная статья в Википедии] (https://en.wikipedia.org/wiki/Branch_predictor) для начальной точки. –

+0

Несмотря на советы в руководстве по архитектуре, на современном x86, я понимаю, что существует не более статических правил прогнозирования! _. То есть, как разрабатываются современные отраслевые предсказатели, всегда будет только динамическое предсказание: если ветвь не была замечена, предсказание основывается только на том, какой нежелательный файл остается в таблицах прогнозирования от других переходов, которые хэшируются там, или, возможно, прогноз по умолчанию (возможно, провал-всегда), если ничего не существует вообще. – BeeOnRope