Программирование для многоядерных процессоров - PullRequest
16 голосов
/ 18 марта 2010

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

мой вопрос,

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

Ответы [ 4 ]

15 голосов
/ 18 марта 2010

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

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

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

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

4 голосов
/ 19 марта 2010

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

3 голосов
/ 18 марта 2010

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

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

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

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

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

0 голосов
/ 19 марта 2010

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

...