Estoy usando Valgrind + Callgrind para perfilar un solucionador que he escrito. Como dice el manual de usuario de Valgrind, he compilado mi código con las opciones de depuración para el compilador:
"Sin información de depuración, las mejores herramientas de Valgrind serán capaces de adivinar a qué función pertenece un código en particular, lo que hace que los mensajes de error y la producción de perfiles sean casi inútiles. Con -g, obtendrá mensajes que apuntan directamente a las líneas de código fuente relevantes ".
Cuando se compila con la opción de depuración, los códigos se ejecutan mucho más lentamente. El código CFD se vuelve REALMENTE lento, incluso en casos pequeños cuando se compila con indicadores de depuración. Valgrind lo hace 40 veces más lento (consulte el manual 1 ).
¿Qué herramientas está utilizando para la creación de perfiles de código (creación de perfiles, no evaluación comparativa)?
¿Cuánto tiempo dejas correr el código (estadísticas: cuántos pasos de tiempo)?
¿Qué tan grandes son los casos (si el caso cabe en el caché, el solucionador es un orden de magnitud más rápido, pero luego extrañaré los procesos relacionados con la memoria)?
callgrind
,cachegrind
omassif
. Muchas personas asocian Valgrind solo con la herramienta predeterminada (memcheck
). Como sistema de creación de perfiles basado en emulación (en lugar de interrupción), no debería necesitar ejecutarse durante mucho tiempo.Respuestas:
Aquí hay un ejemplo de cómo lo hago.
Separo el benchmarking (viendo cuánto tiempo lleva) del perfilado (identificando cómo hacerlo más rápido). No es importante que el perfilador sea rápido. Es importante que le diga qué arreglar.
Ni siquiera me gusta la palabra "perfil" porque evoca una imagen algo así como un histograma, donde hay una barra de costos para cada rutina, o "cuello de botella" porque implica que hay un pequeño lugar en el código que debe ser fijo. Ambas cosas implican algún tipo de tiempo y estadísticas, por lo que asume que la precisión es importante. No vale la pena renunciar a la comprensión de la precisión del tiempo.
El método que uso es una pausa aleatoria, y hay un estudio de caso completo y una presentación de diapositivas aquí . Parte de la visión del mundo del cuello de botella del perfilador es que si no encuentra nada, no se puede encontrar nada, y si encuentra algo y obtiene un cierto porcentaje de aceleración, declara la victoria y renuncia. Los fanáticos de Profiler casi nunca dicen cuánto aceleran, y los anuncios solo muestran problemas artificiales diseñados para ser fáciles de encontrar. La pausa aleatoria encuentra los problemas, ya sean fáciles o difíciles. Luego, solucionar un problema expone otros, por lo que el proceso puede repetirse, para obtener una aceleración compuesta.
En mi experiencia con numerosos ejemplos, así es como funciona: puedo encontrar un problema (haciendo una pausa aleatoria) y solucionarlo, obteniendo una aceleración de un porcentaje, digamos 30% o 1.3x. Entonces puedo hacerlo de nuevo, encontrar otro problema y solucionarlo, obteniendo otra aceleración, tal vez menos del 30%, tal vez más. Entonces puedo hacerlo de nuevo, varias veces hasta que realmente no pueda encontrar nada más que arreglar. El factor de aceleración final es el producto en ejecución de los factores individuales, y puede ser asombrosamente grande: órdenes de magnitud en algunos casos.
INSERTADO: Solo para ilustrar este último punto. Hay un ejemplo detallado aquí , con la presentación de diapositivas y todos los archivos, que muestra cómo se logró un aumento de velocidad de 730x en una serie de suspensiones de problemas. La primera versión tomó 2700 microsegundos por unidad de trabajo. El problema A se eliminó, reduciendo el tiempo a 1800 y ampliando los porcentajes de los problemas restantes en 1.5x (2700/1800). Entonces B fue eliminado. Este proceso continuó a través de seis iteraciones, resultando en casi 3 órdenes de aceleración de magnitud. Pero la técnica de creación de perfiles tiene que ser realmente eficaz, porque si no se encuentra alguno de esos problemas, es decir, si llega a un punto en el que cree incorrectamente que no se puede hacer nada más, el proceso se detiene.
INSERTADO: Para decirlo de otra manera, aquí hay un gráfico del factor de aceleración total a medida que se eliminan los problemas sucesivos:
Entonces, para Q1, para la evaluación comparativa es suficiente un temporizador simple. Para "perfilar", uso una pausa aleatoria.
P2: le doy suficiente carga de trabajo (o simplemente le doy un bucle) para que funcione lo suficiente como para pausar.
P3: Por supuesto, dele una carga de trabajo realmente grande para que no se pierda los problemas de caché. Esos aparecerán como ejemplos en el código haciendo las recuperaciones de memoria.
fuente
pstack
ylsstack
, pero realmente considero que este es un proceso más en común con la depuración. Entonces, incluso si el mejor depurador que puedo soportar esgdb
, hace el trabajo. Con un depurador puede examinar los datos, y eso puede marcar la diferencia cuando la pila por sí sola no le dice lo suficiente.El perfilador del pobre es básicamente un
gdb
script que muestra la pila de llamadas. Aún necesitará tener símbolos de depuración. Todavía es lento, pero como no implementa una máquina virtual para ejecutar el código, a menudo es más rápidocallgrind
y adecuado para la tarea.Me he encontrado con analizadores de física de partículas con un éxito modesto (es decir, demostré que el código no tenía puntos calientes horribles y que la optimización requeriría un algoritmo mejor).
fuente
Para agregar a las excelentes respuestas disponibles, hay una herramienta desarrollada en Rice que automatiza el muestreo de la pila y, por lo tanto, tiene muy poca sobrecarga:
http://hpctoolkit.org/
fuente
exp
ylog
con los mismos argumentos repetidamente, u operaciones matriciales que pasan todas sus opciones de decodificación de tiempo. Sintonizo todo lo que puedo, luego enciendo -O3.Allinea MAP es un generador de perfiles de muestreo compatible y desarrollado comercialmente y, por lo tanto, como HPC Toolkit sugirió en una respuesta anterior, puede ejecutarse en trabajos de producción si lo desea.
Este tipo de herramienta apunta a los cuellos de botella de la CPU o la mala comunicación de MPI, pero también la supervisión completa de la elaboración de perfiles de todo el trabajo puede ser invaluable para encontrar problemas sorpresa.
A menudo hay frutos de bajo rendimiento que se encuentran fuera del núcleo de un código CFD, en áreas que no se esperaban. El muestreo aleatorio de la pila es, ya sea de forma manual con GDB o con herramientas como HPC Toolkit y Allinea MAP, la mejor manera de encontrarlos. Si algo es importante para el rendimiento, aparecerá.
fuente