es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Reduciendo el tiempo JIT con llamadas recursivas en Julia

Tengo una función recursiva que opera un árbol binario de enteros, implementado como un par anidado de pares o enteros. Mi función crea un nuevo árbol con una estructura diferente y se llama a sí misma recursivamente hasta que se cumple alguna condición. El problema que encuentro es que la primera vez que se ejecuta el código, tarda mucho tiempo en compilar JIT todas las posibles firmas de la función; después de eso, se ejecuta bien.

Aquí hay un ejemplo mínimo de trabajo:

mi_arbol = ((((6 => 7) => (6 => 7)) => ((7 => 7) => (0 => 7))) => (((8 => 7) => (7 => 7)) => ((8 => 8) => (8 => 0)))) => ((((2 => 4) => 7) => (6 => (0 => 5))) => (((6 => 8) => (2 => 8)) => ((2 => 1) => (4 => 5))))

function reducir_arbol(arbol::Pair)
    izquierda, derecha = arbol
    izquierda isa Pair && (izquierda = reducir_arbol(izquierda))
    derecha isa Pair && (derecha = reducir_arbol(derecha))
    return izquierda + derecha
end

@show mi_arbol
@show reducir_arbol(mi_arbol)

using MethodAnalysis
metodos = methodinstances(reducir_arbol)
@show length(metodos)

Aunque este ejemplo no es perceptiblemente lento, aún genera 9 instancias de métodos para:

reducir_arbol(::Pair{Pair{Pair{Int64, Int64}, Pair{Int64, Int64}}, Pair{Pair{Int64, Int64}, Pair{Int64, Int64}}}})
reducir_arbol(::Pair{Pair{Int64, Int64}, Pair{Int64, Int64}})
reducir_arbol(::Pair{Int64, Int64})
reducir_arbol(::Pair{Pair{Pair{Pair{Int64, Int64}, Int64}, Pair{Int64, Pair{Int64, Int64}}}, Pair{Pair{Pair{Int64, Int64}, Pair{Int64, Int64}}, Pair{Pair{Int64, Int64}, Pair{Int64, Int64}}}})
etc ...

¿Hay alguna forma de evitar esto / precompilar / acelerar / escribir una función genérica / ejecutar una parte particular (de) una función en modo interpretado? Estaría dispuesto a hacer que el rendimiento general del código sea ligeramente peor a cambio de que se ejecute más rápido en la primera llamada de nivel superior a reducir_arbol.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Una forma de acelerar el tiempo de compilación inicial de tree_reduce es tipificar explícitamente los argumentos en la firma de la función. Esto ayudará al compilador a generar instancias de métodos específicos para la función, en lugar de intentar compilar para todos los posibles tipos de argumentos.

    Por ejemplo, en lugar de definir la función como function tree_reduce(tree::Pair), puedes especificarla de manera más específica como function tree_reduce(tree::Pair{Pair{Int64, Int64}, Pair{Int64, Int64}}). Esto generará una instancia de método para este tipo específico de entrada, en lugar de intentar compilar para todos los tipos de Pair.

    Otra opción es utilizar la macro @code_warntype para identificar cualquier inestabilidad de tipo en la función que pueda estar causando tiempos de compilación más lentos. Esto puede ayudar a optimizar la función y acelerar la compilación.

    Finalmente, puedes usar la macro @interpreter para ejecutar partes específicas de la función en modo interpretado. Esto puede ser útil para pruebas y depuración, pero no necesariamente acelerará el tiempo de compilación.

    En general, optimizar la función y tipificar explícitamente los argumentos pueden ayudar a acelerar el tiempo de compilación de tree_reduce. Sin embargo, es importante equilibrar el rendimiento con la legibilidad y mantenibilidad del código.

Comments are closed.