Параллелизм и многопоточность

Я не очень опытен с предметами, такими как Параллелизм и Многопоточность. На самом деле в большей части моей карьеры веб-разработки я никогда не должен был касаться этих предметов.

Я чувствую, что это - важное понятие, специально для Настольных приложений и в основном любого другого приложения, которое не генерирует HTML:).

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

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

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

14
задан Luca Matteis 3 January 2010 в 22:46
поделиться

9 ответов

Ну, во-первых, многопоточность - это не то же самое, что многопроцессорность, поэтому fork() здесь действительно не применяется.

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

Итак, ваш вопрос в том, почему некоторые языки должны быть лучше? Ну, некоторые вещи могут сделать это проще:

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

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

  • Атомные транзакции. Даже лучше, чем широкий набор синхронизирующих примитивов, не использовать их вообще. Двигатели баз данных очень хороши в этом; вместо вас, программист, должен точно определить, какие ресурсы нужно заблокировать, когда и как, вы просто говорите компилятору или интерпретатору: "все, что находится ниже этой строки, должно происходить вместе, так что убедитесь, что никто больше не связывается с ней, пока я ее использую". И движок разберется с блокировкой для вас. Такой простоты в абстрактном языке программирования почти никогда не бывает, но чем ближе ты можешь подойти, тем лучше. Нитробезопасные объекты, которые объединяют несколько общих операций в одну - это старт.

  • Автоматический параллелизм. Допустим, нужно выполнить итерацию по длинному списку элементов и как-то трансформировать их, например, умножить 50 000 матриц 10х10. Было бы неплохо, если бы Вы просто рассказали компилятору: Эй, каждая операция может выполняться независимо, так что используйте для каждой операции отдельное ядро процессора? Без необходимости самостоятельно реализовывать потоковую обработку? Некоторые языки поддерживают такие вещи; например, команда .NET работает над PLINQ.

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

28
ответ дан 1 December 2019 в 07:12
поделиться

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

Кроме того, в языке программирования, предназначенном для параллелизма, как правило, существует лишь несколько способов делать параллельные вещи, что приводит к согласованности. Напротив, если язык программирования не был разработан для параллелизма, то разные библиотеки и разные программисты будут делать разные вещи по-разному, что затрудняет выбор, как их делать.

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

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

.
4
ответ дан 1 December 2019 в 07:12
поделиться

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

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

.
2
ответ дан 1 December 2019 в 07:12
поделиться

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

А затем некоторые языки имеют различные базовые модели потоков, чем другие. Модель потоков на Python, как я понимаю, использует один системный поток и обрабатывает весь контекст, коммутируя сам себя, что не так чисто, как это бывает только с одной инструкцией на Python.

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

Редактирование: frunsi верно, нити на Python - это системные нити (видимо, это распространенное заблуждение). Проблема, о которой я говорил, была с GIL, или глобальной блокировкой интерпретатора, которая контролирует выполнение потока. В интерпретаторе Python может одновременно работать только один поток, и контекст переключается только между инструкциями. Мои знания о многопоточности Python в основном пришли из этой статьи: www.dabeaz.com/python/GIL.pdf . Может быть, немного не по теме, но, тем не менее, хорошая ссылка.

.
1
ответ дан 1 December 2019 в 07:12
поделиться

Я изучаю этот предмет (прямо сейчас :D) и одно из того, что кажется очень важным различием в параллельности языков, - это способность языка выражать параллельность.

Например, C++ не имеет родной поддержки параллельности и полагается на функции, предоставляемые операционной системой.

Java - это шаг вперед, потому что имеет некоторые встроенные методы, в то время как другие методы оставлены на усмотрение операционной системы (например, планирование потоков или приоритет).

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

Почему это так важно? Из-за переносимости !

Использование языка с хорошей выразительной способностью к параллельной работе позволяет вам привнести вашу параллельную программу в Windows, linux или Mac, не испытывая больших опасений по поводу того, как она будет работать. Например: приоритет потока будет применен в таким же образом в вашей программе Ada, работающей в Windows, linux или Mac, в то время как он может быть действительно различным (игнорируемым в одних ОС и применяемым в других) с Java или C++.

Это то, что мне кажется по курсу, который я сейчас прохожу в университете :)

.
2
ответ дан 1 December 2019 в 07:12
поделиться

Вилка - это человек, чтобы поток был божественным :D

Вилка включает в себя ядро и создает отдельное адресное пространство - это означает, что proc X и Y не могут легко делиться и использовать IPC примитивы, а создание потока позволяет синхронизировать процессы, что является FAR быстрее, чем IPC, который включает в себя переключатели контекста ядра как процессами, так и ненужными потоками (которые включают в себя ядро, чтобы разбудить этот поток вверх).

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

.
1
ответ дан 1 December 2019 в 07:12
поделиться

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

.
0
ответ дан 1 December 2019 в 07:12
поделиться

Выбор языка зависит от того, какое приложение вы хотите сделать.

Хотите создать высокомасштабируемую систему, с большим количеством поступающих "запросов"? Тогда Erlang может быть хорошим выбором. Известно, что он хорошо подходит для "сильно параллельных" сценариев приложений.

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

В (серверной) веб-разработке вы, скорее всего, уже приобрели некоторый опыт в параллельном программировании! Возможно, вы не знали об этом, потому что язык и данный фреймворк (возможно, Apache и PHP) предоставили вам среду, которая снимает с вас бремя

.
0
ответ дан 1 December 2019 в 07:12
поделиться

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

.
0
ответ дан 1 December 2019 в 07:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: