Как понять макрос, «вероятно» влияющий на предсказание ветвления? - PullRequest
0 голосов
/ 04 апреля 2020

Я заметил, что если мы знаем, что есть хороший шанс того, что поток управления будет истинным или ложным, мы можем сообщить об этом компилятору, например, в ядре Linux, есть много likely unlikely, фактически подразумеваемых __builtin_expect предоставлено gcc, поэтому я хочу выяснить, как оно работает, затем проверил сборку там:

  20:branch_prediction_victim.cpp ****             if (array_aka[j] >= 128)
 184                            .loc 3 20 0 is_stmt 1
 185 00f1 488B85D0              movq    -131120(%rbp), %rax
 185      FFFDFF
 186 00f8 8B8485F0              movl    -131088(%rbp,%rax,4), %eax
 186      FFFDFF
 187 00ff 83F87F                cmpl    $127, %eax
 188 0102 7E17                  jle     .L13

Затем для __builtin_expect

  20:branch_prediction_victim.cpp ****             if (__builtin_expect((array_aka[j] >= 128), 1))
 184                            .loc 3 20 0 is_stmt 1
 185 00f1 488B85D0              movq    -131120(%rbp), %rax
 185      FFFDFF
 186 00f8 8B8485F0              movl    -131088(%rbp,%rax,4), %eax
 186      FFFDFF
 187 00ff 83F87F                cmpl    $127, %eax
 188 0102 0F9FC0                setg    %al
 189 0105 0FB6C0                movzbl  %al, %eax
 190 0108 4885C0                testq   %rax, %rax
 191 010b 7417                  je      .L13
  • 188 - setg установить, если больше, здесь установить, если больше чем?
  • 189 - movzbl переместить ноль, продлить байт в длину, я знаю, что это одно движение %al в %eax
  • 190 - testq поразрядно ИЛИ затем установить флаги ZF CF, это правильно?

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

1 Ответ

2 голосов
/ 04 апреля 2020

setcc читает ФЛАГИ, в этом случае устанавливается cmp прямо перед. Прочитайте руководство .

Похоже, что вы забыли включить оптимизацию, поэтому __builtin_expect просто создает логическое значение 0 / 1 в регистре и создает ветвление на нем. ненулевой, вместо ветвления в исходном условии FLAGS. Не смотрите на неоптимизированный код, он всегда будет отстой.

Подсказки: логическое вычисление мертвых мозгов как часть likely и загрузка j из стека использование RBP в качестве указателя кадра с movq -131120(%rbp), %rax


likely, как правило, не улучшает ветвь времени выполнения прогнозирование , оно улучшает структуру кода для минимизации количество отобранных веток, когда вещи go так, как сказал бы исходный код (т.е. быстрый случай). Так что это улучшает локальность I-кэша для общего случая. например, компилятор все раскроет, так что общий случай - это неиспользованная условная ветвь, просто проваливающаяся. Это облегчает работу внешнего интерфейса в суперскалярных конвейерных процессорах, которые извлекают / декодируют несколько команд одновременно. Продолжить выборку по прямой линии проще всего.

likely может заставить компилятор использовать ветку вместо cmov для случаев, которые, как вы знаете, предсказуемы, даже если эвристика компилятора (без руководствуясь оптимизацией) ошибся. Похожие: g cc флаг оптимизации -O3 делает код медленнее, чем -O2

...