Зачем нам нужен '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 как в оригинальном, стандартном коде?

3 ответа

Решение

Хорошо. Я думаю, что следующая статья отвечает на мой вопрос: 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 материализовать в поток для параллельной оценки.

a `par` b `par` a+b 

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

Тем не менее, pseq гарантирует, что a и b будут оценены перед тем, как a+b будет.

Смотрите эту ссылку для более подробной информации по этой теме.

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

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и мы не создали ненужных искр.

Другие вопросы по тегам