performance - ¿Cómo correlaciona los contadores un amplio sistema(por ejemplo, perf) con las instrucciones?
optimization linux-kernel (2)
Estoy tratando de entender cómo funciona un generador de perfiles de todo el sistema. Tomemos el perf de linux como ejemplo. Para un cierto tiempo de creación de perfiles, puede proporcionar:
- Varios contadores de rendimiento de hadware agregados
- Tiempo empleado y contadores de hardware (por ejemplo, #instrucciones) para cada proceso de espacio de usuario y función de espacio del núcleo
- Información sobre los interruptores de contexto
- etc.
Lo primero de lo que estoy casi seguro es que el informe es solo una estimación de lo que realmente está sucediendo. Entonces, creo que hay algún módulo kernel que lanza interrupciones de software a una cierta tasa de muestreo . Cuanto menor sea la tasa de muestreo, menor será la sobrecarga del perfilador. La interrupción puede leer los registros específicos del modelo que almacenan los contadores de rendimiento.
La siguiente parte es correlacionar los contadores con el software que se ejecuta en la máquina. Esa es la parte que no entiendo .
Entonces, ¿de dónde obtiene el profiler sus datos?
¿Puedes interrogar, por ejemplo, al programador de tareas para averiguar qué se estaba ejecutando cuando lo interrumpiste? ¿Eso no afectará la ejecución del planificador (por ejemplo, en lugar de continuar con la función interrumpida, solo programará otra, haciendo que el resultado del perfilador no sea exacto). ¿Está disponible la lista de objetos task_struct ?
- ¿Cómo pueden los profilers correlacionar las métricas HW incluso a nivel de instrucción?
Esto es más o menos responde a las tres preguntas.
Perfiles de dos tipos: recuento y muestreo. El recuento mide el número total de eventos durante toda la ejecución sin ofrecer ninguna información sobre las instrucciones o funciones que los generaron. Por otro lado, el muestreo proporciona una correlación de los eventos con el código a través de muestras capturadas del Puntero de Instrucción. Al muestrear, el kernel instruye al procesador para que emita una interrupción cuando un contador de eventos elegido excede un umbral. T su interrupción es capturada por el núcleo y los datos muestreados, incluido el valor del Puntero de Instrucción, se almacenan en un búfer en anillo. El buffer es consultado periódicamente por la herramienta de perfusión del espacio de usuario y su contenido escrito en el disco. En el procesamiento posterior, el puntero de instrucción se combina con direcciones en archivos binarios, que se pueden traducir en nombres de funciones y tales
Entonces, creo que hay algún módulo kernel que lanza interrupciones de software a una cierta tasa de muestreo.
Perf no es un módulo, es parte del kernel de Linux, implementado en kernel / events / core.c y para cada arquitectura soportada y modelo de CPU, por ejemplo arch / x86 / kernel / cpu / perf_event * .c . Pero Oprofile era un módulo con un enfoque similar.
El rendimiento generalmente funciona pidiendo a la UGP (unidad de monitorización del rendimiento) de la CPU que genere interrupción después de N eventos de algún contador de rendimiento de hardware ( Yokohama, diapositiva 5 ". • Interrupción cuando se alcanza el umbral: permite el muestreo "). En realidad, se puede implementar como:
- seleccione un contador de PMU
- inicialízalo en
-N
, donde N es el período de muestreo (queremos interrupción después de N eventos, por ejemplo, después de 2 millones de ciclos deperf record -c 2000000 -e cycles
, o algo de N calculado y ajustado por perf cuando no hay opción adicional se establece o-F
) - configure este contador para el evento deseado y solicite a PMU que genere interrupción en el desbordamiento (ARCH_PERFMON_EVENTSEL_INT). Sucederá después de N incrementos de nuestro contador.
Todos los chips Intel modernos son compatibles con esto, por ejemplo, Nehalem: https://software.intel.com/sites/default/files/76/87/30320 - Nehalem Performance Monitoring Unit Guía de programación
EBS - Muestreo basado en eventos. Una técnica en la que los contadores están precargados con un recuento negativo grande, y están configurados para interrumpir el procesador en caso de desbordamiento. Cuando el contador desborda la rutina de servicio de interrupción, captura los datos de perfil.
Entonces, cuando usa la PMU de hardware, no hay trabajo adicional en la interrupción del temporizador con lectura especial de los contadores de PMU de hardware. Existe algún trabajo para guardar / restablecer el estado de PMU en el cambio de tarea, pero esto ( *_sched_in
/ *_sched_out
de kernel / events / core.c) no cambiará el valor del contador de PMU ni lo exportará al espacio de usuario.
Hay un manejador: arch/x86/kernel/cpu/perf_event.c: x86_pmu_handle_irq
que encuentra el contador desbordado y llama a perf_sample_data_init(&data, 0, event->hw.last_period);
para registrar la hora actual, IP del último comando ejecutado (puede ser inexacto debido a la naturaleza fuera de orden de la mayoría de las microarquitecturas Intel, existe una solución limitada para algunos eventos - PEBS, perf record -e cycles:pp
rendimiento perf record -e cycles:pp
), stacktrace ( si -g
se usó en el registro), etc. Entonces el manejador restablece el valor del contador a -N
(x86_perf_event_set_period, wrmsrl(hwc->event_base, (u64)(-left) & x86_pmu.cntval_mask);
- tenga en cuenta el signo menos antes de la left
)
Cuanto menor sea la tasa de muestreo, menor será la sobrecarga del perfilador.
Perf le permite establecer la tasa de muestreo objetivo con la opción -F 1000
, -F 1000
significa alrededor de 1000 irq / s. No se recomiendan altas tasas debido a la alta sobrecarga. Hace diez años, Intel VTune no recomendó más de 1000 irq / s (www.cs.utah.edu/~mhall/cs4961f09/VTune-1.pdf " Intenta obtener aproximadamente 1000 muestras por segundo por CPU lógica "), perf por lo general, no permite una tasa alta para no raíz (autoajustada a una tasa menor cuando "la interrupción de perfunción tomó demasiado tiempo" - revise su dmesg; también revise sysctl -a|grep perf
, por ejemplo kernel.perf_cpu_time_max_percent=25
- lo que significa ese rendimiento intentará usar no más del 25% de la CPU)
¿Puedes interrogar, por ejemplo, al programador de tareas para averiguar qué se estaba ejecutando cuando lo interrumpiste?
No. Pero puede habilitar el punto de rastreo en sched_switch u otro evento de sched (haga una lista de todos los disponibles en sched: perf list ''sched:*''
), y úselo como un evento de generación de perfiles para el perf. Incluso puede pedirle a perf para que registre stacktrace en este punto de rastreo:
perf record -a -g -e "sched:sched_switch" sleep 10
¿Eso no afectará la ejecución del planificador?
El punto de rastreo habilitado hará que se agregue algo de muestreo de evento de perforación a la función con punto de rastreo
¿Está disponible la lista de objetos task_struct? Solo a través de ftrace ...
Información sobre los interruptores de contexto
Este es un evento de perf de software, solo llame a perf_sw_event
con el evento PERF_COUNT_SW_CONTEXT_SWITCHES
de sched / core.c (indirectamente). Ejemplo de evento de software de migración de llamada directa: kernel / sched / core.c set_task_cpu () : p->se.nr_migrations++; perf_sw_event(PERF_COUNT_SW_CPU_MIGRATIONS, 1, NULL, 0);
p->se.nr_migrations++; perf_sw_event(PERF_COUNT_SW_CPU_MIGRATIONS, 1, NULL, 0);
PD: hay buenas diapositivas en perfg, ftrace y otros subsistemas de perfilado y rastreo en Linux por Gregg: http://www.brendangregg.com/linuxperf.html