una tipos solicita sistema reglas operativo manejo mac llamadas llamada interfaz como calls multithreading haskell concurrency garbage-collection ghc

multithreading - tipos - Cantidad excesiva de llamadas al sistema cuando se usa `threadDelay`



reglas de llamadas al sistema (0)

Estoy teniendo un par de procesos Haskell en producción en un sistema con 12 núcleos. Todos los procesos se compilan con -threaded y se ejecutan con 12 capacidades. Una biblioteca que todos usan es el grupo de resource-pool que mantiene un grupo de conexiones de bases de datos.

Lo interesante es que, aunque todos los procesos están prácticamente inactivos, consumen alrededor del 2% del tiempo de CPU. La inspección de uno de estos procesos con strace -p $(pgrep processname) -f revela que el proceso está realizando una cantidad irrazonable de llamadas al sistema, aunque en realidad no debería estar haciendo nada. Para poner las cosas en perspectiva:

  • Ejecutar strace en un proceso con -N2 durante 5 segundos produce un archivo de registro 66K.
  • Ejecutando con (irracional) -N64 produce un registro de 60 megabytes .

Entonces, el número de capacidades aumenta la cantidad de llamadas al sistema que se emiten drásticamente.

Profundizando más encontramos que el grupo de resource-pool está ejecutando un hilo de reaper que dispara cada segundo para inspeccionar si puede limpiar algunos recursos. Podemos simular el mismo comportamiento con este programa trivial.

module Main where import Control.Concurrent import Control.Monad (forever) main :: IO () main = forever $ do threadDelay (10 ^ 6)

Si paso -B al sistema de tiempo de ejecución recibo retroalimentación de audio cada vez que se emite un GC, que en este caso es cada 60 segundos.

Por lo tanto, cuando -I0 estos ciclos de GC al pasar -I0 al RTS ejecutando el comando strace en el proceso, solo se producen alrededor de strace archivos de registro de gran tamaño. Dado que el proceso también ejecuta un servidor scotty , GC se activa cuando entran solicitudes, por lo que parece que suceden cuando realmente las necesito.

Debido a que vamos a aumentar la cantidad de procesos de Haskell en esta máquina en una gran cantidad durante el curso del próximo año, me preguntaba cómo mantener su tiempo de inactividad a un nivel razonable. Aparentemente pasar- -I0 parece ser una idea bastante mala (?). Otra idea sería simplemente disminuir el número de capacidades de 12 a tal vez algo así como 4. ¿Hay alguna otra forma de ajustar el RTS para que pueda evitar que los procesos se quemen en muchos ciclos de la CPU mientras está en ralentí?