différence entre time () et gettimeofday () et pourquoi cause-t-on une faute de seg

J’essaie de mesurer le temps nécessaire à un appel système, et j’ai essayé d’utiliser time(0) et gettimeofday() dans ce programme, mais chaque fois que j’utilise gettimeofday() il y a des erreurs. Je suppose que je peux juste utiliser le time(0) mais je voudrais savoir pourquoi cela se produit. Et je sais que vous pouvez simplement regarder et voir le problème. S’il vous plaît ne me criez pas!

Je veux avoir le temps, mais pas le sauver n’importe où.

J’ai essayé toutes les combinaisons de code auxquelles je peux penser, mais j’ai collé la version la plus simple ici. Je suis nouveau sur C et Linux. Je regarde le fichier .stackdump mais ça ne veut rien dire pour moi.

GetRDTSC est dans util.h et il fait rdtsc() , comme on peut s’y attendre. Maintenant, il est mis à 10 itérations mais plus tard, la boucle sera exécutée 1000 fois, sans printf .

 #include  #include  #include "util.h" int main() { int i; uint64_t cycles[10]; for (i = 0; i < 10; ++i) { // get initial cycles uint64_t init = GetRDTSC(); gettimeofday(); // <== time(0) will work here without a seg fault. // get cycles after uint64_t after = GetRDTSC(); // save cycles for each operation in an array cycles[i] = after - init; printf("%i\n", (int)(cycles[i])); } } 

La version courte

gettimeofday() nécessite un pointeur sur une struct timeval pour remplir avec des données de temps.

Ainsi, par exemple, vous faites quelque chose comme ceci:

 #include  #include  int main() { struct timeval tv; gettimeofday(&tv, NULL); // timezone should be NULL printf("%d seconds\n", tv.tv_secs); return 0; } 

La version longue

Le vrai problème est que gcc inclut automatiquement vdso sur votre système, qui contient un symbole pour syscall gettimeofday . Considérez ce programme (fichier entier):

 int main() { gettimeofday(); return 0; } 

Par défaut, gcc comstackra ceci sans avertissement . Si vous cochez les symboles auxquels il est lié, vous verrez:

 ternus@event-horizon ~> gcc -o foo foo.c ternus@event-horizon ~> ldd foo linux-vdso.so.1 => (0x00007ffff33fe000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f56a5255000) /lib64/ld-linux-x86-64.so.2 (0x00007f56a562b000) 

Vous utilisez juste une fonction qui a un symbole défini, mais sans le prototype, il n’y a aucun moyen de dire combien d’arguments de ligne de commande il est censé avoir.

Si vous le comstackz avec -Wall , vous verrez:

 ternus@event-horizon ~> gcc -Wall -o foo foo.c foo.c: In function 'main': foo.c:2:3: warning: implicit declaration of function 'gettimeofday' [-Wimplicit-function-declaration] 

Bien sûr, il ne va pas mieux quand vous essayez de l’exécuter. Il est intéressant de noter qu’il sera bloqué dans l’espace du kernel (c’est sur MacOS):

 cternus@astarael ~/foo> gcc -o foo -g foo.c cternus@astarael ~/foo> gdb foo GNU gdb 6.3.50-20050815 (Apple version gdb-1822) (Sun Aug 5 03:00:42 UTC 2012) [etc] (gdb) run Starting program: /Users/cternus/foo/foo Reading symbols for shared libraries +.............................. done Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000001 0x00007fff87eeab73 in __commpage_gettimeofday () 

Considérons maintenant ce programme (encore une fois, pas de fichiers d’en-tête):

 typedef struct { long tv_sec; long tv_usec; } timeval; int main() { timeval tv; gettimeofday(&tv, 0); return 0; } 

Cela comstackra et fonctionnera correctement – pas de segfault. Vous lui avez fourni l’emplacement de mémoire gettimeofday , même s’il n’y a toujours pas de prototype gettimeofday fourni.

Plus d’information:

Quelqu’un peut-il comprendre comment fonctionne gettimeofday?

Y a-t-il un équivalent plus rapide de gettimeofday?

La spécification POSIX gettimeofday