Назад | Перейти на главную страницу

Сколько процессоров следует использовать с Hyperthreading?

Допустим, у меня есть серверный ЦП с 18 ядрами с включенной гиперпоточностью, что означает, что я вижу 36 ЦП в htop.

Чтобы полностью использовать ЦП и не влиять на однопоточную производительность, следует ли мне стремиться к тому, чтобы все 36 «ядер» работали на 100%, а ядра HT просто будут выполнять меньше работы и по-прежнему сообщать 100%, или это будет означать, что «полные» ядра уже прерываются задачей на «ядре HT» и, таким образом, выполняют меньше однопоточной работы?

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

Счетчики ЦП очень плохо говорят вам, насколько больше производительности вы можете выжать из своих гиперпоточных процессоров. Для этого вам следует запустить свои собственные тесты при различных уровнях превышения количества физических ядер. Есть некоторые рабочие нагрузки, которые лучше всего работают с полностью выключенным HT, поэтому включите этот случай в свое тестирование. Это может быть 1: 2 (36 параллельных рабочих процессов), или 1: 1,5, или даже 1: 2,5! Это зависит от вашей загруженности.

Более подробно, HT реализован на микросхеме таким образом, чтобы сократить время простоя процессора, когда необходимо переключить контекст или предсказание ветвления не удается. Это упрощает достижение 100% использования исполнительных модулей, чем с помощью простых трюков операционной системы. HT эволюционировал с момента своего появления, и на современных чипах больше параллелизма, чем на тех, которые мы использовали 10 лет назад.

Есть два профиля выполнения, которые влияют на оптимальную точку превышения лимита подписки:

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

Если второму виртуальному ядру разрешено участвовать, когда первое в противном случае зависло бы, это лучше, чем не, так что вы получите (по крайней мере) немного дополнительной работы.

Возникает вопрос: когда наличие двух разных потоков приводит к ухудшению работы одного? Прогнозирование ветвлений и зависимости между инструкциями не изменятся. Ожидание доступа к памяти сейчас ... два потока конкурируют за доступ к памяти, как в использовании кеша, так и в пропускной способности.

Если у вас одни процессоры работают с HT, а другие нет, означает ли это также, что вы назначите определенные потоки тому или иному типу? Я думаю, что нет: ваши программы будут запускать свои потоки на случайных виртуальных ядрах. Итак, как разделение конфигурации помогает? Поскольку каждый ЦП имеет свой собственный кэш, единственное влияние на него связано с пропускной способностью памяти и бременем когерентности кеша.

В общем, вы достигнете точки, где имея что-то большее, чем вы могли бы заниматься, обходится дороже, чем простаивать некоторые исполнительные блоки ЦП. Это зависит не напрямую от количества потоков, а от что делают потоки, а также подробную архитектуру памяти и нюансы производительности различных компонентов.

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

Вы должны попробовать это сами и мера что является самым быстрым, с этой конкретной работой на этой конкретной машине. И даже тогда это может измениться с обновлением программного обеспечения и изменением использования со временем.

Взгляни на том 3 гнева magnum opus. Если вы внимательно посмотрите на какой-то конкретный процессор, вы можете найти ограничивающие ресурсы среди глубокого конвейера многих шагов, необходимых для выполнения кода. Вам нужно найти случай, когда чрезмерное вознаграждение заставляет его выполняться медленнее, а не выполнять больше работы. В общем, это означало бы какое-то кеширование; и где ресурс распределяется между потоками.


Что означает счетчик ЦП: он сообщает обо всем времени, которое не было потрачено на выполнение незанятого потока. Оба логических потока, назначенных ядру, не будут бездействовать, даже если фактическая работа, выполняемая на одном из них, может быть небольшой. Время, потраченное на зависание конвейера на несколько циклов, пока результаты не будут готовы, память будет извлечена, атомарные операции изолированы и т. Д., Аналогично не заставляет поток откладывать как «не готов», чтобы он не простаивал, и время по-прежнему отображается как использованное. Ожидание в ОЗУ не будет отображаться как бездействие. Только что-то вроде ввода-вывода заставит поток блокироваться и прекратит заряжать его. Мьютекс операционной системы в целом будет делать это, но с появлением многоядерных систем это уже не так, как "спин-блокировка". не верните нить на полку.

Таким образом, 100% -ный счетчик ЦП не означает, что все идет гладко, если ЦП часто зависает в ожидании памяти. Меньшее количество логических ядер, показывающих 90%, вполне могло бы выполнять больше работы, поскольку заканчивается номер хрустит и теперь ждет на диске.

Так что не беспокойтесь о счетчике ЦП. Посмотрите на фактический прогресс, только.

Вы должны увидеть, что все 36 ядер работают на 100% - при условии, что программное обеспечение может это сделать (что нетривиально - планирование может быть сложным с таким количеством ядер, поэтому допустимы падения ниже 100%).

Очевидно, что когда вы «разбиваете» руду с помощью гиперпоточности, значение этих 200% не равно «2x100% - выполненной работы. Но это невидимо для любых выполненных измерений (которые исходят от загрузки процессора и не имеют понятия о выполненной работе). Сколько работы будет выполнено, зависит от того, что это за работа - большую часть времени следует ожидать где-то выше 1,5-кратной работы без гиперпоточности.

Способ реализации гиперпоточности зависит от конкретного процессора. От Nehalem до Skylake Intel значительно сократила количество общих частей конвейера с фиксированным соотношением (например, 50/50), перейдя к динамически разделяемым структурам.

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

Как это возможно? Ключевой момент, который следует понять, заключается в том, что ЦП не представляет физические ядра и виртуальные как равные ядра, скорее он предоставляет последние таким образом, чтобы планировщик Linux не мог избежать планирования для них, если доступны какие-либо другие физические ядра. Другими словами, сначала используются все физические ядра, затем он начинает использовать виртуальный.

Это означает, что, как правило, HyperThreading является очень ценной функцией (другие процессоры, такие как Power8, используют еще более глубокие методы SMT), и что для максимальной пропускной способности вы должны включить ее, загрузив ЦП хотя бы одним потоком на виртуальное или физическое ядро. В качестве практического примера, чтобы извлечь полную производительность из 18-ядерного процессора, вы должны использовать как минимум 36 потоков.

Существуют два исключения:

  1. если все, что вам нужно, это минимизировать задержку из ограниченного набора потоков (где потоки <физических ядер), вы можете отключить HT
  2. очень старый ЦП (Pentium4 и, в гораздо меньшей степени, Nehalem) имеет негибкие правила разделения, которые заставляют ЦП разделять многие ключевые ресурсы в соотношении 50/50 независимо от состояния / нагрузки второго потока. В этом случае вам нужно было протестировать свой вариант использования, чтобы убедиться, что добавленная пропускная способность стоит значительно более низкой производительности одного потока.