L'unité de temps utilisée par le clock
est arbitraire. Sur la plupart des plateformes, elle n'est pas liée à la vitesse du processeur. Elle est plus souvent liée à la fréquence d'une interruption de timer externe - qui peut être configurée en logiciel - ou à une valeur historique qui a été conservée pour des raisons de compatibilité au cours des années d'évolution du processeur. Vous devez utiliser la macro CLOCKS_PER_SEC
à convertir en temps réel.
printf("Total time taken by CPU: %fs\n", (double)total_t / CLOCKS_PER_SEC);
La bibliothèque standard C a été conçue pour pouvoir être mise en œuvre sur une large gamme de matériel, y compris les processeurs qui ne possèdent pas de minuterie interne et qui dépendent d'un périphérique externe pour donner l'heure. De nombreuses plates-formes disposent de moyens plus précis pour mesurer le temps de l'horloge murale que time
et des moyens plus précis de mesurer la consommation du CPU que clock
. Par exemple, sur les systèmes POSIX (par exemple Linux et d'autres systèmes similaires à Unix), vous pouvez utiliser getrusage
qui a une précision de l'ordre de la microseconde.
struct timeval start, end;
struct rusage usage;
getrusage(RUSAGE_SELF, &usage);
start = usage.ru_utime;
…
getrusage(RUSAGE_SELF, &usage);
end = usage.ru_utime;
printf("Total time taken by CPU: %fs\n", (double)(end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) / 1e-6);
Lorsqu'il est disponible, clock_gettime(CLOCK_THREAD_CPUTIME_ID)
o clock_gettime(CLOCK_PROCESS_CPUTIME_ID)
peut donner une meilleure précision. Il a une précision de l'ordre de la nanoseconde.
Notez la différence entre précision et exactitude : la précision est l'unité dans laquelle les valeurs sont rapportées. L'exactitude est la proximité des valeurs rapportées par rapport aux valeurs réelles. À moins que vous ne travailliez sur un système en temps réel En effet, il n'y a pas de garantie absolue quant au temps que prend un morceau de code, y compris l'invocation des fonctions de mesure elles-mêmes.
Certains processeurs ont cycle des horloges qui comptent les cycles du processeur plutôt que le temps de l'horloge murale, mais cela devient très spécifique au système.
Lorsque vous réalisez des benchmarks, n'oubliez pas que ce que vous mesurez est l'exécution de cet exécutable particulier sur ce processeur particulier dans ces circonstances particulières, et que les résultats peuvent ou non être généralisés à d'autres situations. Par exemple, la boucle vide dans votre question sera optimisée par la plupart des compilateurs, à moins que vous ne désactiviez les optimisations. Mesurer la vitesse d'un code non optimisé est généralement inutile. Même si vous ajoutez du travail réel dans la boucle, méfiez-vous des benchmarks jouets : ils n'ont souvent pas les mêmes caractéristiques de performance que le code réel. Sur les processeurs modernes haut de gamme tels que ceux que l'on trouve dans les PC et les smartphones, les benchmarks de code à forte intensité CPU sont souvent très sensibles aux effets de cache et les résultats peuvent dépendre de ce qui est en train de tourner sur le système, du modèle exact du processeur (en raison des différentes tailles et dispositions de cache), de l'adresse à laquelle le code est chargé, etc.