Подтвердить что ты не робот

Почему нам нужно "seq" или "pseq" с "par" в Haskell?

Я пытаюсь понять, почему нам нужны все части стандартного образца кода:

a `par` b `pseq` a+b

Почему этого недостаточно?

a `par` b `par` a+b

Вышеприведенное выражение кажется очень описательным: попробуйте параллельно и a и b, и верните результат a+b. Является ли причина только эффективностью: вторая версия будет вызывать два раза вместо одного?

Как насчет следующей, более сжатой версии?

a `par` a+b

Почему нам нужно убедиться, что b оценивается до a+b, как в исходном стандартном коде?

4b9b3361

Ответ 1

Ok. Я думаю, что следующая статья отвечает на мой вопрос: http://community.haskell.org/~simonmar/papers/threadscope.pdf

Таким образом, проблема с

a `par` b `par` a+b 

и

a `par` a+b

- отсутствие порядка оценки. В обеих версиях основной поток начинает работать с a (или иногда b) сразу, заставляя искры "отгонять" сразу, так как нет необходимости запускать нить для оценки того, что основной поток уже начал оценивать.

Оригинальная версия

a `par` b `pseq` a+b

обеспечивает, чтобы основной поток работал на b до a+b (или иначе начал бы оценивать a), тем самым давая возможность искровой a материализоваться в нить для параллельной оценки.

Ответ 2

a `par` b `par` a+b 

будет оценивать a и b параллельно и возвращает a + b, да.

Тем не менее, pseq there обеспечивает как a, так и b оцениваются до того, как a + b.

Подробнее об этой теме см. эту ссылку.

Ответ 3

a `par` b `par` a+b создает искры как для a, так и для b, но a+b достигается немедленно, так что одна из искр будет fizzle (т.е. оценивается в основном потоке). Проблема с этим - эффективность, поскольку мы создали ненужную искру. Если вы используете это для реализации параллельного деления и покорения, тогда накладные расходы будут ограничивать ваше ускорение.

a `par` a+b кажется лучше, потому что он создает только одну искру. Однако попытка оценить a до b приведет к искривлению искры для a, а поскольку b не имеет искры, это приведет к последовательной оценке a+b. Переключение порядка на b+a решило бы эту проблему, но в качестве кода это не обеспечивает упорядочение, и Haskell все еще может оценить это как a+b.

Итак, мы делаем a `par` b `pseq` a+b для принудительной оценки b в основном потоке, прежде чем пытаемся оценить a+b. Это дает возможность искробезопасности a, прежде чем мы попытаемся оценить a+b, и мы не создали ненужных искр.