Несколько потоков на двухъядерном процессоре

#multithreading #pthreads

#многопоточность #pthreads

Вопрос:

Я изучаю темы и немного смущен одной вещью.

Если у меня есть один процесс с несколькими потоками, запущенный на двух- / четырехъядерном процессоре, будут ли разные потоки выполняться одновременно на разных ядрах?

Заранее спасибо.

Ответ №1:

Это зависит.

По крайней мере, в Linux каждая задача назначается набору процессоров, на которых она может выполняться ( processor affinity ). И, по крайней мере, в Linux, планировщик попытается запланировать задачу на том же процессоре, что и в прошлый раз, чтобы получить максимальную выгоду от повторного использования кэша процессора. Забавно то, что это не всегда приводит к перебалансировке, когда система находится под нагрузкой, поэтому можно запустить одно ядро довольно горячим и оспариваемым, а три ядра оставить холодными и относительно бездействующими. (Я видел именно такое поведение с клиентом Folding @ Home.)

Вы можете принудительно установить необходимую вам близость с помощью pthread_setaffinity_np(3) подпрограммы для многопоточных приложений или sched_setaffinity(2) для более традиционных fork(2) приложений ed в стиле Unix. Или вы можете использовать taskset(1) программу для установки соответствия до или после запуска приложения. (Именно такой подход я использовал в своем глупом клиенте Folding @ Home — было легко модифицировать initscript для вызова taskset(1) , чтобы правильно установить привязку каждого клиентского процесса, чтобы каждый клиент получил свое собственное ядро и не конкурировал за ресурсы с другими клиентами на разных родственных гиперпоточных «фальшивых» исполнительных ядрах.)

Ответ №2:

ДА


Это зависит от языка, библиотеки и операционной системы, а также от того, имеет ли многопоточное приложение когда-либо несколько выполняемых потоков в один и тот же момент времени, но обычно ответ «да».

Комментарии:

1. Спасибо за ваш ответ. Хотя я только что нашел это в своей книге. «Основное различие можно увидеть при использовании многопроцессорных систем, пользовательские потоки, полностью управляемые библиотекой потоков, не могут выполняться параллельно на разных процессорах, хотя это означает, что они будут нормально выполняться на однопроцессорных системах. Поскольку потоки ядра используют планировщик ядра, разные потоки ядра могут выполняться на разных процессорах.» Так что я немного сбит с толку!!

Ответ №3:

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

Комментарии:

1. Почему потоки из одного процесса будут выполняться параллельно на многоядерном процессоре, если они из игры? Поток t = новый поток (game_threads = true); Таким образом, планировщик будет знать, что этот поток может выполняться параллельно с другими потоками?

2. @gfelisberto: Видишь скобки? Игра была бы примером чего-то, требующего больших затрат процессора, что привело бы к запуску разных потоков на разных ядрах, поскольку они не могут действительно выполняться на одном ядре из-за того, что требуется время процессора. Я думаю. Это было более двух лет назад. В любом случае, если потоки не активны одновременно, а другие ядра заняты чем-то ресурсоемким, само собой разумеется, что они могут работать на одном ядре. Однако IANACD. (Я не разработчик микросхем). И, конечно, «вы никогда не можете быть уверены в этом факте» было важной частью.

Ответ №4:

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

Ответ №5:

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

Ответ №6:

Я думаю, что вы теряете идею параллелизма; дело не в том, что вы хотите запускать процессы на нескольких ядрах. Вместо этого вам не нужно все время блокировать один процесс. Прекрасным примером этого является потоковое сетевое прослушивание. Вы хотите выполнить accept, который фактически создаст новый клиент-> серверный сокет. После этого вы хотите выполнить некоторую обработку с этим сокетом, сохраняя при этом возможность принимать новые подключения. Здесь вы хотели бы сгенерировать поток для выполнения обработки, чтобы accept мог вернуться к ожиданию нового соединения.

Комментарии:

1. Хорошо, я привожу здесь очень абстрактный пример, это из моего лектора. Допустим, у нас запущен MS Word, и предположим, что 1 поток занимается проверкой орфографии, а другой — проверкой грамматики, оба потока из msword.exe может ли поток проверки орфографии выполняться на одном ядре, а проверка грамматики выполняться на другом ядре одновременно.

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