linux performance optimization computer-architecture cpu-architecture

linux - ¿Qué son estanlled-cycles-frontend y estanlled-cycles-backend en el resultado ''perf stat''?



performance optimization (4)

¿Alguien sabe cuál es el significado de estancado-ciclos-frontend y estancado-ciclos-backend en el resultado de la estadística? Busqué en Internet pero no encontré la respuesta. Gracias

$ sudo perf stat ls Performance counter stats for ''ls'': 0.602144 task-clock # 0.762 CPUs utilized 0 context-switches # 0.000 K/sec 0 CPU-migrations # 0.000 K/sec 236 page-faults # 0.392 M/sec 768956 cycles # 1.277 GHz 962999 stalled-cycles-frontend # 125.23% frontend cycles idle 634360 stalled-cycles-backend # 82.50% backend cycles idle 890060 instructions # 1.16 insns per cycle # 1.08 stalled cycles per insn 179378 branches # 297.899 M/sec 9362 branch-misses # 5.22% of all branches [48.33%] 0.000790562 seconds time elapsed


De acuerdo con el autor de estos eventos, se definieron de forma general y se aproximan por los contadores de rendimiento de la CPU disponibles. Como sé, perf no admite fórmulas para calcular algún evento sintético basado en varios eventos de hardware, por lo que no puede usar el método de conexión front-end / back-end desde el manual de optimización de Intel (implementado en VTune) intel.com/content/dam/www/public/us/en/documents/manuals/… "B.3.2 Metodología jerárquica de caracterización de rendimiento de arriba hacia abajo"

%FE_Bound = 100 * (IDQ_UOPS_NOT_DELIVERED.CORE / N ); %Bad_Speculation = 100 * ( (UOPS_ISSUED.ANY – UOPS_RETIRED.RETIRE_SLOTS + 4 * INT_MISC.RECOVERY_CYCLES ) / N) ; %Retiring = 100 * ( UOPS_RETIRED.RETIRE_SLOTS/ N) ; %BE_Bound = 100 * (1 – (FE_Bound + Retiring + Bad_Speculation) ) ; N = 4*CPU_CLK_UNHALTED.THREAD" (for SandyBridge)

Las fórmulas correctas se pueden utilizar con algunos scripts externos, como se hizo en las herramientas pmu de Andi Kleen ( toplev.py ): https://github.com/andikleen/pmu-tools (fuente), http://halobates.de/blog/p/262 (descripción):

% toplev.py -d -l2 numademo 100M stream ... perf stat --log-fd 4 -x, -e {r3079,r19c,r10401c3,r100030d,rc5,r10e,cycles,r400019c,r2c2,instructions} {r15e,r60006a3,r30001b1,r40004a3,r8a2,r10001b1,cycles} numademo 100M stream ... BE Backend Bound: 72.03% This category reflects slots where no uops are being delivered due to a lack of required resources for accepting more uops in the Backend of the pipeline. ..... FE Frontend Bound: 54.07% This category reflects slots where the Frontend of the processor undersupplies its Backend.

Commit que introdujo los ciclos de stalled-cycles-frontend y stalled-cycles-backend en lugar de los ciclos de espera universal original:

http://git.kernel.org/cgit/linux/kernel/git/tip/tip.git/commit/?id=8f62242246351b5a4bc0c1f00c0c7003edea128a

author Ingo Molnar <mingo@el...> 2011-04-29 11:19:47 (GMT) committer Ingo Molnar <mingo@el...> 2011-04-29 12:23:58 (GMT) commit 8f62242246351b5a4bc0c1f00c0c7003edea128a (patch) tree 9021c99956e0f9dc64655aaa4309c0f0fdb055c9 parent ede70290046043b2638204cab55e26ea1d0c6cd9 (diff)

eventos de rendimiento: Agregue definiciones genéricas de eventos de ciclo de front-end y back-end Agregue dos eventos de hardware genéricos: ciclos de entrada y salida.

Estos eventos miden las condiciones cuando la CPU está ejecutando el código, pero sus capacidades no se utilizan por completo. Comprender tales situaciones y analizarlas es una subtarea importante de los flujos de trabajo de optimización de código.

Ambos eventos limitan el rendimiento: la mayoría de los puestos de front-end tienden a ser causados ​​por errores de predicción de sucursales o cachemises de recuperación de instrucciones, los puestos de backend pueden ser causados ​​por la escasez de recursos o la programación ineficiente de instrucciones.

Las paradas de front-end son las más importantes: el código no puede ejecutarse rápidamente si la secuencia de instrucciones no se mantiene.

Un back-end sobreutilizado puede causar paradas en el front-end y, por lo tanto, debe vigilarse también.

La composición exacta es muy lógica de programa y depende de la combinación de instrucciones.

Usamos los términos ''puesto'', ''front-end'' y ''back-end'' sin apretar e intentamos utilizar los mejores eventos disponibles de CPU específicas que se aproximan a estos conceptos.

Cc: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Frederic Weisbecker Enlace: http://lkml.kernel.org/n/[email protected] Firmado por: Ingo Molnar

/* Install the stalled-cycles event: UOPS_EXECUTED.CORE_ACTIVE_CYCLES,c=1,i=1 */ - intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES] = 0x1803fb1; + intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = 0x1803fb1; - PERF_COUNT_HW_STALLED_CYCLES = 7, + PERF_COUNT_HW_STALLED_CYCLES_FRONTEND = 7, + PERF_COUNT_HW_STALLED_CYCLES_BACKEND = 8,


Para convertir eventos genéricos exportados por perf en los eventos sin procesar de la documentación de la CPU, puede ejecutarlos:

more /sys/bus/event_source/devices/cpu/events/stalled-cycles-frontend

Le mostrará algo así como

event=0x0e,umask=0x01,inv,cmask=0x01

De acuerdo con la documentación de Intel SDM volumen 3B (tengo un Core i5-2520):

UOPS_ISSUED.ANY:

  • Incrementa cada ciclo el número de Uops emitidos por la RAT a RS.
  • Establezca Cmask = 1, Inv = 1, Any = 1 para contar los ciclos estancados de este núcleo.

Para el evento stalled-cycles-backend traducido a event = 0xb1, umask = 0x01 en mi sistema, la misma documentación dice:

UOPS_DISPATCHED.THREAD:

  • Cuenta el número total de uops que se enviarán por cada ciclo
  • Configure Cmask = 1, INV = 1 para contar los ciclos de bloqueo.

Por lo general, los ciclos estancados son ciclos en los que el procesador está esperando algo (la memoria se alimentará después de ejecutar una operación de carga, por ejemplo) y no tiene otras cosas que hacer. Además, la parte frontal de la CPU es la pieza de hardware responsable de buscar y descodificar las instrucciones (convertirlas a UOP) mientras que la parte de fondo es responsable de ejecutar de manera efectiva los UOP.


Un ciclo de CPU se "detiene" cuando la tubería no avanza durante el mismo.

El pipeline del procesador se compone de muchas etapas: el front-end es un grupo de estas etapas que es responsable de las fases de captación y decodificación, mientras que el back-end ejecuta las instrucciones. Hay un búfer entre el front-end y el back-end, por lo que cuando el primero está estancado, el último todavía puede tener un trabajo por hacer.

Tomado de http://paolobernardi.wordpress.com/2012/08/07/playing-around-with-perf/


La teoría:

Comencemos por esto: las CPU de hoy en día son superescalares, lo que significa que pueden ejecutar más de una instrucción por ciclo (IPC). Las últimas arquitecturas Intel pueden ir hasta 4 IPC (4 decodificadores de instrucciones x86). No traigamos la macro / micro fusión a la discusión para complicar más las cosas :).

Normalmente, las cargas de trabajo no llegan a IPC = 4 debido a diversas contenciones de recursos. Esto significa que la CPU está perdiendo ciclos (el software proporciona el número de instrucciones y la CPU debe ejecutarlos en el menor número posible de ciclos).

Podemos dividir los ciclos totales que usa la CPU en 3 categorías:

  1. Ciclos donde las instrucciones se retiran (trabajo útil)
  2. Ciclos que se gastan en el Back-End (desaprovechado)
  3. Ciclos gastados en el front-end (desperdiciados).

Para obtener un IPC de 4, el número de ciclos que se retiran debe estar cerca del número total de ciclos. Tenga en cuenta que en esta etapa, todas las microoperaciones (uOps) se retiran de la canalización y comprometen sus resultados en registros / cachés. En esta etapa, puede tener incluso más de 4 uOps retirados, porque este número viene dado por el número de puertos de ejecución. Si solo tienes el 25% de los ciclos retirando 4 uOps, entonces tendrás un IPC general de 1.

Los ciclos detenidos en el back-end son un desperdicio porque la CPU tiene que esperar recursos (generalmente memoria) o terminar largas instrucciones de latencia (por ejemplo, transcedentales - sqrt, reciprocals, divisiones, etc.).

Los ciclos detenidos en el front-end son un desperdicio porque eso significa que el Front-End no alimenta el Back End con microoperaciones. Esto puede significar que tiene errores en el caché de instrucciones o instrucciones complejas que no están ya descodificadas en el caché de microoperaciones. El código compilado justo a tiempo generalmente expresa este comportamiento.

Otra razón de pérdida es la omisión de predicción de rama. Eso se llama mala especulación. En ese caso, se emiten uOps, pero se descartan porque el BP predijo el error.

La implementación en profilers:

¿Cómo interpreta los ciclos de BE y FE estancados?

Los diferentes perfiladores tienen diferentes enfoques en estas métricas. En vTune, las categorías 1 a 3 se suman para dar el 100% de los ciclos. Eso se ve razonable porque o bien tiene su CPU estancada (no se están retirando uOps) o bien realiza un trabajo útil (uOps) retirarse. Vea más aquí: https://software.intel.com/sites/products/documentation/doclib/stdxe/2013SP1/amplifierxe/snb/index.htm

En perf, esto generalmente no sucede. Eso es un problema porque cuando ve un 125% de ciclos estancados en el frente , no sabe cómo interpretar esto realmente. Puede vincular la métrica> 1 con el hecho de que hay 4 decodificadores, pero si continúa el razonamiento, entonces la IPC no coincidirá.

Aún mejor, no sabes cuán grande es el problema. 125% de qué? ¿Qué significan los #cycles entonces?

Personalmente parezco un poco sospechoso en los ciclos de BE y FE estancados de perf y espero que esto se solucione.

Probablemente obtendremos la respuesta final depurando el código desde aquí: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/tools/perf/builtin-stat.c