Программирование для многоядерных процессоров

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

мой вопрос:

учитывая, что у вас многоядерная среда, могу ли я использовать какие-либо методы программирования для более эффективного использования доступных ресурсов? Как изменить код, чтобы повысить производительность в многоядерных средах?

4 ответов


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

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

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

было бы невозможно дать полный ответ о том, как писать эффективные параллельные программы на StackOverflow. Это действительно предмет по крайней мере одного (возможно, нескольких) курса информатики. Я предлагаю вам записаться на такой курс или купить книгу. Я бы порекомендовал вам книгу, если бы знал хорошую, но в курсе алгоритмов паралелла, который я изучал, не было учебника для этого курса. Вам также может быть интересно написать несколько программ, использующих последовательную реализацию, параллельную реализацию с многопоточностью (регулярные потоки, пулы потоков и т. д.), и параллельная реализация с передачей сообщений (например, с Hadoop, Apache Spark, облачными потоками данных, асинхронными RPCs и т. д.), а затем измерение их производительности, варьируя количество ядер в случае параллельных реализаций. Это была основная часть курсовой работы для моего курса параллельных алгоритмов и может быть довольно проницательной. Некоторые вычисления, которые вы можете попробовать распараллелить, включают вычисление Pi с помощью метода Монте-Карло (это тривиально распараллеливается, если вы можете создать генератор случайных чисел, где случайные числа генерируемые в разных потоках независимы), выполняя умножение матрицы, вычисляя форму эшелона строки матрицы, суммируя квадрат числа 1...N для очень большого числа n, и я уверен, что вы можете думать о других.


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

чтобы ваша операционная система использовала несколько ядер, вам нужно сделать одну из двух вещей: увеличить количество потоков на процесс или увеличить количество процессов, запущенных одновременно (или оба!).

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

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

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


Я не знаю, является ли это лучшим местом для начала, но я подписался на ленту статей из Intel Software Network некоторое время назад и нашли там много интересного, представленного довольно простым способом. Вы можете найти некоторые очень основные статьи по фундаментальным понятиям параллельных вычислений, как этой. здесь у вас есть быстрое погружение в openMP, что является одним из возможных подходов для начала распараллеливания самых медленных частей вашего применение, без изменения остальных. (Если эти части представляют параллелизм, конечно.) Также проверьте руководство Intel для разработки многопоточных приложений. Или просто пойти и просмотреть статьи раздела статьи не слишком много, так что вы можете быстро выяснить, что подходит вам лучше всего. У них также есть форум и неделю трансляция называемых параллельных разговоров программирования.


вы можете использовать языки программирования, предназначенные для параллельного программирования. Эрланг и Go приходят на ум.