linux - test - phoronix benchmark
¿El comando `time` de UNIX es lo suficientemente preciso para los benchmarks? (4)
Digamos que quería comparar dos programas: foo.py y bar.py.
¿Hay un par de miles de ejecuciones y los promedios respectivos de time python foo.py
y time python bar.py
suficientemente adecuados para perfilar y comparar su velocidad?
Editar: Además, si la ejecución de cada programa fue de menos de un segundo (suponiendo que no fuera por lo anterior), ¿estaría bien utilizar el tiempo?
Hoy en día, imo, no hay ninguna razón para utilizar el time
con fines de evaluación comparativa. Usa perf stat
lugar. Le da mucha más información útil y puede repetir el proceso de evaluación comparativa en cualquier momento dado y hacer estadísticas sobre los resultados, es decir, calcular la varianza y el valor medio. Esto es mucho más confiable y tan fácil de usar como el time
:
perf stat -r 10 -d <your app and arguments>
El -r 10
ejecutará su aplicación 10 veces y hará estadísticas sobre ella. -d
genera más datos, como errores de caché.
Entonces, aunque el time
puede ser lo suficientemente confiable para aplicaciones de larga ejecución, definitivamente no es tan confiable como la perf stat
. Usa eso en cambio.
Adición: si realmente quieres seguir usando el time
, al menos no uses el comando bash-builtin, sino el real-deal en modo detallado:
/usr/bin/time -v <some command with arguments>
El resultado es, por ejemplo:
Command being timed: "ls"
User time (seconds): 0.00
System time (seconds): 0.00
Percent of CPU this job got: 0%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.00
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 1968
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 0
Minor (reclaiming a frame) page faults: 93
Voluntary context switches: 1
Involuntary context switches: 2
Swaps: 0
File system inputs: 8
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0
Observe especialmente cómo esto es capaz de medir el máximo de RSS, que a menudo es suficiente si desea comparar el efecto de un parche en el consumo máximo de memoria. Es decir, usar ese valor para comparar antes / después y si hay una disminución significativa en el pico de RSS, entonces hiciste algo bien.
Sí, el time
es lo suficientemente preciso. Y tendrá que ejecutar solo una docena de veces sus programas (siempre que la ejecución dure más de un segundo, o una fracción significativa de segundo, es decir, más de 200 milisegundos al menos). Por supuesto, el sistema de archivos estaría caliente (es decir, los archivos pequeños ya estarían en la memoria caché) para la mayoría de las ejecuciones (excepto la primera), así que tenlo en cuenta.
La razón por la que desea que el time
d ejecutado dure al menos unas décimas de segundo es la precisión y la granularidad de la medición del tiempo. No esperes menos de centésimas de segundo de precisión. (necesitas alguna opción especial del kernel para tener un milisegundo)
Desde dentro de la aplicación, puede usar clock , clock_gettime , getrusage , getrusage , times (seguramente tienen un equivalente de Python).
No te olvides de leer la página man de time(7) .
Sí. El comando de tiempo proporciona tanto el tiempo transcurrido como la CPU consumida. Probablemente, esto último es lo que debes enfocarte, a menos que estés haciendo un montón de E / S. Si el tiempo transcurrido es importante, asegúrese de que el sistema no tenga otra actividad significativa mientras ejecuta su prueba.
time
produce tiempos suficientemente buenos para los puntos de referencia que se ejecutan en un segundo, de lo contrario el tiempo que demoró en ejecutar un proceso puede ser grande en comparación con su tiempo de ejecución.
Sin embargo, cuando se realiza una evaluación comparativa, debe tener cuidado con el cambio de contexto. Es decir, otro proceso puede ser el uso de la CPU, conteniendo así la CPU con su punto de referencia y aumentando su tiempo de ejecución. Para evitar conflictos con otros procesos, debe ejecutar un punto de referencia como este:
sudo chrt -f 99 /usr/bin/time --verbose <benchmark>
sudo chrt -f 99
ejecuta su punto de referencia en clase FIFO en tiempo real con prioridad 99, lo que hace que su proceso sea el proceso de mayor prioridad y evita el cambio de contexto (puede cambiar su /etc/security/limits.conf
para que no requiera un proceso privilegiado para usar prioridades en tiempo real).
También hace que el time
reporte todas las estadísticas disponibles, incluida la cantidad de cambios de contexto en los que incurrió su punto de referencia, que normalmente debería ser 0; de lo contrario, es posible que desee volver a ejecutar el índice de referencia.
Y es mejor desactivar el aumento y la ampliación de la frecuencia de la CPU, de modo que la frecuencia de la CPU se mantenga constante durante el benchmark para obtener resultados consistentes.