Разница между параллельным и параллельным программированием?

44

При рассмотрении параллельного программирования обычно используются два термина: параллельный и параллельный.

А некоторые языки программирования специально заявляют о поддержке параллельного программирования, например, Java .

Означает ли это, что параллельное и параллельное программирование на самом деле отличаются?

nish1013
источник
10
Да, параллельное и параллельное программирование разные. например, у вас может быть два потока (или процесса), выполняющихся одновременно на одном и том же ядре посредством переключения контекста. Когда два потока (или процессы) выполняются на двух разных ядрах (или процессорах), вы получаете параллелизм. Итак, в первом случае (параллелизм) параллелизм является только «виртуальным», тогда как во втором случае вы имеете истинный параллелизм. Следовательно, каждая параллельная программа является параллельной, но обратное не обязательно верно.
Массимо Кафаро
1
Будьте осторожны здесь. Вы можете достичь того же результата либо с помощью языковой поддержки (т. Е. Расширения языка новыми конструкциями), либо с помощью низкоуровневого подхода (например, с помощью библиотеки, как в случае MPI и OpenMP). В любом случае, с текущими многоядерными процессорами и операционными системами с поддержкой SMP программа, которая будет работать одновременно на старых одноядерных процессорах, может выполняться параллельно, если ОС планирует потоки выполнения программы на разных ядрах. Таким образом, различие немного "размыто" в наше время.
Массимо Кафаро
3
Что вы используете для световой константы скорости света. В параллельности вы притворяетесь, что задержка скорости света равна одному такту. Параллельно вы предполагаете, что один сервер находится по соседству, а в распределенном - один сервер находится на Марсе.
1
Роберт Харпер обсуждает эту проблему в двух сообщениях в блогах: «Параллелизм - это не параллелизм» и «Параллелизм и параллелизм, вновь посещенный» , которые вы, возможно, захотите проверить.
Василий

Ответы:

26

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

Из «Софомического * введения в параллелизм и параллелизм совместно используемой памяти» Дэна Гроссмана (версия от 16 ноября 2013 г.)

Рафаэль
источник
21

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

Цитирую оттуда:

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

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

Напротив, параллелизм - это метод структурирования программы, в котором существует несколько потоков управления. Условно потоки управления выполняются «одновременно»; пользователь видит, что их эффекты чередуются. Независимо от того, выполняются ли они одновременно или нет, это деталь реализации; Параллельная программа может выполняться на одном процессоре с чередованием или на нескольких физических процессорах.

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

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

Понятие «потоки управления» не имеет смысла в чисто функциональной программе, потому что нет никаких эффектов, которые нужно наблюдать, и порядок оценки не имеет значения. Таким образом, параллелизм - это метод структурирования для эффективного кода; в Haskell это означает код в монаде IO.

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

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

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

Nickie
источник
20

Параллельность и параллелизм различаются по проблемам, которые они решают и вызывают, но они не являются независимыми.

совпадение

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

Это полезно в некоторых отношениях:

  • Более четкое программирование самостоятельных задач в одной программе.
  • Позволяет работать с вводом-выводом во время вычислений (например, в графическом интерфейсе).
  • Позволяет одновременно выполнять более одной программы (параллелизм на уровне ОС).

Некоторые из основных проблем:

  • Поддерживать согласованность данных.
  • Избегайте тупики и livelocks .
  • Определить точную семантику параллельных процессов.
  • Определите статические свойства, которые гарантируют правильность.

параллелизм

Выполнение двух задач параллельно означает, что операторы выполняются одновременно . Это в основном полезно для:

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

Ключевые проблемы включают в себя:

  • Проблемы разбиения, которые позволяют и развивают алгоритмы, которые могут использовать параллелизм.
  • Минимизируйте зависимости и общение между вычислительными блоками.
  • Все проблемы, связанные с параллелизмом: по крайней мере, с точки зрения памяти, параллельные программы выглядят как параллельные из-за сериализации доступа к памяти.
  • Работа с неоптимальной аппаратной поддержкой.

Смотрите также этот вопрос для различения параллельных и распределенных вычислений.

Рафаэль
источник
5

Возможно, слегка идеализированный ответ ...

  • Параллельность - это свойство написания программы . Если программа написана с использованием таких конструкций, как разветвления / объединения, блокировки, транзакции, атомарные операции сравнения и замены и т. Д., То она выполняется одновременно.

  • Параллелизм - это свойство того, как выполняется программа . Если программа выполняется более чем на одном вычислительном блоке одновременно, то она выполняется параллельно.

Джон Викерсон
источник
1

Есть множество ответов на это, но это может сбить с толку. Мне нравится думать об этом таким образом, и, может быть, это помогает ?:

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

Пример может включать создание сотен HTTP-запросов. В NodeJS самое простое решение - открыть все 100 запросов одновременно с помощью метода обратного вызова, а когда ответы возвращаются, метод выполняется каждый раз. Это параллельное программирование. В Ruby самое простое (наиболее распространенное) решение - открыть запрос и обработать ответ, открыть следующий запрос и обработать ответ, и т. Д. Для многих запросов NodeJS проще выполнить своевременно, хотя вам нужно будьте осторожны, чтобы не перегружать сервер и не увеличивать количество исходящих соединений (это легко сделать по ошибке). Вы можете писать Ruby одновременно, но это не так, как написано большинство кода на Ruby, и это немного мешает это делать.

Параллельное программированиеэто код, который может быть запущен одновременно в нескольких потоках или процессах. Это позволяет оптимизировать производительность, выполняя код на нескольких процессорах (часто включая несколько компьютеров, как вы могли бы с чем-то вроде Akka). Поскольку NodeJS не является многопоточным и параллельное выполнение не требуется, вам не нужно беспокоиться о написании многопоточного кода (и большая часть кода JavaScript, который я видел, не является поточно-ориентированным). В Java, хотя язык не делает параллельное программирование нормальным шаблоном, параллельное программирование очень встроено, и вам часто приходится беспокоиться о безопасности потоков. Если вы пишете веб-сайт на Java, обычно это будет выполняться в контейнере, который выполняет каждый запрос в отдельном потоке в той же памяти,


Некоторые из вышеперечисленных зависит от объема и границ, о которых вы говорите. Я работаю на сайтах. Большая часть кода Java, который я вижу, не является параллельным программированием. Конечно, если вы уменьшаете масштаб достаточно, порядок, в котором поступают запросы клиентов, не важен, но если вы увеличиваете масштаб дальше, порядок выполнения вещей определяется кодом. Но код написан так, что запросы могут выполняться параллельно с большим количеством общих объектов, которые должны быть поточно-ориентированными.

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

Для дополнительного чтения мне очень нравятся иллюстрации в верхнем ответе на этот вопрос здесь: https://www.quora.com/What-are-the-differences-between-parallel-concurrent-and-asynchronous-programming

Джун-Дай Бейтс-Кобашигава
источник