¿Alguien sabe cuál es el significado de los ciclos estancados frontend y los ciclos estancados backend en el resultado de la estadística de rendimiento? 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
Respuestas:
La teoría:
Empecemos 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 de Intel pueden llegar hasta 4 IPC (4 decodificadores de instrucciones x86). No pongamos en discusión macro / micro fusión para complicar más las cosas :).
Normalmente, las cargas de trabajo no alcanzan IPC = 4 debido a diversas disputas por recursos. Esto significa que la CPU está desperdiciando ciclos (la cantidad de instrucciones las da el software y la CPU tiene que ejecutarlas en el menor número de ciclos posible).
Podemos dividir los ciclos totales que gasta la CPU en 3 categorías:
Para obtener un IPC de 4, el número de ciclos que se retiran tiene que estar cerca del número total de ciclos. Tenga en cuenta que en esta etapa, todas las microoperaciones (uOps) se retiran del pipeline y comprometen sus resultados en registros / cachés. En esta etapa, puede tener incluso más de 4 uOps retirándose, porque este número viene dado por el número de puertos de ejecución. Si solo tiene el 25% de los ciclos retirando 4 uOps, entonces tendrá un IPC general de 1.
Los ciclos estancados en el back-end son un desperdicio porque la CPU tiene que esperar recursos (generalmente memoria) o terminar instrucciones de latencia larga (por ejemplo, transcedentals - sqrt, recíprocos, divisiones, etc.).
Los ciclos estancados en el front-end son un desperdicio porque eso significa que el Front-End no alimenta al Back End con microoperaciones. Esto puede significar que tiene errores en la caché de instrucciones o instrucciones complejas que aún no están decodificadas en la caché de microoperaciones. El código compilado justo a tiempo generalmente expresa este comportamiento.
Otro motivo de estancamiento es el error de predicción de rama. Eso se llama mala especulación. En ese caso, se emiten uOps pero se descartan porque el BP predijo mal.
La implementación en perfiladores:
¿Cómo interpretas los ciclos estancados BE y FE?
Diferentes perfiladores tienen diferentes enfoques sobre estas métricas. En vTune, las categorías 1 a 3 se suman para dar el 100% de los ciclos. Eso parece razonable porque o tiene su CPU estancada (no se están retirando uOps) o realiza un trabajo útil (uOps) retirándose. Vea más aquí: https://software.intel.com/sites/products/documentation/doclib/stdxe/2013SP1/amplifierxe/snb/index.htm
En perf, esto no suele suceder. Eso es un problema porque cuando ves 125% de ciclos estancados en la parte delantera , no sabes cómo interpretar esto realmente. Puede vincular la métrica> 1 con el hecho de que hay 4 decodificadores, pero si continúa con el razonamiento, el IPC no coincidirá.
Aún mejor, no sabes qué tan grande es el problema. 125% de qué? Entonces, ¿qué significan los #ciclos?
Personalmente, parezco un poco sospechoso sobre los ciclos estancados BE y FE 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
fuente
Para convertir eventos genéricos exportados por perf en los eventos sin procesar de la documentación de su CPU, puede ejecutar:
Te mostrará algo como
De acuerdo con la documentación de Intel SDM volumen 3B (tengo un núcleo i5-2520):
UOPS_ISSUED.ANY:
Para el evento de backend de ciclos estancados que se traduce en event = 0xb1, umask = 0x01 en mi sistema, la misma documentación dice:
UOPS_DISPATCHED.THREAD:
Por lo general, los ciclos detenidos son ciclos en los que el procesador está esperando algo (la memoria se alimenta 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 obtener y decodificar las instrucciones (convertirlas en UOP), mientras que la parte de backend es responsable de ejecutar eficazmente las UOP.
fuente
Un ciclo de CPU se "detiene" cuando la canalización no avanza durante él.
La tubería del procesador se compone de muchas etapas: el front-end es un grupo de estas etapas que es responsable de las fases de recuperació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 se detiene, el segundo aún puede tener algo de trabajo por hacer.
Tomado de http://paolobernardi.wordpress.com/2012/08/07/playing-around-with-perf/
fuente
Según el autor de estos eventos, se definieron libremente y se aproximan por los contadores de rendimiento de 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 bloqueo de front-end / back-end del manual de optimización de Intel (implementado en VTune) http: // www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-optimization-manual.pdf "B.3.2 Metodología jerárquica de caracterización del rendimiento de arriba hacia abajo"
Las fórmulas correctas se pueden usar con algunas secuencias de comandos externas, como se hizo en pmu-tools (
toplev.py
) de Andi Kleen : https://github.com/andikleen/pmu-tools (fuente), http://halobates.de/blog/ p / 262 (descripción):Compromiso que introdujo eventos de parada de ciclos de interfaz y de ciclos de parada de fondo en lugar del universal original
stalled-cycles
:http://git.kernel.org/cgit/linux/kernel/git/tip/tip.git/commit/?id=8f62242246351b5a4bc0c1f00c0c7003edea128a
fuente
perf stat
con FE> 100% como para toplev.py? Acabo de comenzar con bucles simples y cortos y tengo ciclos 3G para instrucciones 3G (1G son ramas con una tasa de falla del 0.00%) con paradas 2G FE (perf stat
) y 1G BE paradas (IPC = 1.00). Creo que el problema es definir correctamente "parada" para el núcleo complejo de OOO y otro es interpretar correctamente lostoplev.py
resultados.