Как планируются легкие потоки ядром linux в многоядерной многоядерной SMP-системе?

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

2 ответа

Решение

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

В зависимости от версии Linux, которую вы используете, могут быть полезны две статьи: в этой статье описываются ядра ранних версий 2.6, начиная с версии 2.6.22, и в этой статье описываются ядра новее, чем 2.6.23.

Различные библиотеки потоков выполняют операции потоков по-разному. В наши дни "стандартом" в Linux является NPTL, который планирует потоки на том же уровне, что и процессы. Это вполне нормально, поскольку процесс создания в Linux быстрый, и он всегда должен оставаться быстрым.

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

Обычно это хорошо, но я заметил, что ядро ​​не всегда может переносить задачи с занятых ядер на незанятые. Это поведение может меняться от версии к версии, но я обнаружил, что несколько задач, связанных с процессором, выполняются на одном ядре, а три других ядра простаивают. (Я нашел это, заметив, что одно ядро ​​было на шесть или семь градусов Цельсия теплее, чем три других.)

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

Другие вопросы по тегам