por - pattern matching haskell
¿Por qué necesitamos ''seq'' o ''pseq'' con ''par'' en Haskell? (3)
Estoy tratando de entender por qué necesitamos todas las partes del código de muestra estándar:
a `par` b `pseq` a+b
¿Por qué no será suficiente lo siguiente?
a `par` b `par` a+b
La expresión anterior parece muy descriptiva: intente evaluar tanto a
como b
en paralelo, y devuelva el resultado a+b
. ¿El motivo es solo el de la eficiencia: la segunda versión se activaría dos veces en lugar de una sola vez?
¿Qué tal la siguiente, versión más sucinta?
a `par` a+b
¿Por qué deberíamos asegurarnos de que b
se evalúe antes de a+b
como en el código estándar original?
De acuerdo. Creo que el siguiente documento responde mi pregunta: http://community.haskell.org/~simonmar/papers/threadscope.pdf
En resumen, el problema con
a `par` b `par` a+b
y
a `par` a+b
es la falta de ordenamiento de la evaluación. En ambas versiones, el hilo principal se pone a trabajar en a
(o a veces b
) inmediatamente, provocando que las chispas se "esfumen" inmediatamente ya que ya no hay necesidad de iniciar un hilo para evaluar lo que el hilo principal ya ha comenzado a evaluar.
La versión original
a `par` b `pseq` a+b
asegura que el hilo principal funcione en b
antes de a+b
(o de lo contrario habría comenzado a evaluar a
), dando así la posibilidad de que la chispa a se materialice en un hilo para una evaluación paralela.
a `par` b `par` a+b
crea chispas para a
y b
, pero a+b
se alcanza inmediatamente para que una de las chispas se encienda (es decir, se evalúa en el hilo principal). El problema con esto es la eficiencia, ya que creamos una chispa innecesaria. Si está utilizando esto para implementar divide y vencer en paralelo, la sobrecarga limitará su aceleración.
a `par` a+b
parece mejor porque solo crea una sola chispa. Sin embargo, intentar evaluar a
antes b
hará que la chispa se inflame para a
, y como b
no tiene una chispa, esto resultará en una evaluación secuencial de a+b
. Cambiar el orden a b+a
resolvería este problema, pero como código, esto no impone el ordenamiento y Haskell aún podría evaluar eso como a+b
.
Entonces, hacemos a `par` b `pseq` a+b
para forzar la evaluación de b
en el hilo principal antes de intentar evaluar a+b
. Esto da a
oportunidad de materializarse antes de intentar evaluar a+b
, y no hemos creado chispas innecesarias.
a `par` b `par` a+b
evaluará a y b en paralelo y devuelve a + b , sí.
Sin embargo, el pseq asegura que tanto a como b sean evaluados antes de que a + b sea.
Vea este enlace para más detalles sobre ese tema.