Имеет ли смысл в современных планировщиках ОС вручную блокировать процессы для конкретных процессоров / ядер? - PullRequest
4 голосов
/ 21 октября 2009

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

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

Ответы [ 7 ]

3 голосов
/ 10 ноября 2009

Прежде всего, «Замок» - неправильный термин для его описания. «Сродство» является более подходящим термином.

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

Операционные системы обычно не обращают внимания на детали современной многоядерной архитектуры. Например, скажем, у нас есть 2-сокетные четырехъядерные процессоры, и процессор поддерживает SMT (= HyperThreading). В этом случае у нас есть 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. Поэтому могут быть веские причины, по которым вам может потребоваться вручную установить привязку к процессору / процессу / потоку.

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

1 голос
/ 09 ноября 2009

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

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

1 голос
/ 22 октября 2009

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

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

1 голос
/ 21 октября 2009

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

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

Статья: Производительность в реальном времени и промежуточное ПО для многопроцессорных и многоядерных платформ Linux

0 голосов
/ 21 октября 2009

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

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

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

0 голосов
/ 21 октября 2009

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

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

0 голосов
/ 21 октября 2009

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

Edit: Похоже, что на win32 у вас есть некоторый контроль над тем, какое семейство процессоров вы собираетесь запускать этот процесс. Теперь я только жду, пока кто-нибудь докажет, что я не прав, и на linux / posix ...

...