Имеет ли смысл вручную привязывать процессы к конкретным процессорам/ядрам при использовании современных планировщиков ОС?

StackOverflow https://stackoverflow.com/questions/1602980

Вопрос

Недавно я узнал, что иногда люди привязывают определенные процессы или потоки к определенным процессорам или ядрам, и считается, что такая ручная настройка лучше всего распределит нагрузку.Для меня это немного противоречит здравому смыслу — я думаю, что планировщик ОС сможет принять лучшее решение, чем человек, о том, как распределить нагрузку.Я мог видеть, что это верно для старых операционных систем, которые, возможно, не знали о таких проблемах, как большая задержка между определенными парами ядер или общий кеш между одной парой ядер, но не другой парой.Но я предполагаю, что «современные» ОС, такие как Linux, Solaris 10, OS X и Vista, должны иметь планировщики, которые знают эту информацию.Я ошибаюсь насчет их возможностей?Я ошибаюсь, что эту проблему действительно может решить ОС?Меня особенно интересует ответ для Solaris и Linux.

Следствием этого является то, нужно ли мне информировать пользователей моего (многопоточного) программного обеспечения о том, как они могут рассмотреть возможность балансировки на своем компьютере.

Это было полезно?

Решение

Прежде всего, «Lock» — неправильный термин для его описания.«Аффинити» — более подходящий термин.

В большинстве случаев вам не нужно об этом заботиться.Однако в некоторых случаях ручная настройка привязки процессора/процесса/потока может быть полезной.

Операционные системы обычно не обращают внимания на детали современной многоядерной архитектуры.Например, предположим, что у нас есть двухпроцессорные четырехъядерные процессоры, и процессор поддерживает СМТ(=Гиперпоточность).В данном случае у нас есть 2 процессора, 8 ядер и 16 аппаратных потоков.Итак, ОС увидит 16 логических процессоров.Если ОС не распознает такую ​​иерархию, она, скорее всего, потеряет некоторый прирост производительности.Причины:

  1. Тайники:в нашем примере два разных процессора (установленные в двух разных сокетах) не используют общий внутренний кэш.Предположим, что в приложении имеется 4 занятых потока, и потоки совместно используют большой объем данных.Если ОС планирует потоки между процессорами, мы можем потерять некоторую локальность кэша, что приведет к снижению производительности.Однако потоки не передают много данных (имеют отдельный рабочий набор), поэтому лучше разделить их на разные физические процессоры за счет увеличения эффективной емкости кэша.Кроме того, может произойти более сложный сценарий, о котором ОС будет очень сложно знать.

  2. Конфликт ресурсов:давайте рассмотрим случай SMT(=HyperThreading).SMT использует множество важных ресурсов ЦП, таких как кэши, TLB и исполнительные блоки.Допустим, есть только два занятых потока.Однако ОС может по глупости запланировать эти два потока на двух логических процессорах одного физического ядра.В таком случае значительные ресурсы конкурируют между двумя логическими потоками.

Хорошим примером является Windows 7.Windows 7 теперь поддерживает политику интеллектуального планирования, учитывающую SMT (соответствующая статья).Windows 7 фактически предотвращает вышеуказанное 2.случай.Вот снимок диспетчера задач в Windows 7 с 20% нагрузкой на Core i7 (четырехъядерный процессор с HyperThreading = 8 логических процессоров):

alt text
(источник: egloos.com)

История использования процессора очень интересна, не так ли?:) Вы можете это увидеть используется только один процессор в парах, Это означает, что Windows 7 избегает одновременного планирования двух потоков на одном ядре.Эта политика определенно уменьшит негативные последствия SMT, такие как конфликт ресурсов.

Я бы хотел сказать, что ОС не очень умны, чтобы понимать современную многоядерную архитектуру, где много кешей, общий кеш последнего уровня, SMT и даже NUMA.Таким образом, могут быть веские причины, по которым вам может потребоваться вручную установить соответствие процессора/процесса/потока.

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

Другие советы

Для приложений общего назначения нет причин устанавливать привязку к процессору; Вы просто должны позволить планировщику ОС выбирать, какой ЦП должен запускать процесс или поток. Однако в некоторых случаях необходимо установить привязку к процессору. Например, в системах реального времени, где стоимость переноса потока из одного ядра в другое (что может произойти в любое время, если привязка к ЦП не установлена) может привести к непредсказуемым задержкам, которые могут привести к тому, что задачи будут уложены в сроки. исключить гарантии в реальном времени.

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

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

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

Это активно изучаемая тема, и существует отличный курс по OpenCourseWare MIT, который вникает в эти вопросы: http://ocw.mit.edu/OcwWeb/Electrical-Engineering-and-Computer-Science/6-189January--IAP --2007 / CourseHome /

Ну, кое-что, о чем многие не думали, это идея запрета запуска двух процессов на одном процессоре (сокете). Возможно, стоит помочь системе привязать разные интенсивно используемые процессы к разным процессорам. Это может избежать конфликта, если планировщик не достаточно умен, чтобы понять это сам.

Но это скорее задача системного администратора, чем задача для программистов. Я видел подобные оптимизации для нескольких высокопроизводительных серверов баз данных.

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

В общем, вы никогда не должны устанавливать сродство вашей нити, если у вас нет для этого веских причин. Вы не так хорошо понимаете, как ОС, другую работу, которую выполняют потоки в системе. Ядра постоянно обновляются на основе новой процессорной технологии (от одного процессора на сокет до гиперпоточности с несколькими ядрами на сокеты). Любая ваша попытка установить жесткую привязку может иметь неприятные последствия на будущих платформах.

Эта статья из журнала MSDN, Использование параллелизма для масштабируемости , дает хороший обзор многопоточности на Win32. Что касается сродства процессора,

  

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

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

Я даже не уверен, что вы можете привязать процессы к конкретному процессору в Linux. Итак, мой ответ «НЕТ» — пусть с этим справится ОС, в большинстве случаев она умнее вас.

Редактировать:Кажется, что в Win32 у вас есть некоторый контроль над тем, какое семейство процессоров вы собираетесь запускать этот процесс.Теперь я только жду, пока кто-нибудь докажет мою неправоту и в Linux/posix...

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top