web-dev-qa-db-fra.com

La commande UNIX `time` est-elle suffisamment précise pour les benchmarks?

Disons que je voulais comparer deux programmes: foo.py et bar.py.

Sont quelques milliers de pistes et les moyennes respectives de time python foo.py et time python bar.py suffisamment adéquat pour profiler et comparer leur vitesse?


Éditer: De plus, si l'exécution de chaque programme était inférieure à la seconde (supposons que ce n'était pas le cas ci-dessus), time serait-il toujours utilisable?

45
chrisdotcode

time produit suffisamment de temps pour les tests de performance qui s'exécutent sur une seconde, sinon le temps qu'il a fallu à exec() un processus peut être important par rapport à son temps d'exécution.

Cependant, lors de l'analyse comparative, vous devez faire attention au changement de contexte. C'est-à-dire qu'un autre processus peut utiliser le processeur, se disputant ainsi le processeur avec votre référence et augmentant son temps d'exécution. Pour éviter les conflits avec d'autres processus, vous devez exécuter un benchmark comme celui-ci:

Sudo chrt -f 99 /usr/bin/time --verbose <benchmark>

Ou

Sudo chrt -f 99 perf stat -ddd <benchmark>

Sudo chrt -f 99 exécute votre benchmark dans FIFO classe en temps réel avec priorité 99, ce qui fait de votre processus le processus prioritaire et évite le changement de contexte (vous pouvez changer votre /etc/security/limits.conf pour qu'il ne nécessite pas de processus privilégié pour utiliser les priorités en temps réel).

Il permet également à time de rapporter toutes les statistiques disponibles, y compris le nombre de changements de contexte encourus par votre benchmark, qui devrait normalement être 0, sinon vous voudrez peut-être réexécuter le benchmark.

perf stat -ddd est encore plus informatif que /usr/bin/time et affiche des informations telles que les instructions par cycle, les erreurs de branchement et de cache, etc.

Et il est préférable de désactiver la mise à l'échelle et l'augmentation de la fréquence du processeur, de sorte que la fréquence du processeur reste constante pendant le test pour obtenir des résultats cohérents.

57
Maxim Egorushkin

De nos jours, imo, il n'y a aucune raison d'utiliser time à des fins d'analyse comparative. Utilisation perf stat au lieu. Il vous donne des informations beaucoup plus utiles et peut répéter le processus d'analyse comparative un nombre de fois donné et faire des statistiques sur les résultats, c'est-à-dire calculer la variance et la valeur moyenne. C'est beaucoup plus fiable et aussi simple à utiliser que time:

perf stat -r 10 -d <your app and arguments>

Le -r 10 exécutera votre application 10 fois et effectuera des statistiques dessus. -d génère des données supplémentaires, telles que des échecs de cache.

Ainsi, bien que time soit suffisamment fiable pour les applications de longue durée, il n'est certainement pas aussi fiable que perf stat. Utilisez-le à la place.

Addendum: Si vous voulez vraiment continuer à utiliser time, au moins n'utilisez pas la commande bash-builtin, mais la vraie affaire en mode verbeux:

/usr/bin/time -v <some command with arguments>

La sortie est alors par exemple:

    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

Notez en particulier comment cela est capable de mesurer le pic RSS, ce qui est souvent suffisant si vous souhaitez comparer l'effet d'un patch sur la consommation de mémoire maximale. C'est à dire. utilisez cette valeur pour comparer avant/après et s'il y a une diminution significative du pic RSS, alors vous avez fait quelque chose de bien.

48
milianw

Oui, time est suffisamment précis. Et vous n'aurez besoin d'exécuter qu'une douzaine de fois vos programmes (à condition que l'exécution dure plus d'une seconde, ou une fraction de seconde significative - soit plus de 200 millisecondes au moins). Bien sûr, le système de fichiers serait chaud (c'est-à-dire que les petits fichiers seraient déjà mis en cache dans la RAM) pour la plupart des exécutions (sauf la première), alors tenez-en compte.

la raison pour laquelle vous voulez que le time- d s'exécute pour durer quelques dixièmes de secondes au moins est la précision et la granularité de la mesure du temps. Ne vous attendez pas à moins d'un centième de seconde de précision. (vous avez besoin d'une option spéciale du noyau pour l'avoir une milliseconde)

Depuis l'intérieur de l'application, vous pouvez utiliser horloge , clock_gettime , gettimeofday , getrusage , times (ils ont sûrement un Python équivalent).

N'oubliez pas de lire la page man time (7) .

4

Oui. La commande time donne à la fois le temps écoulé et le CPU consommé. Ce dernier est probablement ce sur quoi vous devez vous concentrer, à moins que vous ne fassiez beaucoup d'E/S. Si le temps écoulé est important, assurez-vous que le système n'a pas d'autre activité significative lors de l'exécution de votre test.

2
schtever