Насколько сложно многопоточность Haskell?
=========================================

Я слышал, что в Haskell создание многопоточного приложения так же просто, как принятие стандартного приложения Haskell и его компиляция с флагом `-threaded`. Другие случаи, однако, описали использование команды `par` в самом исходном коде.

Каково состояние многопоточности Haskell? Насколько легко внедряться в программы? Есть ли хороший многопоточный учебник, который охватывает эти разные команды и их использование?

 

>  Каково состояние многопоточности Haskell?
> 
> 
> 

Зрелые. Реализация составляет около 15 лет, с транзакционной памятью на 5 лет. GHC - широко используемый компилятор с большой поддержкой с открытым исходным кодом и коммерческой поддержкой.

>  Насколько легко внедряться в программы?
> 
> 
> 

Это зависит от алгоритма. Иногда это может быть использование одной строки `par` для получения parallelism. Иногда необходимо разработать новые алгоритмы. В общем, будет проще вводить безопасные parallelism и concurrency в Haskell, чем в типичных языках, и производительность хорошая.

>  Есть ли хороший многопоточный учебник, в котором рассматриваются эти разные команды и их использование?
> 
> 
> 

В Haskell есть 3 основные параллельные и параллельные модели программирования.

* неявный parallelism через `par`
* явный concurrency и parallelism через forkIO/MVars и транзакционную память программного обеспечения
* данные parallelism через библиотеки DPH

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

Вот [введение в основные модели параллельного программирования в Haskell,](https://donsbot.wordpress.com/2010/06/01/open-source-bridge-talk-multicore-haskell-now/) и как добиться ускорений.

Я думаю, [Глава 24 Real World Haskell](http://book.realworldhaskell.org/read/concurrent-and-multicore-programming.html) - хороший учебник.

 

Существует также термин concurrency.

Без каких-либо изменений кода ваш haskell rts попытается использовать их для некоторого внутреннего процесса, но для использования в вашем приложении вы должны дать подсказку, сделанную `par b (f a b)`, которая заставляет Haskell быть не так ленив на caculation `b`, даже если `f` не потребует его для результата.

Одна из причин не делать этого для каждой функции, для которой требуются все ее аргументы (например, `a+b`), заключается в том, что синхронизация (планирование вычислений и ожидание результатов) дает некоторые накладные расходы, и вы, вероятно, не хотите тратить дополнительные средства -ticks для `(2*3)+(3*4)` только потому, что вы можете рассчитать умножения параллельно. И вы, вероятно, потеряете некоторые кеш-хиты или что-то вроде этого или оптимизации, которые выполняются, когда вы делаете это на одном процессоре (т.е. Вы все равно должны передавать результат от одного процессора к другому).

Конечно, код, который использует `par`, является уродливым, и когда вы сворачиваете список или некоторые другие структуры данных со светлыми субэлементами, вы, вероятно, захотите рассчитать некоторые куски этих легких элементов, чтобы убедиться, что служебные/быть очень маленьким. Чтобы разрешить это, вы можете посмотреть [parallel](https://hackage.haskell.org/package/parallel).

Существует также Data Parallel Haskell (DPH).

Если ваша программа больше похожа на IO monad, вам определенно нужно много изменений. См. [`forkIO`](https://hackage.haskell.org/packages/archive/base/4.2.0.1/doc/html/Control-Concurrent.html#v%3AforkIO), [Программная транзакционная память (STM)](https://hackage.haskell.org/package/stm) и многие другие из [Concurrency category](https://hackage.haskell.org/packages/archive/pkg-list.html#cat:concurrency)