Прогнозирование ветвлений и многопоточность

Предположим, что простой if выглядит следующим образом:

if (something)
   // do_something
else
   // do_else

Предположим, что этот оператор if-else выполняется параллельно в разных потоках, и каждый поток дает разный результат, но постоянный на протяжении всей своей жизни. Например, в потоке 1 условие всегда оценивается как ложное, в потоке 2 — как истинное; в потоке 3 всегда верно и так далее.

Учитывает ли прогнозирование ветвлений контекст выполнения каждого потока для составления статистики? Потому что, если это не так (я так не думаю, но это трудно проверить тестированием), процессор увидит, что условие следует случайному шаблону, и вообще не будет его предсказывать.


person Peregring-lk    schedule 18.09.2016    source источник
comment
Определить нить. Процессор явно не знает о потоках ОС. Но большинство процессоров в наши дни знают об аппаратных потоках.   -  person Kris Vandermotten    schedule 18.09.2016
comment
Предсказание переходов — это деталь реализации процессора, работающая с наносекундным разрешением. Выполнение потока работает с миллисекундным разрешением. Разница в 6 порядков делает проблему неактуальной.   -  person Hans Passant    schedule 18.09.2016
comment
Исследование и проектирование прогнозирования ветвлений на основе многоядерных гетерогенных - Аннотация: Стремление к той проблеме, что было трудно улучшить производительность процессора только за счет повышения частоты одного ядра, т.к. а также остановку суперскалярного конвейера при обработке инструкции ветвления, в этой статье была представлена ​​архитектура гетерогенного многоядерного процессора, в котором использовалась структура B-Cache и контроллер процессора C-Core. Новая архитектура позволила избежать сброса конвейера из-за промаха ветвления и повысить общую эффективность многоядерного процессора.   -  person samis    schedule 30.05.2018
comment
ref: ieeexplore.ieee.org/document/5564921   -  person samis    schedule 30.05.2018


Ответы (1)


Если мы игнорируем SMT (например, гиперпоточность), большинство архитектур имеют предсказатель ветвления для каждого аппаратного потока. Он тесно связан с блоком выборки отдельного ядра. Некоторые (AMD?) хранят некоторую информацию о предсказании переходов в I-кэше L1/L2, но в основном нацелены на следующую выборку.

Поэтому, если вы не запускаете свой код на SMT, вы находитесь в раю и каждый раз будете получать 100% предсказание за счет нескольких инструкций.

Если вы запустите свой код на SMT, вы часто обнаружите, что ваша жизнь превратилась в ад, с более чем 50% неправильных прогнозов.

Теперь вы можете легко решить свою проблему, вам просто нужно использовать больше кода, проверить свое условие раньше и вызвать ветку вашего кода с do_something или do_else в ней.

Если у вас есть цикл, который вызывает вашу функцию, где у вас есть ветка, вы можете сделать что-то вроде:

если (что-то) do_something_loop(); иначе do_else_loop();

void do_something_loop() { for (auto x: myVec) do_something; }

Недостатком этого является то, что вам нужно поддерживать 2 почти равные ветви кода.

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

Код концепции С++.

template<bool b_something>
void brancher() {
  // do things
  if (b_something)
    // do_something
  else
    // do_else
  }
  // do more things
}

void branch_user() {
  if (something) {
    for (auto x : myVec)
      brancher<true>();
  } else {
    for (auto x : myVec)
      brancher<false>();
  }
}

Теперь вам нужно только поддерживать 2 ветки внешней функции, что, надеюсь, требует меньше работы.

person Surt    schedule 08.11.2016