multithreading haskell

multithreading - ¿Se necesitan grupos de hilos para el código Haskell puro?



(1)

El problema central, me imagino, es el lado de la red. Si tiene 10.000 enlaces y forkIO para cada enlace, entonces posiblemente tenga 10.000 sockets que está intentando abrir a la vez, lo que, dependiendo de cómo esté configurado su sistema operativo, probablemente ni siquiera será posible, mucho menos eficiente.

Sin embargo, el hecho de que tengamos hilos verdes que se programen "virtualmente" a través de múltiples subprocesos (que idealmente están pegados a núcleos individuales) no significa que podamos simplemente distribuir el trabajo aleatoriamente sin importar el uso de la CPU. El problema aquí no es tanto que la programación de la CPU en sí no sea manejada por nosotros, sino que los cambios de contexto (incluso los verdes) cuestan ciclos. Cada hilo, si está trabajando en datos diferentes, tendrá que extraer esos datos en la CPU. Si hay suficientes datos, eso significa introducir y sacar elementos de la memoria caché de la CPU. Incluso sin eso, significa extraer cosas de la memoria caché a registros, etc.

Incluso si un problema es trivialmente paralelo, virtualmente nunca es la idea correcta dividirlo lo más pequeño posible e intentar hacerlo "todo a la vez".

En Real World Haskell, Capítulo 28, Memoria transaccional de software , se desarrolla un comprobador de enlace web concurrente. Busca todos los enlaces en una página web y los golpea una vez con una solicitud HEAD para averiguar si el enlace está activo. Se toma un enfoque concurrente para construir este programa y se realiza la siguiente declaración:

No podemos simplemente crear un hilo por URL, ya que puede sobrecargar nuestra CPU o nuestra conexión de red si (como esperamos) la mayoría de los enlaces son en vivo y receptivos. En cambio, utilizamos un número fijo de subprocesos de trabajo, que obtienen URL para descargar de una cola.

No entiendo completamente por qué se necesita este grupo de subprocesos en lugar de usar forkIO para cada enlace. AFAIK, el tiempo de ejecución de Haskell mantiene un conjunto de hilos y los programa adecuadamente, así que no veo que la CPU esté sobrecargada. Además, en una discusión sobre concurrencia en la lista de correo de Haskell , encontré la siguiente declaración yendo en la misma dirección:

El único paradigma que no tiene sentido en Haskell son los hilos de trabajo (ya que el RTS lo hace por nosotros); en lugar de buscar un trabajador, simplemente forkIO en su lugar.

¿El conjunto de hilos solo es necesario para la parte de la red o hay un motivo de CPU para ello también?