test results multithreaded benchmarks benchmark performance benchmarking flops

performance - results - test cpu benchmark



¿Qué es FLOP/s y es una buena medida de rendimiento? (8)

Me han pedido que mida el rendimiento de un programa fortran que resuelve ecuaciones diferenciales en un sistema de varias CPU. Mi empleador insiste en que mida FLOP / s (operaciones flotantes por segundo) y compare los resultados con los puntos de referencia ( LINPACK ), pero no estoy convencido de que sea el camino a seguir, simplemente porque nadie puede explicarme qué es un FLOP.

Hice algunas investigaciones sobre qué es exactamente un FLOP y obtuve algunas respuestas bastante contradictorias. Una de las respuestas más populares que obtuve fue ''1 FLOP = Una operación de suma y multiplicación''. ¿Es eso cierto? Si es así, otra vez, físicamente, ¿qué significa eso exactamente?

Cualquier método que termine usando, tiene que ser escalable. Algunas versiones del código resuelven sistemas con millones de incógnitas y tardan días en ejecutarse.

¿Cuáles serían algunas otras maneras efectivas de medir el rendimiento en mi caso (el resumen de mi caso es ''código fortran que hace un montón de cálculos aritméticos una y otra vez durante días en varios cientos de CPU)?


"comparar los resultados con los puntos de referencia" y hacer qué?

FLOPS significa que necesitas

1) FLOPs por alguna unidad de trabajo.

2) tiempo para esa unidad de trabajo.

Digamos que tiene un archivo de entrada que hace 1,000 iteraciones a través de algún bucle. El ciclo es una unidad de trabajo útil. Se ejecuta 1,000 veces. Se tarda una hora.

El ciclo tiene algunas adiciones y multiplicaciones y algunas divisiones y una raíz cuadrada. Puede contar suma, multiplica y divide. Puede contar esto en la fuente, buscando +, * y /. Puede encontrar el resultado de ensamblador en lenguaje del compilador y contarlos allí también. Puede obtener diferentes números. ¿Cuál es la correcta? Pregúntele a su jefe

Puede contar las raíces cuadradas, pero no sabe lo que realmente hace en términos de multiplicaciones y agrega. Por lo tanto, tendrá que hacer algo como multiplicación de referencia vs. raíz cuadrada para tener una idea de cuánto tarda una raíz cuadrada.

Ahora conoces los FLOPS en tu ciclo. Y sabes el tiempo para ejecutarlo 1,000 veces. Usted sabe FLOPS por segundo.

Luego miras LINPACK y descubres que eres más lento. ¿Ahora que? Tu programa no es LINPACK, y es más lento que LINPACK. Las probabilidades son realmente buenas de que tu código sea más lento. A menos que su código se haya escrito y optimizado durante la misma cantidad de años que un LINPACK, será más lento.

Aquí está la otra parte. Su procesador tiene una calificación FLOPS definida contra varios puntos de referencia. Su algoritmo no es uno de esos puntos de referencia, por lo que no está a la altura de los puntos de referencia. ¿Es esto malo? ¿O es esta la consecuencia obvia de no ser un punto de referencia?

¿Cuál será el resultado procesable?

La medición con respecto a una base de código de referencia solo le indicará que su algoritmo no es el algoritmo de referencia. Es una conclusión inevitable que serás diferente; usualmente más lento.

Obviamente, el resultado de medir contra LINPACK será (a) usted es diferente y, por lo tanto, (b) necesita optimizar.

La medición solo es realmente valiosa cuando se hace contra usted mismo . No es una mezcla de instrucción hipotética, sino tu propia combinación de instrucciones. Mida su propio rendimiento. Hacer un cambio. Vea si su desempeño, en comparación con usted mismo, mejora o empeora.

Los FLOPS no importan. Lo que importa es el tiempo por unidad de trabajo. Nunca coincidirá con los parámetros de diseño de su hardware porque no está ejecutando el punto de referencia que los diseñadores de hardware esperaban.

LINPACK no importa. Lo que importa es su código base y los cambios que está realizando para cambiar el rendimiento.


A FLOPS es, como usted dijo, una operación de coma flotante por segundo. Como ejemplo, si toma exactamente un segundo para una operación (como sumar, restar, multiplicar o dividir dos valores y devolver el resultado), su rendimiento es simplemente 1 FLOPS. Una CPU reciente logrará fácilmente varios GigaFLOPS, es decir, varios miles de millones de operaciones de coma flotante por segundo.


Es una medida de rendimiento bastante buena, siempre y cuando comprenda exactamente lo que mide.

FLOPS es que, como el nombre implica OPerations de punto de combustión por segundo, lo que constituye un FLOP puede variar según la CPU. (Algunas CPU pueden realizar suma y multiplicación como una operación, otras no, por ejemplo). Eso significa que, como medida de rendimiento, está bastante cerca del hardware, lo que significa que 1) debe conocer su hardware para calcular los FLOPS ideales en la arquitectura dada, y debe conocer su algoritmo y su implementación para descubrir cómo muchas operaciones de punto flotante en las que realmente consiste.

En cualquier caso, es una herramienta útil para examinar qué tan bien utiliza la CPU. Si conoce el rendimiento máximo teórico de la CPU en FLOPS, puede calcular qué tan eficientemente utiliza las unidades de punto flotante de la CPU, que a menudo son una de las más difíciles de utilizar de manera eficiente. Un programa que ejecuta el 30% de los FLOPS de los que la CPU es capaz, tiene espacio para la optimización. Uno que funciona al 70% probablemente no será mucho más eficiente a menos que cambie el algoritmo básico. Para algoritmos matemáticos pesados ​​como el tuyo, esa es una forma bastante común de medir el rendimiento. Simplemente puedes medir cuánto tarda un programa en ejecutarse, pero eso varía enormemente dependiendo de la CPU. Pero si su programa tiene un 50% de utilización de la CPU (relativo al conteo máximo de FLOPS), ese es un valor algo más constante (aún variará entre arquitecturas de CPU radicalmente diferentes, pero es mucho más consistente que el tiempo de ejecución).

Pero sabiendo que "Mi CPU es capaz de X GFLOPS, y solo estoy logrando un rendimiento de, por ejemplo, 20% de eso" es información muy valiosa en software de alto rendimiento. Significa que algo que no sea ​​el punto flotante te está reteniendo y evitando que las unidades FP funcionen de manera eficiente. Y dado que las unidades FP constituyen la mayor parte del trabajo, eso significa que su software tiene un problema.

Es fácil medir "Mi programa se ejecuta en X minutos", y si crees que eso es inaceptable, entonces puedes ir "Me pregunto si puedo cortar un 30% de descuento", pero no sabes si eso es posible a menos que calcula exactamente cuánto trabajo se está haciendo y qué es exactamente lo que la CPU es capaz de alcanzar al máximo. ¿Cuánto tiempo quieres pasar optimizando esto, si ni siquiera sabes si la CPU es fundamentalmente capaz de ejecutar más instrucciones por segundo?

Es muy fácil evitar que la unidad de FP de la CPU se utilice de manera eficiente, al tener demasiadas dependencias entre las operaciones de FP o al tener demasiadas ramas o similares que impidan una programación eficiente. Y si eso es lo que está reteniendo su implementación, debe saberlo. Necesita saber que "no estoy obteniendo el rendimiento de FP que debería ser posible, por lo que es evidente que otras partes de mi código impiden que las instrucciones de FP estén disponibles cuando la CPU está lista para emitir una".

¿Por qué necesitas otras formas de medir el rendimiento? ¿Qué hay de malo con solo calcular el recuento de FLOPS como te lo pidió tu jefe? ;)


Me gustaría agregar un par de puntos más finos:

  • la división es especial. Dado que la mayoría de los procesadores pueden hacer una adición, comparación o multiplicación en un solo ciclo, todos se cuentan como un fracaso. Pero la división siempre lleva más tiempo. Cuánto tiempo más depende del procesador, pero existe una especie de estándar de facto en la comunidad de HPC para contar una división como 4 fracasos.

  • Si un procesador tiene una instrucción fusionada de suma y multiplicación que hace una multiplicación y una suma en una sola instrucción, generalmente A + = B * C, eso cuenta como 2 operaciones.

  • Siempre tenga cuidado al distinguir entre fracasos de precisión simple y fracasos de precisión doble . Un procesador que es capaz de tantos gigaflops de precisión simple solo puede tener una pequeña fracción de muchos gigaflops de doble precisión. Los procesadores AMD Athlon y Phenom generalmente pueden hacer la mitad de fracasos de precisión doble que la precisión simple. Los procesadores ATI Firestream generalmente pueden hacer 1/5 tantos fracasos de precisión doble como precisión simple. Si alguien está tratando de venderle un procesador o un paquete de software y solo citan fracasos sin decir cuál, debe llamarlos.

  • Los términos megaflop, gigaflop, teraflop, etc. son de uso común. Estos se refieren a factores de 1000 , no de 1024 . Por ejemplo, 1 megaflop = 1,000,000 de flop / seg, no 1,048,576. Al igual que con los tamaños de las unidades de disco, hay algo de confusión en esto.


No creo que la medición de FLOPS sea muy útil.

El número de FLOPS logrados le dirá cuán ocupado está su algoritmo para mantener la CPU, pero no le dirá qué tan bien está funcionando su algoritmo.

Puede encontrar dos algoritmos diferentes que hacen que el procesador realice el mismo número de FLOPS, pero uno le proporciona el resultado deseado en la mitad del tiempo.

Creo que sería mejor que miraras una estadística de ''nivel más alto'', como la cantidad de ecuaciones diferenciales resueltas por unidad de tiempo (es decir, después de todo, el propósito de tu algoritmo).

Por otro lado, medir el número de FLOPS logrados puede ayudarte a mejorar tu algoritmo ya que te indicará cuán ocupado estás manteniendo la CPU.


Su empleador tiene razón.
La única forma de medir la efectividad de su programa Fortran (o de cualquier otro programa, por cierto) es probarlo con los puntos de referencia estándar, si existen.

Y, sobre FLOPs, significa "operaciones de punto flotante por segundo" - vea la definición en Wikipedia.


Una vieja pregunta con respuestas antiguas, si bien populares, que no son exactamente geniales, IMO.

Un "FLOP" es una operación matemática de coma flotante. "FLOPS" puede significar una de dos cosas:

  • El plural simple de "FLOP" (es decir, "operación X toma 50 FLOP")
  • La tasa de FLOP en el primer sentido (es decir, operaciones matemáticas de coma flotante por segundo)

Donde no está claro desde el contexto, cuál de estos significa a menudo se desambigua escribiendo al primero como "FLOP" y al último como "FLOP / s".

Los FLOP se denominan para distinguirlos de otros tipos de operaciones de CPU , como operaciones matemáticas enteras, operaciones lógicas, operaciones bit a bit, operaciones de memoria y operaciones de bifurcación, que tienen costos diferentes (léase "tomar diferentes duraciones de tiempo") asociados con ellos.

La práctica del "recuento FLOP" se remonta a los primeros tiempos de la informática científica, cuando los FLOP eran, hablando en términos relativos, extremadamente caros, y tomaban muchos ciclos de CPU cada uno. Un coprocesador matemático 80387, por ejemplo, tomó alrededor de 300 ciclos para una sola multiplicación. Esto fue antes de la canalización y antes de que el abismo entre las velocidades de reloj de la CPU y la velocidad de la memoria realmente se abriera: las operaciones de memoria tomaron solo un ciclo o dos, y la ramificación ("toma de decisiones") fue igualmente barata. En aquel entonces, si podía eliminar un solo FLOP a favor de una docena de accesos a la memoria, obtenía una ganancia. Si pudieras eliminar un solo FLOP en favor de una docena de ramas, obtendrías una ganancia. Por lo tanto, en el pasado, tenía sentido contar FLOP y no preocuparse mucho por referencias de memoria y sucursales porque las FLOP dominaban fuertemente el tiempo de ejecución porque eran individualmente muy costosas en comparación con otros tipos de operación.

Más recientemente, la situación se ha revertido. Los FLOP se han vuelto muy baratos: cualquier núcleo Intel moderno puede realizar aproximadamente dos FLOP por ciclo (aunque la división sigue siendo relativamente cara) y los accesos a memoria y sucursales son comparativamente mucho más caros: un golpe de caché L1 cuesta 3 o 4 ciclos, una recuperación de la memoria principal cuesta 150-200. Dada esta inversión, ya no es el caso que la eliminación de un FLOP a favor de un acceso a memoria dará como resultado una ganancia ; de hecho, eso es poco probable. Del mismo modo, a menudo es más barato "simplemente hacer" un FLOP, incluso si es redundante, en lugar de decidir si hacerlo o no. Esto es prácticamente lo opuesto a la situación de hace 25 años.

Desafortunadamente, la práctica del conteo ciego de FLOP como una métrica absoluta del mérito algorítmico ha persistido mucho después de su fecha de caducidad. La informática científica moderna es mucho más acerca de la administración del ancho de banda de la memoria , tratando de mantener las unidades de ejecución que alimentan los FLOP constantemente con datos, que de reducir el número de FLOP. La referencia a LINPACK (que fue básicamente obsoleta por LAPACK hace 20 años) me lleva a sospechar que su empleador probablemente sea de una escuela muy antigua que no ha internalizado el hecho de que establecer expectativas de rendimiento no es solo cuestión de contar de nuevo con FLOP . Un solucionador que haga el doble de FLOPs podría ser veinte veces más rápido que otro si tiene un patrón de acceso a la memoria y un diseño de datos mucho más favorables.

El resultado de todo esto es que la evaluación del rendimiento del software computacionalmente intensivo se ha vuelto mucho más compleja de lo que solía ser . El hecho de que los FLOP se hayan vuelto baratos se complica enormemente por la gran variabilidad en los costos de las operaciones y ramas de la memoria. Cuando se trata de evaluar algoritmos , el conteo simple de FLOP simplemente ya no informa las expectativas de rendimiento generales.

Tal vez una mejor forma de pensar acerca de las expectativas de rendimiento y la evaluación sea el llamado modelo de línea de techo , que está lejos de ser perfecto, pero tiene la ventaja de hacerle pensar en el equilibrio entre problemas de ancho de banda flotante y de memoria en el al mismo tiempo , brindando una "imagen 2D" más informativa y perspicaz que permite la comparación de las mediciones de rendimiento y las expectativas de rendimiento.

Vale la pena echarle un vistazo.


Intentaré hacerlo lo más rápido posible, y eso requiere saber dónde está pasando el tiempo, especialmente si hay llamadas a funciones que podrían evitarse.

Lo hago por el simple método de simplemente interrumpirlo un par de veces mientras se está ejecutando, y ver lo que está haciendo. Aquí están los tipos de cosas que encuentro:

  • Gran parte del tiempo está en el proceso de calcular la derivada y / o Jacobiano. Gran parte de este tiempo puede utilizarse en llamadas a funciones matemáticas como exp() , log() y sqrt() . A menudo, estos se repiten con argumentos idénticos y pueden ser memorizados. (Masiva aceleración)

  • Gran parte del tiempo se gasta calculando derivados muchas veces porque las tolerancias de integración son más estrictas de lo necesario. (Más rápido)

  • Si se usa un algoritmo de integración implícita (como DLSODE Gear) porque se cree que las ecuaciones son rígidas, lo más probable es que no lo sean, y podría usarse algo como Runge-Kutta. (DVERK). (Más rápido todavía)

  • Posiblemente un algoritmo de matriz exponente podría usarse si el modelo es lineal (DGPADM). Este es un gran triunfo para el rendimiento y la precisión, y es inmune a la rigidez. (Mucho más rápido)

  • Más arriba en la pila de llamadas, podría ser que las mismas integraciones se realicen repetidamente con parámetros ligeramente diferentes, a fin de determinar un gradiente de diferencia hacia adelante o central de la solución con respecto a esos parámetros. Si las ecuaciones diferenciales son en sí mismas diferenciables, es posible obtener esos gradientes analíticamente, o mediante el aumento de las ecuaciones con ecuaciones de sensibilidad. Esto no solo es mucho más rápido, sino mucho más preciso, lo que puede acelerar las cosas aún más arriba en la pila.

Puedes ver cada nivel de la pila como una oportunidad para encontrar cosas para optimizar y las aceleraciones se combinarán. Luego, cuando vayas a multi-cpu, asumiendo que sea paralelizable, eso debería proporcionar su propio factor multiplicativo.

Así que de vuelta a FLOPs. Podría intentar maximizar FLOPs / second , pero también puede ser mucho más útil minimizar FLOPs / run , optimizando en todos los niveles de la pila. En cualquier caso, solo medirlos no te dice casi nada.