Perfilación
# Perfilación

La recopilación de información sobre el comportamiento de un programa, específicamente su uso de recursos, se denomina perfilación (del término en inglés: profiling). El recurso más importante en términos de computación de alto rendimiento es el tiempo de ejecución.

Una estrategia común de creación de perfiles es averiguar cuánto tiempo se le dedica a las diferentes funciones, y tal vez incluso a las líneas, de un código para identificar los puntos calientes, es decir, las partes del programa que requieren la fracción dominante de tiempo de ejecución. Estos puntos calientes se analizan posteriormente en busca de posibles oportunidades de optimización.

En todos los procesadores actuales se permite conocer, en profundidad, el uso de recursos dentro del chip y el sistema; de hecho, existen circunstancias en las que ya no se puede hacer nada para acelerar más un código de serie y es fundamental que, el usuario, pueda identificar el punto en el que los esfuerzos de optimización adicionales no son útiles.

## Perfilado en tiempo de ejecución basado en funciones y líneas

En general, se utilizan dos tecnologías para la creación de perfiles basados ​​en funciones y líneas:

* Instrumentación de código: La instrumentación funciona permitiendo que el compilador modifique cada llamada de función, insertando algún código que registre la llamada, su llamador (o la pila de llamadas completa) y probablemente cuanto tiempo requirió. Esta técnica en curso conlleva una sobrecarga significativa, especialmente si el código contiene muchas funciones con un tiempo de ejecución corto. El código de instrumentación intentará compensar eso, pero siempre hay cierta incertidumbre residual.
* Muestreo de código: El muestreo es menos invasivo, pues el programa se interrumpe a intervalos periódicos, por ejemplo, 10 milisegundos, y se registra el contador del programa (y posiblemente la pila de llamadas actual). Necesariamente, este proceso es estadístico por naturaleza, pero cuanto más se ejecute el código, más precisos serán los resultados.

Si el compilador ha equipado el código objeto con la información adecuada, el muestreo puede entregar información sobre el tiempo de ejecución hasta la línea fuente e incluso el nivel del código de la máquina.

La instrumentación está necesariamente limitada a funciones o bloques básicos (código con una entrada y un punto de salida sin llamadas ni saltos intermedios) por razones de eficiencia.

### Perfilado de funciones

El perfil plano contiene información sobre los tiempos de ejecución de todas las funciones del programa y la frecuencia con la que se llamaron. Por cada función hay una fila con los datos correspondientes.

Estos datos pueden ser:

* Porcentaje de tiempo: Porcentaje de todo el tiempo de ejecución usado exclusivamente para esa función, es decir, no toma en cuenta ninguna de sus llamadas.
* Segundos acumulados: Suma acumulativa de tiempos de ejecución exclusivos de todas las funciones (inclusive).
* Segundos de la función: Número de segundos utilizados por esta función (exclusivo). De forma predeterminada, la lista está ordenada según este campo.
* Llamadas: Veces que la función fue llamada.
* Milisegundos por llamada de la función: Cantidad promedio de los milisegundos por llamada (exclusivo).
* Milisegundos por llamada totales. Cantidad promedio de los milisegundos por llamada que se gastaron por la función, incluyendo sus llamadas (inclusivo).

Aunque el perfil plano contiene bastante información, no dice cómo la contribución del tiempo de ejecución de una cierta función está compuesta por varios llamadores diferentes, qué otras funciones (llamadas) se llaman desde él ni qué contribución al tiempo de ejecución incurren a su vez. Estos datos son proporcionados por el gráfico de mariposa o el perfil de gráfico de llamadas.

Cada sección del gráfico de llamadas pertenece exactamente a una función, que se enumera junto con un índice en ejecución (extremo izquierdo). Las funciones enumeradas arriba de esta línea son las personas que llaman a la función actual, mientras que las que se enumeran a continuación son sus destinatarios. Las llamadas recursivas se contabilizan.

Los campos son:

* Porcentaje de tiempo: El porcentaje de todo el tiempo de ejecución gastado en una función, incluido sus llamadas (tiempo inclusivo). Esto debe ser idéntico al producto del número de llamadas con el tiempo por llamada en el perfil plano.
* La función misma: Para cada función indexada, es el tiempo de ejecución exclusivo (idéntico al del perfil plano). Para sus llamadas, denota el tiempo inclusivo esta función (cada calle) contribuido a cada llamador (esta función).
* Hijos: Para cada función indexada, esto es inclusivo menos el tiempo de ejecución exclusivo, es decir, la contribución de todos sus destinatarios al tiempo inclusivo. Parte de este tiempo contribuye al tiempo de ejecución inclusivo de cada uno de los llamadores de la función y se indica en las respectivas filas de llamadores. Las filas de los destinatarios de esta columna designan la contribución de los destinatarios de cada destinatario al tiempo de ejecución inclusivo de la función.
* Llamado: Indica el número de veces que la función fue llamada (probablemente dividida en contribuciones recursivas más contribuciones no recursivas. La fracción de la cantidad de llamadas provenientes de cada llamador que llama se muestra en la fila de la función que llama, mientras que la fracción de llamadas para cada llamada que se inició desde esta función se puede encontrar en las filas de la función que llama.

Existen herramientas que pueden representar el perfil de la mariposa de forma gráfica, lo que permite navegar por el árbol de llamadas y encontrar rápidamente la ”ruta crítica”, es decir, la secuencia de funciones (desde la raíz hasta alguna hoja) que muestra las contribuciones inclusivas dominantes por todos sus elementos.

### Perfilado basado en líneas

Si la zona activa en tales funciones no se puede encontrar, se deben utilizar herramientas para la creación de perfiles basados en líneas.

Con un perfilado basado en líneas, el usuario puede extraer información sobre un binario específico. Entre otras cosas, puede ser una lista de fuentes anotada en la que cada línea de fuente, acompañada por el número de resultados de muestreo (primera columna) y el porcentaje relativo del total de muestras de programas (segunda columna).

