Вносит ли выполнение второго потока на гиперпоточном ЦП дополнительные накладные расходы по всему конвейеру?

На работе шла дискуссия, связанная с машинами Xeon с гиперпотоками. Мое (поверхностное) понимание того, как работает Hyperthreading, состоит в том, что ЦП физически мультиплексирует инструкции, поступающие из двух «потоков». То есть исполнительные блоки являются общими, но есть два разных архитектурных набора (наборы регистров, очереди инструкций, возможно, даже предикторы ветвлений и т. Д.) - по одному для каждого потока. Исполнительные блоки и их буферы / очереди всегда готовы к приему новых инструкций / данных, и что с этой точки зрения нет никакого преимущества в отключении одного из потоков вместо сохранения обоих.

Мой коллега имел в виду, что, отключив гиперпоточность, мы можем добиться ускорения, так как ЦП, выполняющий единственный поток, больше не должен «смотреть», чтобы увидеть, есть ли у другого потока работу. Я понимаю, что вся эта схема уже жестко запрограммирована для мультиплексирования входящих данных / инструкций из обоих потоков, и что отключение гиперпоточности просто отключит один из потоков, не позволяя ему получать какие-либо инструкции / данные, но на самом деле больше ничем не отличается. Это хорошая ментальная модель того, как работает гиперпоточность?

Я понимаю, что существует множество факторов, таких как рабочие наборы памяти, проблема общих кешей и т. Вопрос больше направлен на то, если отключение гиперпоточности каким-то образом ускоряет весь поток данных / инструкций по конвейеру или нет? Могут ли возникнуть проблемы с конкуренцией при попытке заполнить буферы, например, в головной части серверной части?

Объяснение моего коллеги также каким-то образом включало гипервизоры, но я не вижу связи между ними? Они кажутся ортогональными понятиями.

Спасибо!


person devoured elysium    schedule 10.09.2019    source источник
comment
Некоторые подробности в этом ответе, многие ресурсы являются общими. Глядя на то, есть ли у другого потока что-то делать, на самом деле не так уж важно, оба потока инструкций складываются в кучу и просматриваются.   -  person harold    schedule 10.09.2019
comment
HT использует несовершенное использование ресурсов ЦП, поэтому для запуска кода, идеально подходящего для вашей u-архитектуры, лучше отключить HT, поскольку теперь у вас может быть весь бэкэнд для кода. Однако не всегда возможно использовать все ресурсы ЦП, и в целом выполнение с обоими потоками замедлит каждую программу гораздо меньше, чем их планирование на выходе. ЦП извлекает инструкции в интерфейсе, и вы либо получаете больше инструкций, которые могут быть выполнены в бэкэнде (из-за зависимостей), либо с меньшим количеством (из-за остановок). В обоих случаях поможет HT. HV не связаны.   -  person Margaret Bloom    schedule 10.09.2019


Ответы (2)


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

Каждый поток имеет собственное архитектурное состояние, как описано в разделе 8.7.1 руководства Intel под названием «Состояние логических процессоров». Большинство архитектурных регистров дублируются для каждого потока. Это достигается путем репликации структуры RAT в конвейере. Память также является частью архитектурного состояния, но все процессоры Intel являются процессорами с общей памятью, что означает, что память распределяется между всеми ядрами системы.

Мне непонятно, во фразе «отключив гиперпоточность, мы могли бы добиться ускорения», какие метрики производительности и справочная система используются для этого сравнения. Если вы хотите сравнить время выполнения настенных часов двух задач в следующих двух конфигурациях:

  • Две задачи выполняются на одном физическом ядре с включенной гиперпоточностью и в предположении, что переключение контекста отсутствует.
  • Две задачи выполняются на разных физических ядрах с отключенной гиперпоточностью и в предположении, что переключение контекста отсутствует.

Обычно вторая конфигурация дает меньшее время выполнения, но возможные взаимодействия между задачами на ядре с поддержкой HT слишком сложны, чтобы знать наверняка. Например, вы упомянули, что две задачи могут конфликтовать в частных кэшах данных, но также существует возможность обмена данными. Кроме того, то, что происходит в остальной части системы, может повлиять на ускорение, которое вы можете получить при отключении гиперпоточности.

Возможно, вам придется немного отступить и определить, нужно ли это сравнение в первую очередь. Если общее количество задач, которые находятся в рабочем состоянии, не превышает общего количества физических ядер, будет ли ваш гипервизор планировать виртуальные ЦП на разных физических ядрах или упаковать их более плотно на меньшем количестве физических ядер, чтобы разместить другие ядра в спящем состоянии? Например, ядро ​​Liunx обычно предпочитает планировать один поток на каждом физическом ядре перед использованием другого логического ядра каждого ядра. Если количество задач больше, чем количество физических ядер, вам нужно провести другое сравнение, где гипертеги могут дать вам преимущество в избежании переключения контекста. Это основная ситуация, когда гиперпоточность может улучшить общую производительность. Вы даже можете добиться более высокого ускорения, определив, какие пары задач являются хорошими «братьями и сестрами», и изменив их сходство так, чтобы каждая дружественная пара планировалась на одном физическом ядре. Вам придется выполнить эту оптимизацию вручную, потому что большинство операционных систем и гипервизоров не могут сделать это автоматически (но есть предложения по исследованию на этот счет).

Еще одно большое преимущество гиперпоточности заключается в том, что она может обеспечить лучшую производительность на энергию, что является лучшим показателем для использования в случае, если потребление энергии не менее важно для производительности. Например, если есть только две выполняемые задачи, вы можете достичь более высокой производительности в расчете на энергию, если бы две задачи выполнялись на логических ядрах одного физического ядра по сравнению с их запуском на разных физических ядрах, даже если есть изобилие физических ядер.

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

person Hadi Brais    schedule 10.09.2019

Когда одно логическое ядро ​​находится в состоянии сна с низким энергопотреблением, физическое ядро ​​переключается в однопоточный режим и не разделяет ресурсы, которые статически разделены при работе в режиме HT. (Включая ROB, буфер хранилища, iTLB или dTLB на некоторых ЦП и IDQ на некоторых ЦП, где это не реплицируется. Различные поколения ЦП Intel реплицируют некоторые функции вместо статического разбиения на разделы для гиперпоточного режима. Ресурсы, которые совместно используются на конкурентной основе, подобно внутренним исполнительным модулям и кешу L1d, уже может более интенсивно использоваться одним потоком, когда другой в основном остановлен, но не находится в состоянии сна.)

Для этого состояния есть аппаратный счетчик производительности: под Linux вы можете использовать
perf stat -e cpu_clk_thread_unhalted.one_thread_active ./my_program. На моем Skylake с тактовой частотой 4 ГГц это составляет около 24 МГц, когда логическое ядро ​​имеет физическое ядро ​​целиком.

Нет ничего особенного в отключении HT в BIOS, ОС или гипервизоре.

Но это означает, что прерывания по таймеру или планирование задач или что-то еще никогда не разбудит родственное ядро ​​ядра, на котором работает ваш код. Это произойдет, если вы этого не сделаете, но влияние на производительность очень невелико.

Если что-то, что вы делаете на машине, действительно выигрывает от гиперпоточности, возможно, имеет смысл оставить HT включенным. (например, компиляция с make -j: компиляторы, как правило, имеют узкое место из-за задержки, промахов в кэше и неверных прогнозов ветвлений вместо пропускной способности памяти, внешней или внутренней пропускной способности или объема кеша.)


поскольку ЦП, выполняющий единственный поток, больше не должен «смотреть», чтобы увидеть, есть ли у другого потока работу.

Это не реальный механизм, влияющий на стоимость перфоманса. Если у обоих логических потоков есть инструкции, готовые к выполнению, они чередуют циклы во внешнем интерфейсе, выдавая группы из 4 мопов.

Если один логический поток остановлен (например, его половина ROB заполнена, промах в I-кэше или восстановление после ошибочного прогноза ветвления), другой логический поток получает все циклы внешнего интерфейса. Это не требует переключения в режим one_thread_active; Я думаю, что это происходит с детализацией цикла.

См. Также https://agner.org/optimize/ для более подробного изучения того, как процессоры x86 выполняют суперскалярное исполнение вне очереди и какие ресурсы разделяются статически, а какие - на конкурентной основе. (И некоторые полезные комментарии о том, когда HT полезен или нейтрален или вреден для параллельных рабочих нагрузок, которые могут эффективно масштабироваться с количеством потоков, например, matmul или что-то в этом роде).

person Peter Cordes    schedule 17.09.2019