clock_gettime () toujours pas monotone – alternatives?

Comme on le sait depuis un moment (voir, par exemple, cette vieille question et les rapports de bogues qui apparaissent lorsque vous recherchez ceci sur Google), clock_gettime () ne semble pas rapporter le temps de manière monotone. Pour écarter toute erreur stupide que j’aurais pu oublier, voici le code correspondant (extrait d’un programme plus important):

 long nano_1, nano_2; double delta; struct timespec tspec, *tspec_ptr; clock_gettime(CLOCK_MONOTONIC_RAW, tspec_ptr); nano_1 = tspec.tv_nsec; sort_selection(sorted_ptr, n); clock_gettime(CLOCK_MONOTONIC_RAW, tspec_ptr); nano_2 = tspec.tv_nsec; delta = (nano_2 - nano_1)/1000000.0; printf("\nSelection sort took %g micro seconds.\n", (double) delta); 

Le sorting de petits tableaux (environ 1 000 éléments) indique des temps plausibles. Lorsque je sortinge les plus gros (plus de 10 000) à l’aide de 3 algorithmes, 1 à 3 des 3 indiquent le temps de sorting négatif. J’ai essayé tous les types d’horloge mentionnés dans la page de manuel, pas seulement CLOCK_MONOTONIC_RAW – aucun changement.

(1) Quelque chose que j’ai oublié dans mon code?
(2) Existe-t-il une alternative à clock_gettime () pour mesurer le temps par incréments plus précis que les secondes? Je n’ai pas besoin de nanonsecondes, mais secondes est trop grossier pour vraiment aider.

Système:
– Ubuntu 12.04.
kernel 3.2.0-30
– gcc 4.6.3.
– libc version 2.15
– compilé avec -lrt

Cela n’a rien à voir avec la mythologie de l’horloge monotone de clock_gettime qui n’est pas réellement monotone (qui a probablement une base dans la réalité, mais qui n’a jamais été bien documentée et probablement fixée il y a longtemps). C’est juste un bug dans votre programme. tv_nsec est la partie en nanosecondes d’une valeur de temps stockée sous la forme de deux champs:

  • tv_sec – secondes entières
  • tv_nsec – nanosecondes comsockets entre 0 et 999999999

Bien sûr, tv_nsec va revenir en arrière de 999999999 à 0 lorsque tv_sec augmentera. Pour calculer les différences de structures timespec , vous devez prendre 1 million de fois la différence en secondes et l’append à la différence en nanosecondes. Bien sûr, cela pourrait rapidement déborder si vous ne convertissez pas d’abord en un type 64 bits.

Basé sur un peu de lecture autour (y compris le lien que j’ai fourni ci-dessus, et comment mesurer le temps d’exécution réel d’un programme C sous Linux? ), Il semble que getrusage() ou clock() devrait tous les deux vous fournir un “travail” timer qui mesure le temps passé par votre calcul uniquement. Il est vrai que votre autre fonction ne donne pas toujours un intervalle> = 0, je dois dire.

Pour une utilisation sur getrusage, voir http://linux.die.net/man/2/getrusage