$ time foo
real 0m0.003s
user 0m0.000s
sys 0m0.004s
Lequel de ces trois éléments est significatif pour l'évaluation de mon application ?
$ time foo
real 0m0.003s
user 0m0.000s
sys 0m0.004s
Lequel de ces trois éléments est significatif pour l'évaluation de mon application ?
Statistiques sur le temps de traitement réel, utilisateur et système
L'une de ces choses n'est pas comme l'autre. Real se réfère au temps réel écoulé ; User et Sys se réfèrent au temps CPU utilisé. uniquement par le processus.
Real est le temps de l'horloge murale - le temps du début à la fin de l'appel. Il s'agit de tout le temps écoulé, y compris les tranches de temps utilisées par d'autres processus et le temps que le processus passe bloqué (par exemple s'il attend la fin des E/S).
Utilisateur est la quantité de temps CPU passé dans le code en mode utilisateur (en dehors du noyau) sur le processus. Il s'agit uniquement du temps CPU réel utilisé pour l'exécution du processus. Les autres processus et le temps que le processus passe bloqué ne sont pas pris en compte dans ce chiffre.
Sys est la quantité de temps CPU passé dans le noyau au sein du processus. Cela signifie que l'exécution du temps CPU passé dans les appels système dans le noyau, par opposition au code de la bibliothèque, qui est toujours exécuté dans l'espace utilisateur. Comme pour le mode "utilisateur", il s'agit uniquement du temps CPU utilisé par le processus. Voir ci-dessous pour une brève description du mode noyau (également connu sous le nom de mode "superviseur") et du mécanisme d'appel système.
User+Sys
vous dira combien de temps réel de CPU votre processus a utilisé. Notez que ce temps est calculé sur tous les processeurs, donc si le processus a plusieurs threads, il peut potentiellement dépasser le temps d'horloge indiqué par la fonction Real
. Notez que dans la sortie, ces chiffres incluent le User
et Sys
de tous les processus enfants également, bien que les appels système sous-jacents renvoient les statistiques pour le processus et ses enfants séparément.
Origines des statistiques rapportées par time (1)
Les statistiques rapportées par time
sont recueillies à partir de divers appels système. User " et " Sys " proviennent de wait (2)
ou times (2)
selon le système en question. La valeur "réelle" est calculée à partir d'une heure de début et d'une heure de fin obtenues à partir de l'écran d'affichage. gettimeofday (2)
appel. En fonction de la version du système, d'autres statistiques telles que le nombre de changements de contexte peuvent également être collectées par time
.
Sur une machine multiprocesseur, un processus multithread ou un processus bifurquant des enfants pourrait avoir un temps écoulé inférieur au temps total du CPU - car différents threads ou processus peuvent fonctionner en parallèle. En outre, les statistiques de temps rapportées proviennent de différentes origines, de sorte que les temps enregistrés pour des tâches de très courte durée peuvent être sujets à des erreurs d'arrondi, comme le montre l'exemple donné par le posteur original.
Une brève introduction au mode Kernel vs. mode Utilisateur
Sur Unix, ou tout autre système d'exploitation à mémoire protégée, Kernel" ou "Superviseur". fait référence à un mode privilégié dans laquelle l'unité centrale peut fonctionner. Certaines actions privilégiées susceptibles d'affecter la sécurité ou la stabilité ne peuvent être effectuées que lorsque l'UC fonctionne dans ce mode ; ces actions ne sont pas accessibles au code d'application. Un exemple d'une telle action pourrait être de manipuler la fonction MMU pour accéder à l'espace d'adressage d'un autre processus. Normalement, mode utilisateur ne peut pas le faire (avec de bonnes raisons), bien qu'il puisse demander Mémoire partagée du noyau, qui pourrait être lu ou écrit par plus d'un processus. Dans ce cas, la mémoire partagée est explicitement demandée au noyau par un mécanisme sécurisé et les deux processus doivent explicitement s'y attacher pour pouvoir l'utiliser.
Le mode privilégié est généralement appelé mode "noyau" parce que le noyau est exécuté par l'unité centrale de traitement qui fonctionne dans ce mode. Afin de passer en mode noyau, vous devez émettre une instruction spécifique (souvent appelée piège ) qui fait passer l'unité centrale en mode noyau. et exécute le code à partir d'un emplacement spécifique contenu dans une table de saut. Pour des raisons de sécurité, vous ne pouvez pas passer en mode noyau et exécuter du code arbitraire - les pièges sont gérés par une table d'adresses dans laquelle il est impossible d'écrire, sauf si l'unité centrale fonctionne en mode superviseur. Les pièges sont gérés par une table d'adresses dans laquelle il est impossible d'écrire, à moins que le CPU ne fonctionne en mode superviseur. Vous utilisez un numéro de piège explicite et l'adresse est recherchée dans la table de saut ; le noyau a un nombre fini de points d'entrée contrôlés.
Les appels "système" de la bibliothèque C (notamment ceux décrits dans la section 2 des pages de manuel) ont une composante en mode utilisateur, qui correspond à ce que vous appelez réellement depuis votre programme C. En coulisse, ils peuvent émettre un ou plusieurs appels système vers le noyau pour effectuer des services spécifiques tels que les E/S, mais ils ont toujours du code qui s'exécute en mode utilisateur. Il est également tout à fait possible d'émettre directement un piège vers le mode noyau à partir de n'importe quel code de l'espace utilisateur si vous le souhaitez, bien que vous deviez écrire un bout de langage d'assemblage pour configurer les registres correctement pour l'appel. Une page décrivant les appels système fournis par le noyau Linux et les conventions de configuration des registres peut être consultée à l'adresse suivante ici.
Plus d'informations sur 'sys'.
Il y a des choses que votre code ne peut pas faire en mode utilisateur - des choses comme l'allocation de mémoire ou l'accès au matériel (disque dur, réseau, etc.). Ces choses sont sous la supervision du noyau, et lui seul peut les faire. Certaines opérations que vous effectuez (comme malloc
ou fread
/ fwrite
) invoquera ces fonctions du noyau et cela comptera alors comme du temps 'sys'. Malheureusement, ce n'est pas aussi simple que "chaque appel à malloc sera compté dans le temps 'sys'". L'appel à malloc
effectuera son propre traitement (toujours comptabilisé dans le temps "utilisateur") et, quelque part, appellera la fonction dans le noyau (comptabilisé dans le temps "sys"). Après le retour de l'appel au noyau, il y aura encore un peu de temps en 'user', puis en 'sys'. malloc
retournera à votre code. Quant à savoir quand la commutation se produit, et combien de temps elle passe en mode noyau... vous ne pouvez pas le dire. Cela dépend de l'implémentation de la bibliothèque. De plus, d'autres fonctions apparemment innocentes peuvent également utiliser malloc
et autres en arrière-plan, qui auront à nouveau du temps dans 'sys'.
@ron - Selon la page de manuel de Linux, il agrège les temps 'c' avec les temps de processus, donc je pense qu'il le fait. Les temps des parents et des enfants sont disponibles séparément de l'appel times(2), cependant. Je suppose que la version Solaris/SysV de time(1) fait quelque chose de similaire.
@ron Je viens de modifier la réponse : Le temps passé par les processus enfants et leurs descendants comptent seulement alors que le temps aurait pu être collecté par wait(2) ou waitpid(2), et récursivement avec les descendants. Cela implique que les processus fils doivent s'être terminés. Par exemple, on peut comparer time sh -c 'foo & sleep 1'
y time sh -c 'foo & sleep 2'
où foo
est une commande qui prend du temps CPU entre 1 et 2 secondes. Le premier produit quelque chose autour de 0.
Puisque je n'ai pas assez de représentants pour commenter la réponse la plus élevée, je voulais juste fournir une autre raison pour laquelle real
≠ user
+ sys
.
Gardez à l'esprit que real
représente le temps réel écoulé, tandis que user
et sys
représentent le temps d'exécution du CPU. Par conséquent, sur un système multicœur, la valeur de user
et/ou sys
temps (ainsi que leur somme) peuvent en fait dépasser le temps réel. Par exemple, sur une application Java que j'exécute pour la classe, j'obtiens cet ensemble de valeurs :
real 1m47.363s
user 2m41.318s
sys 0m4.013s
Je me suis toujours posé cette question. Puisque je sais que mes programmes sont mono-threading, la différence entre le temps utilisateur et le temps réel doit être une surcharge de la VM, n'est-ce pas ?
Pas nécessairement ; la JVM de Sun sur les machines Solaris ainsi que la JVM d'Apple sur Mac OS X parviennent à utiliser plus d'un cœur même dans les applications à un seul fil. Si vous faites un échantillon d'un processus Java, vous verrez que des choses comme la collecte des déchets s'exécutent sur des threads séparés (et d'autres choses aussi dont je ne me souviens plus). Je ne sais pas si vous voulez vraiment appeler cela "VM overhead".
@Quantum7 - non, pas nécessairement. Voir mon message ci-dessus. Real est le temps écoulé, user et sys sont des statistiques de tranches de temps accumulées à partir du temps CPU que le processus utilise réellement.
- real : Le temps réel passé à exécuter le processus du début à la fin, comme s'il était mesuré par un humain avec un chronomètre.
- utilisateur : Le temps cumulé passé par tous les CPUs pendant le calcul.
- sys : Le temps cumulé passé par toutes les unités centrales pendant les tâches liées au système, telles que l'allocation de mémoire.
Notez que parfois user + sys peut être plus grand que réel, comme plusieurs processeurs peuvent travailler en parallèle.
Exemples POSIX C minimaux exécutables
Pour rendre les choses plus concrètes, je veux illustrer quelques cas extrêmes de time
avec quelques programmes de test C minimaux.
Tous les programmes peuvent être compilés et exécutés avec :
gcc -ggdb3 -o main.out -pthread -std=c99 -pedantic-errors -Wall -Wextra main.c
time ./main.out
et ont été testés dans Ubuntu 18.10, GCC 8.2.0, glibc 2.28, noyau Linux 4.18, ordinateur portable ThinkPad P51, CPU Intel Core i7-7820HQ (4 cœurs / 8 threads), 2x Samsung M471A2K43BB1-CRC RAM (2x 16GiB).
sleep
syscall
Le sommeil non-occupé tel que fait par le sleep
syscall ne compte que dans real
mais pas pour user
o sys
.
Par exemple, un programme qui dort pendant une seconde :
#define _XOPEN_SOURCE 700
#include <stdlib.h>
#include <unistd.h>
int main(void) {
sleep(1);
return EXIT_SUCCESS;
}
sort quelque chose comme :
real 0m1.003s
user 0m0.001s
sys 0m0.003s
Il en va de même pour les programmes bloqués sur IO qui deviennent disponibles.
Par exemple, le programme suivant attend que l'utilisateur saisisse un caractère et appuie sur la touche Entrée :
#include <stdio.h>
#include <stdlib.h>
int main(void) {
printf("%c\n", getchar());
return EXIT_SUCCESS;
}
Et si vous attendez environ une seconde, il sort comme l'exemple de sommeil quelque chose comme :
real 0m1.003s
user 0m0.001s
sys 0m0.003s
C'est pourquoi time
peut vous aider à distinguer les programmes liés au processeur et ceux liés aux entrées-sorties : Que signifient les termes "lié au processeur" et "lié aux E/S" ?
Fils multiples
L'exemple suivant fait niters
itérations de travail inutile purement lié au CPU sur nthreads
fils :
#define _XOPEN_SOURCE 700
#include <assert.h>
#include <inttypes.h>
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
uint64_t niters;
void* my_thread(void *arg) {
uint64_t *argument, i, result;
argument = (uint64_t *)arg;
result = *argument;
for (i = 0; i < niters; ++i) {
result = (result * result) - (3 * result) + 1;
}
*argument = result;
return NULL;
}
int main(int argc, char **argv) {
size_t nthreads;
pthread_t *threads;
uint64_t rc, i, *thread_args;
/* CLI args. */
if (argc > 1) {
niters = strtoll(argv[1], NULL, 0);
} else {
niters = 1000000000;
}
if (argc > 2) {
nthreads = strtoll(argv[2], NULL, 0);
} else {
nthreads = 1;
}
threads = malloc(nthreads * sizeof(*threads));
thread_args = malloc(nthreads * sizeof(*thread_args));
/* Create all threads */
for (i = 0; i < nthreads; ++i) {
thread_args[i] = i;
rc = pthread_create(
&threads[i],
NULL,
my_thread,
(void*)&thread_args[i]
);
assert(rc == 0);
}
/* Wait for all threads to complete */
for (i = 0; i < nthreads; ++i) {
rc = pthread_join(threads[i], NULL);
assert(rc == 0);
printf("%" PRIu64 " %" PRIu64 "\n", i, thread_args[i]);
}
free(threads);
free(thread_args);
return EXIT_SUCCESS;
}
GitHub amont + code de la parcelle .
Ensuite, nous traçons wall, user et sys en fonction du nombre de threads pour un nombre fixe de 10^10 itérations sur mon CPU à 8 hyperthreads :
D'après le graphique, nous voyons que :
pour une application mono-coeur intensive en CPU, le mur et l'utilisateur sont à peu près identiques
pour 2 cœurs, l'utilisateur est environ 2x le mur, ce qui signifie que le temps de l'utilisateur est compté sur tous les threads.
l'utilisateur a pratiquement doublé, et le mur est resté le même.
cela continue jusqu'à 8 threads, ce qui correspond au nombre d'hyperthreads de mon ordinateur.
Après 8, le mur commence à augmenter aussi, parce que nous n'avons pas de CPUs supplémentaires pour mettre plus de travail dans une quantité donnée de temps !
Le rapport se stabilise à ce stade.
Notez que ce graphique n'est aussi clair et simple que parce que le travail est purement lié à l'unité centrale : s'il était lié à la mémoire, nous aurions une baisse de performance beaucoup plus tôt avec moins de cœurs, car les accès à la mémoire seraient un goulot d'étranglement, comme le montre l'illustration ci-dessous. Que signifient les termes "lié au processeur" et "lié aux E/S" ?
Vérifier rapidement ce mur < utilisateur est un moyen simple de déterminer qu'un programme est multithreadé, et plus ce ratio est proche du nombre de cœurs, plus la parallélisation est efficace, par ex :
Sys heavy work with sendfile
La charge de travail la plus lourde pour le système que j'ai pu trouver était d'utiliser la fonction sendfile
qui effectue une opération de copie de fichier dans l'espace du noyau : Copier un fichier de manière saine, sûre et efficace
J'ai donc imaginé que ce noyau interne memcpy
sera une opération gourmande en ressources CPU.
D'abord j'initialise un grand fichier aléatoire de 10GiB avec :
dd if=/dev/urandom of=sendfile.in.tmp bs=1K count=10M
Ensuite, exécutez le code :
#define _GNU_SOURCE
#include <assert.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/sendfile.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char **argv) {
char *source_path, *dest_path;
int source, dest;
struct stat stat_source;
if (argc > 1) {
source_path = argv[1];
} else {
source_path = "sendfile.in.tmp";
}
if (argc > 2) {
dest_path = argv[2];
} else {
dest_path = "sendfile.out.tmp";
}
source = open(source_path, O_RDONLY);
assert(source != -1);
dest = open(dest_path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
assert(dest != -1);
assert(fstat(source, &stat_source) != -1);
assert(sendfile(dest, source, 0, stat_source.st_size) != -1);
assert(close(source) != -1);
assert(close(dest) != -1);
return EXIT_SUCCESS;
}
ce qui donne essentiellement du temps système comme prévu :
real 0m2.175s
user 0m0.001s
sys 0m1.476s
J'étais aussi curieux de voir si time
distinguerait les syscalls de différents processus, alors j'ai essayé :
time ./sendfile.out sendfile.in1.tmp sendfile.out1.tmp &
time ./sendfile.out sendfile.in2.tmp sendfile.out2.tmp &
Et le résultat a été :
real 0m3.651s
user 0m0.000s
sys 0m1.516s
real 0m4.948s
user 0m0.000s
sys 0m1.562s
Le temps sys est à peu près le même pour les deux que pour un seul processus, mais le temps wall est plus important parce que les processus sont en compétition pour l'accès à la lecture du disque.
Il semble donc qu'il tienne compte du processus qui a lancé un travail donné du noyau.
Code source de Bash
Quand vous faites juste time <cmd>
sur Ubuntu, il utilise le mot-clé Bash comme on peut le voir :
type time
qui sort :
time is a shell keyword
Donc, nous grep source dans le code source de Bash 4.19 pour la chaîne de sortie :
git grep '"user\b'
ce qui nous amène à execute_cmd.c fonction time_command
qui utilise :
gettimeofday()
y getrusage()
si les deux sont disponiblestimes()
sinonqui sont tous Appels système Linux y Fonctions POSIX .
Code source de GNU Coreutils
Si nous l'appelons ainsi :
/usr/bin/time
alors il utilise l'implémentation de GNU Coreutils.
Celle-ci est un peu plus complexe, mais la source pertinente semble être à l'adresse suivante resuse.c et c'est le cas :
un BSD non-POSIX wait3
appeler si cela est disponible
times
y gettimeofday
sinon
1 : https://i.stack.imgur.com/qAfEe.png**Minimal exemples POSIX C exécutables**
Pour rendre les choses plus concrètes, je veux exemplifier quelques cas extrêmes de time
avec quelques programmes de test C minimaux.
Tous les programmes peuvent être compilés et exécutés avec :
gcc -ggdb3 -o main.out -pthread -std=c99 -pedantic-errors -Wall -Wextra main.c
time ./main.out
et ont été testés dans Ubuntu 18.10, GCC 8.2.0, glibc 2.28, noyau Linux 4.18, ordinateur portable ThinkPad P51, CPU Intel Core i7-7820HQ (4 cœurs / 8 threads), 2x Samsung M471A2K43BB1-CRC RAM (2x 16GiB).
dormir
Le sommeil non occupé ne compte pas dans les deux cas user
o sys
seulement real
.
Par exemple, un programme qui dort pendant une seconde :
#define _XOPEN_SOURCE 700
#include <stdlib.h>
#include <unistd.h>
int main(void) {
sleep(1);
return EXIT_SUCCESS;
}
sort quelque chose comme :
real 0m1.003s
user 0m0.001s
sys 0m0.003s
Il en va de même pour les programmes bloqués sur IO qui deviennent disponibles.
Par exemple, le programme suivant attend que l'utilisateur saisisse un caractère et appuie sur la touche Entrée :
#include <stdio.h>
#include <stdlib.h>
int main(void) {
printf("%c\n", getchar());
return EXIT_SUCCESS;
}
Et si vous attendez environ une seconde, il sort comme l'exemple de sommeil quelque chose comme :
real 0m1.003s
user 0m0.001s
sys 0m0.003s
C'est pourquoi time
peut vous aider à distinguer les programmes liés au processeur et ceux liés aux entrées-sorties : Que signifient les termes "lié au processeur" et "lié aux E/S" ?
Fils multiples
L'exemple suivant fait niters
itérations de travail inutile purement lié au CPU sur nthreads
fils :
#define _XOPEN_SOURCE 700
#include <assert.h>
#include <inttypes.h>
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
uint64_t niters;
void* my_thread(void *arg) {
uint64_t *argument, i, result;
argument = (uint64_t *)arg;
result = *argument;
for (i = 0; i < niters; ++i) {
result = (result * result) - (3 * result) + 1;
}
*argument = result;
return NULL;
}
int main(int argc, char **argv) {
size_t nthreads;
pthread_t *threads;
uint64_t rc, i, *thread_args;
/* CLI args. */
if (argc > 1) {
niters = strtoll(argv[1], NULL, 0);
} else {
niters = 1000000000;
}
if (argc > 2) {
nthreads = strtoll(argv[2], NULL, 0);
} else {
nthreads = 1;
}
threads = malloc(nthreads * sizeof(*threads));
thread_args = malloc(nthreads * sizeof(*thread_args));
/* Create all threads */
for (i = 0; i < nthreads; ++i) {
thread_args[i] = i;
rc = pthread_create(
&threads[i],
NULL,
my_thread,
(void*)&thread_args[i]
);
assert(rc == 0);
}
/* Wait for all threads to complete */
for (i = 0; i < nthreads; ++i) {
rc = pthread_join(threads[i], NULL);
assert(rc == 0);
printf("%" PRIu64 " %" PRIu64 "\n", i, thread_args[i]);
}
free(threads);
free(thread_args);
return EXIT_SUCCESS;
}
GitHub amont + code de la parcelle .
Ensuite, nous traçons wall, user et sys en fonction du nombre de threads pour un nombre fixe de 10^10 itérations sur mon CPU à 8 hyperthreads :
D'après le graphique, nous voyons que :
pour une application mono-coeur intensive en CPU, le mur et l'utilisateur sont à peu près identiques
pour 2 cœurs, l'utilisateur est environ 2x le mur, ce qui signifie que le temps de l'utilisateur est compté sur tous les threads.
L'utilisateur a pratiquement doublé, et le mur est resté le même.
cela continue jusqu'à 8 threads, ce qui correspond au nombre d'hyperthreads de mon ordinateur.
Après 8, le mur commence à augmenter aussi, parce que nous n'avons pas de CPUs supplémentaires pour mettre plus de travail dans une quantité donnée de temps !
Le rapport se stabilise à ce stade.
Notez que ce graphique n'est aussi clair et simple que parce que le travail est purement lié à l'unité centrale : s'il était lié à la mémoire, nous aurions une baisse de performance beaucoup plus tôt avec moins de cœurs, car les accès à la mémoire seraient un goulot d'étranglement, comme le montre l'illustration ci-dessous. Que signifient les termes "lié au processeur" et "lié aux E/S" ?
Vérifier rapidement ce mur < utilisateur est un moyen simple de déterminer qu'un programme est multithreadé, et plus ce ratio est proche du nombre de cœurs, plus la parallélisation est efficace, par ex :
Sys heavy work with sendfile
La charge de travail la plus lourde pour le système que j'ai pu trouver était d'utiliser la fonction sendfile
qui effectue une opération de copie de fichier dans l'espace du noyau : Copier un fichier de manière saine, sûre et efficace
Donc j'ai imaginé que ce noyau interne memcpy
sera une opération gourmande en ressources CPU.
D'abord j'initialise un grand fichier aléatoire de 10GiB avec :
dd if=/dev/urandom of=sendfile.in.tmp bs=1K count=10M
Ensuite, exécutez le code :
#define _GNU_SOURCE
#include <assert.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/sendfile.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char **argv) {
char *source_path, *dest_path;
int source, dest;
struct stat stat_source;
if (argc > 1) {
source_path = argv[1];
} else {
source_path = "sendfile.in.tmp";
}
if (argc > 2) {
dest_path = argv[2];
} else {
dest_path = "sendfile.out.tmp";
}
source = open(source_path, O_RDONLY);
assert(source != -1);
dest = open(dest_path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
assert(dest != -1);
assert(fstat(source, &stat_source) != -1);
assert(sendfile(dest, source, 0, stat_source.st_size) != -1);
assert(close(source) != -1);
assert(close(dest) != -1);
return EXIT_SUCCESS;
}
ce qui donne essentiellement du temps système comme prévu :
real 0m2.175s
user 0m0.001s
sys 0m1.476s
J'étais aussi curieux de voir si time
distinguerait les syscalls de différents processus, alors j'ai essayé :
time ./sendfile.out sendfile.in1.tmp sendfile.out1.tmp &
time ./sendfile.out sendfile.in2.tmp sendfile.out2.tmp &
Et le résultat a été :
real 0m3.651s
user 0m0.000s
sys 0m1.516s
real 0m4.948s
user 0m0.000s
sys 0m1.562s
Le temps sys est à peu près le même pour les deux que pour un seul processus, mais le temps wall est plus important parce que les processus sont en compétition pour l'accès à la lecture du disque.
Il semble donc qu'il tienne compte du processus qui a lancé un travail donné du noyau.
Code source de Bash
Quand vous faites juste time <cmd>
sur Ubuntu, il utilise le mot-clé Bash comme on peut le voir :
type time
qui sort :
time is a shell keyword
Donc, nous grep source dans le code source de Bash 4.19 pour la chaîne de sortie :
git grep '"user\b'
ce qui nous amène à execute_cmd.c fonction time_command
qui utilise :
gettimeofday()
y getrusage()
si les deux sont disponiblestimes()
sinonqui sont tous Appels système Linux y Fonctions POSIX .
Code source de GNU Coreutils
Si nous l'appelons ainsi :
/usr/bin/time
alors il utilise l'implémentation de GNU Coreutils.
Celle-ci est un peu plus complexe, mais la source pertinente semble être à l'adresse suivante resuse.c et c'est le cas :
wait3
appeler si cela est disponibletimes
y gettimeofday
sinon Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
2 votes
Comment puis-je accéder à un seul d'entre eux ? par exemple en temps réel ?
4 votes
@Casillass Real - stackoverflow.com/questions/2408981/
19 votes
Si votre programme se termine aussi rapidement, aucune de ces mesures n'est significative, il s'agit simplement de frais de démarrage. Si vous voulez mesurer l'ensemble du programme avec
time
pour qu'il fasse quelque chose qui prendra au moins une seconde.27 votes
Il est vraiment important de noter que
time
est un mot-clé de bash. Ainsi, en tapantman time
es no vous donnant une page de manuel pour le bashtime
Il s'agit plutôt de la page de manuel de/usr/bin/time
. Cela m'a fait trébucher.