haskell optimization ghc

haskell - Desventajas de usar pragma INLINABLE



optimization ghc (1)

Estoy haciendo esta pregunta con la esperanza de refinar la respuesta que Simon Marlow dio a una pregunta anterior sobre INLINABLE , enlazada aquí:

¿Hay alguna razón para no usar el pragma INLINABLE para una función?

Me doy cuenta de que esto es casi un duplicado de esa pregunta, excepto que Simon Marlow no respondió la pregunta clave que más le interesa a muchos autores de bibliotecas: ¿es seguro desde una perspectiva puramente de rendimiento simplemente agregar INLINABLE INLINABLES a todo?

Por lo que puedo decir, las únicas desventajas son:

  • Tiempos de compilación más lentos

  • Archivos de interfaz más grandes (es decir, *.hi )

Pero lo que realmente quiero saber es si el código se ejecutará más lentamente como resultado de agregar INLINABLE INLINABLES. En otras palabras, ¿puede un pragma INLINABLE hacer que GHC elija una optimización menos óptima?

La razón por la que pregunto es que a muchos autores de bibliotecas, incluido yo mismo, no les importa el tamaño de los archivos de interfaz y no observamos una ralentización significativa en la compilación al agregar INLINABLE INLINABLES, por lo que es tentador simplemente agregarlos por reflejo a todos lados, ya que Parece que no hay costo para hacerlo.

A la inversa, el costo de omitirlos es que cuando los módulos se vuelven muy grandes, los ghc comienzan a omitir selectivamente algunas funciones del archivo de interfaz para ahorrar espacio, lo que a veces produce peores optimizaciones, y es muy difícil predecir en qué punto ocurrirá esto. y qué funciones omitirá.

Personalmente nunca he presenciado una función que se ejecute más lentamente como resultado de una anotación INLINABLE , pero eso podría deberse por completo a la suerte. Si hay casos en los que INLINABLE ralentiza las cosas, me gustaría saber por qué lo hace para poder razonar mejor cuándo agregar el pragma en lugar de realizar una tediosa evaluación comparativa de cada permutación de los pragmas del compilador.


No estoy seguro si esto califica como una perspectiva puramente funcional, y seguramente no es la respuesta completa a su pregunta, pero es un poco.

Desde un punto o vista de administración del sistema, hacer que todo sea INLINABLE significa que cada pequeño cambio en cualquier función hace que la interfaz cambie, y obtiene un nuevo identificador de paquete y necesita recompilar todo según este módulo.

Esto está, por ejemplo, causando problemas en las distribuciones: Intentamos realizar copias de seguridad de los arreglos de seguridad para empaquetar en Debian estable. Si la solución no cambia el ABI, simplemente podemos actualizar un paquete (y reconstruir todos los programas construidos estáticamente). Si cambia el ABI, es posible que tengamos que reconstruir paquetes de dozends o más. Tales problemas hacen que Haskell se vea mal para aquellos que tienen que manejar los problemas, pero que no se preocupan por Haskell en particular.