profiler - etiquetas - title html definicion
¿Cómo funcionan los perfiladores de código? (5)
Mientras trabajaba en un proyecto de la Universidad, utilicé un generador de perfiles interno del proyecto hecho por un alumno mayor, era muy básico pero lo suficientemente bueno ya que su tarea era restar tiempos entre dos puntos del código y dar estadísticas.
Ahora, ¿cómo funciona un perfilador profesional? ¿Preprocesa el código para insertar puntos de control o cosas así? ¿Lee el código binario con datos de depuración para detectar dónde se llama una función?
Gracias.
Como Jon Skeet escribió anteriormente, hay dos estrategias: instrumentación y muestreo.
La instrumentación se realiza tanto de forma manual como automática. En caso manual: el desarrollador inserta código manualmente para rastrear el inicio / final de una región de código de interés. Por ejemplo, un simple "StartTimer" y "EndTimer". Algunas herramientas de creación de perfiles también pueden hacer esto automáticamente; para ello, el generador de perfiles deberá realizar un análisis estático del código, es decir, analizará el código e identificará puntos de control importantes, como el inicio / finalización de un método en particular. Esto es más fácil con los lenguajes que admiten la reflexión (por ejemplo, cualquier lenguaje .net). Al usar ''reflexión'', el generador de perfiles puede reconstruir todo el árbol de códigos fuente (junto con los gráficos de llamadas).
La toma de muestras la realiza el generador de perfiles y examina el código binario. El generador de perfiles también puede utilizar técnicas como enganchar o atrapar eventos / mensajes de Windows con el fin de crear perfiles.
Tanto la instrumentación como los métodos de muestreo tienen sus propios gastos generales. La cantidad de sobrecarga depende, por ejemplo, si la frecuencia de muestreo se establece en valores altos, entonces el propio perfil puede contribuir significativamente al rendimiento que se informa.
Instrumentación Vs Muestreo: No es que uno sea mejor que el otro enfoque. Ambos tienen su lugar.
El mejor enfoque es comenzar con un generador de perfiles basado en muestras y observar todo el nivel del sistema. Eso es ejecutar la muestra y ver el uso de recursos de todo el sistema: memoria, disco duro, red, CPU.
De lo anterior, identifique los recursos que se están ahogando.
Con la información anterior, ahora puede agregar instrumentación a su código para identificar al culpable. Por ejemplo, si la memoria es el recurso más utilizado, ayudará a instrumentar el código relacionado con la asignación de memoria. Tenga en cuenta que con la instrumentación realmente se está concentrando en un área particular de su código.
Depende del tipo de código que se analiza, por ejemplo, .NET CLR proporciona la posibilidad de crear perfiles de código. Cuando se trata de código administrado, es posible reescribir el código intermedio para inyectar ganchos personalizados. También puedes analizar el seguimiento de la pila de las aplicaciones. El sistema operativo puede proporcionar medios para crear perfiles, por ejemplo, Windows tiene contadores de rendimiento . Al tratar con el código incrustado, puede emular / sustituir el hardware subyacente para monitorear efectivamente el rendimiento del sistema.
Hay dos estrategias de creación de perfiles comunes (para los lenguajes basados en VM de todos modos): instrumentación y muestreo.
La instrumentación inserta puntos de control e informa al generador de perfiles cada vez que se inicia y finaliza un método. Esto puede hacerlo el JIT / intérprete o una fase posterior a la compilación normal pero previa a la ejecución que simplemente cambia el ejecutable. Esto puede tener un efecto muy significativo en el rendimiento (lo que sesga los resultados de sincronización). Sin embargo, es bueno para obtener recuentos precisos.
El muestreo le pregunta a la VM periódicamente cómo se ve el seguimiento de la pila para todos los subprocesos y actualiza sus estadísticas de esa manera. Esto generalmente afecta el rendimiento menos, pero produce recuentos de llamadas menos precisas.
Hay muchos perfiles diferentes que funcionan de diferentes maneras.
Los perfiladores de uso común simplemente examinan el programa en ejecución regularmente para ver qué instrucción de ensamblaje se está ejecutando actualmente (el contador del programa) y qué rutinas llaman la función actual (la pila de llamadas). Este tipo de generador de perfiles de muestreo puede funcionar con archivos binarios estándar, pero son más útiles si tiene símbolos de depuración para resolver las líneas de las direcciones dadas por el código en el programa.
Además de muestrear regularmente, también puede usar los contadores de rendimiento del procesador para muestrear después de una cierta cantidad de eventos, como fallas en la caché, que le ayudarán a ver qué partes de su programa se están desacelerando debido a los accesos a la memoria.
Otros perfiladores implican recompilar el programa para insertar instrucciones (conocidas como instrumentación ) para contar con qué frecuencia se ejecuta cada conjunto continuo de instrucciones (bloques básicos), o incluso registrar la secuencia en la que se ejecutan los bloques básicos, o registrar el contenido de variables en ciertos lugares.
El enfoque de instrumentación puede brindarle toda la precisión y los datos que pueda desear, pero ralentizará el programa y eso cambiará sus características de rendimiento. Por el contrario, con los enfoques basados en el muestreo, puede ajustar el impacto en el rendimiento en función del tiempo que necesita para ejecutar el programa en comparación con la precisión de los datos de perfil que obtiene.
para gprof en * nix, en el tiempo de compilación y enlace usando el -pg, se inyecta un código adicional en el código del objeto. Luego, al ejecutar gprof, el código inyectado genera un archivo de informe.