Запутался насчет параллельного Хаскелла - PullRequest
1 голос
/ 03 апреля 2009

Как выглядит этот код:

parfib :: Int -> Int
parfib 0 = 1
parfib 1 = 1
parfib n = nf2 `par` (nf1 `par` (nf1+nf2+1))
           where nf1 = parfib (n-1)
                 nf2 = parfib (n-2)

Лучше, чем это:

parfib :: Int -> Int
parfib 0 = 1
parfib 1 = 1
parfib n = nf2 `par` (nf1 `seq` (nf1+nf2+1))
           where nf1 = parfib (n-1)
                 nf2 = parfib (n-2)

Я не получаю объяснений, которые я нашел в Интернете, которые говорят: «Чтобы гарантировать, что основное выражение оценено в правильном порядке (т.е. без блокировки основной задачи в дочерней задаче), используется аннотация seq» .

Почему используется seq? Я знаю, что это заставляет переводчика сначала оценить parfib (n-1), но зачем это нужно?

При выполнении второй программы не будет ли интерпретатор инициировать новый процесс для оценки nf2 при одновременной оценке nf1 выражения nf1 + nf2 + 1 параллельно? Что нужно сказать ему, чтобы указать, что он должен начинаться с nf1?

Ответы [ 2 ]

4 голосов
/ 03 апреля 2009

Не имеет особого смысла оценивать nf1 параллельно nf1+..., так как последний зависит от nf1, поэтому все, что он должен сделать, это заблокировать искру nf1. При использовании seq он будет пытаться использовать nf1 только после того, как вы узнаете, что он был оценен.

0 голосов
/ 07 июня 2009

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

, но при первом варианте вы будете запускать два дополнительных процесса (nf1, nf2). Но когда мы используем seq, мы просто запускаем только один дополнительный процесс (nf1).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...