Многоядерное программирование в Haskell - Управление. Параллель

Лед от ZeroC является действительно высокой производительностью "enterprisey" уровень взаимодействия, который поддерживает Java и .net среди других. Я думаю о нем как обновленный Corba - это даже имеет свой собственный объектно-ориентированный язык определения интерфейсов, названный Часть (как IDL Corba, но на самом деле довольно читаемый).

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

10
задан Peter Mortensen 19 April 2011 в 12:57
поделиться

3 ответа

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

import Control.Parallel

cutoff :: Int
cutoff = 20

parFib :: Int -> Int
parFib n | n < cutoff = fib n
parFib n = p `par` q `pseq` (p + q)
    where
      p = parFib $ n - 1
      q = parFib $ n - 2

fib :: Int -> Int
fib 0 = 0
fib 1 = 1
fib n = fib (n - 1) + fib (n - 2)

main :: IO ()
main = print $ parFib 40

демонстрация:

[computer ~]$ ghc --make -threaded -O2 Main.hs
[1 of 1] Compiling Main             ( Main.hs, Main.o )
Linking Main ...
[computer ~]$ time ./Main +RTS -N1
102334155

real    0m1.509s
user    0m1.450s
sys     0m0.003s
[computer ~]$ time ./Main +RTS -N2
102334155

real    0m0.776s
user    0m1.487s
sys     0m0.023s
[computer ~]$ time ./Main +RTS -N3
102334155

real    0m0.564s
user    0m1.487s
sys     0m0.030s
[computer ~]$ time ./Main +RTS -N4
102334155

real    0m0.510s
user    0m1.587s
sys     0m0.047s
[computer ~]$ 
15
ответ дан 3 December 2019 в 14:53
поделиться

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

Решение состоит в том, чтобы используйте стратегию отсечения, как описано в этом докладе: http://donsbot.wordpress.com/2009/09/05/defun-2009-multicore-programming-in-haskell-now/

По сути, переключение как только вы достигнете определенной глубины, перейдите к версии с прямой линией и используйте + RTS -sstderr, чтобы увидеть, сколько искр преобразуется, чтобы вы могли определить, тратите ли вы работу впустую или нет.

12
ответ дан 3 December 2019 в 14:53
поделиться

Re (1): par позволяет вычислить a в другом потоке. Я предполагаю здесь, но я думаю, что pseq ведет себя очень похоже на seq : он заставляет сначала вычислить первый результат (ну, seq не гарантированно сделает это, но на практике на GHC это так). Таким образом, в этом случае вычисление a разветвляется как один поток, а другой поток вычисляет b , а затем суммирует a и b .

Re (2): Это довольно тривиальное вычисление, переданное другим потокам; вероятно, процессор так же быстро вычислит его сам. Держу пари, что накладные расходы на потоки вредят почти так же, как и помогают в этом простом вычислении.

1
ответ дан 3 December 2019 в 14:53
поделиться
Другие вопросы по тегам:

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