2009-12-05 4 views
2

En ce moment, je charge un fichier puis en utilisant gettimeofday et le suivi du temps CPU avec tv_usecsommeil (0)? temps cohérent dans le code?

Mes résultats varient, je reçois 250 à 280 mais parfois 300 ou 500. Je me suis endormi et j'ai dormi (0) et (1) sans succès. Le temps varie encore énormément. Je pensais que dormir (1) (secondes sous Linux, pas les fenêtres de sommeil en ms) l'aurait résolu. Comment puis-je suivre le temps d'une manière plus cohérente pour les tests? Peut-être devrais-je attendre d'avoir des données de test beaucoup plus grandes et un code plus complexe avant de commencer les mesures?

Répondre

4

L'interface actuellement recommandée pour Linux sous Linux (et POSIX en général) est clock_gettime. Voir la page de manuel.


clock_gettime(CLOCK_REALTIME, struct timespec *tp) // for wall-clock time 
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, struct timespec *tp) // for CPU time 

Mais lisez la page man. Notez que vous devez lier avec -lrt, car POSIX le dit, je suppose. Peut-être pour éviter les conflits de symboles dans -lc, pour les anciens programmes qui ont défini leur propre clock_gettime? Mais les bibliothèques dynamiques utilisent des symboles faibles ...

La meilleure fonction de sommeil est nanosleep. Il ne dérange pas avec des signaux ou des conneries comme le sommeil. Il est défini pour juste dormir, et ne pas avoir d'autres effets secondaires. Et cela vous indique si vous vous êtes réveillé tôt (par exemple à partir de signaux), vous n'avez donc pas besoin d'appeler une autre fonction temporelle.

Quoi qu'il en soit, vous allez avoir du mal à tester un représentant de quelque chose d'aussi court qu'un appel système. Il y a énormément de possibilités de variation. par exemple. le planificateur peut décider qu'un autre travail doit être fait (peu probable si votre processus vient de démarrer, vous n'aurez pas encore utilisé votre timelice). Le cache de l'UC (L2 et TLB) est facilement possible.

Si vous disposez d'une machine multicœur et d'un banc d'essai à un seul thread pour le code que vous optimisez, vous pouvez lui attribuer une priorité en temps réel sur l'un de vos cœurs. Assurez-vous de choisir le noyau qui ne gère pas les interruptions, sinon votre clavier (et tout le reste) sera verrouillé jusqu'à ce qu'il soit terminé. Utilisez taskset (pour l'épinglage à une CPU) et chrt (pour le réglage du prio en temps réel). Voir ce mail j'ai envoyé à gmp-devel avec cette astuce: http://gmplib.org/list-archives/gmp-devel/2008-March/000789.html

Oh oui, pour le moment le plus précis, vous pouvez utiliser rdtsc vous (sur x86/AMD64). Si vous n'avez pas d'autres appels système dans ce que vous faites, ce n'est pas une mauvaise idée. Prenez un cadre d'analyse comparative pour mettre votre fonction dans. GMP en a un assez décent. Il n'est peut-être pas bien configuré pour les fonctions de benchmarking qui ne sont pas dans GMP et qui s'appellent mpn_whatever. Je ne me souviens pas, et ça vaut le coup d'oeil.

2

Essayez-vous de mesurer combien de temps il faut pour charger un fichier? Habituellement, si vous testez la performance avec un peu de code qui est déjà assez rapide (sous-seconde), alors vous voudrez répéter le même code un certain nombre de fois (disons un millier ou un million), temps le tout, puis diviser le temps total par le nombre d'itérations. Cela dit, je ne suis pas tout à fait sûr de ce que vous utilisez sleep() pour. Pouvez-vous poster un exemple de ce que vous avez l'intention de faire?

1

Je recommande de mettre ce code dans une boucle for. Exécutez-le sur 1000 ou 10000 itérations. Il y a des problèmes avec ceci si vous faites seulement quelques instructions, mais cela devrait aider.

De plus grands ensembles de données aident également bien sûr.

sommeil va désélectionner votre thread à partir du processeur. Il ne compte pas avec précision le temps avec précision.