Auteur de questions
Durée d'exécution d'un calcul

Discussion générale
-
Bonjour
Je travaille (en Visual C++ 2008) sur un programme arithmétique (donc aisément reproductible) et je souhaite déterminer avec le plus de précision possible les temps d’exécution de quelques unes de mes fonctions. Il faudrait donc une fonction "temps" qui stoppe le compteur quand l’ordinateur effectue d’autres tâches, ce que ne font pas les fonctions usuelles. Ce problème n’est pas nouveau et je pense que des solutions existent.
Merci de me les communiquer ou de me signaler une référence.
Très cordialement
- Type modifié Ciprian Duduiala jeudi 26 avril 2012 06:47 attente de feedback
Toutes les réponses
-
Avez vous essayé QueryPerformanceCounter ?
LARGE_INTEGER debut, fin, freq; QueryPerformanceFrequency(&frequence); // Une seule fois QueryPerformanceCounter(&debut); ... QueryPerformanceCounter(&fin); LONGLONG duree = fin.QuadPart - debut.QuadPart; LONGLONG milliseconds = duree * 1000L / frequence.QuadPart;
-
Bonjour, Sergeil17,
Est-ce que vous avez testé la solution proposée ? Merci de partager avec nous les résultats, afin que d'autres personnes avec le même problème puissent profiter de cette solution.
Bonne journée,
Cipri
Ciprian DUDUIALA, MSFT  
•Nous vous prions de considérer que dans le cadre de ce forum on n’offre pas de support technique et aucune garantie de la part de Microsoft ne peut être offerte.
-
Bonjour à tous
Je suis en train d’essayer de comprendre et de tester les diverses informations reçues (j’ai posé la même question sur le forum analogue anglais …). Cette phase n’est pas terminée mais pour garder ce post actif, voici un petit résumé de la situation, telle que je la comprends : merci de me corriger en cas d’erreur.
* les fonctions « temps » usuelles de Windows donnent le temps légal, basé sur le temps UCT (ou une différence entre ce temps et un temps pris comme origine). Une différence de temps (dt) obtenu par un programme du genre
t_begin = fontion_temps() ;
// partie du programme dont on mesure le temps d’exécution
....
t_end = fontion_temps() ;
dt = t_end – t_begin ;
donnera le temps d’exécution cherché AUGMENTE d’un temps additionnel correspondant aux diverses tâches effectuées en permanence par Windows : ce temps additionnel crée donc un « bruit » qu’il serait souhaitable d’éliminer.
* les fonctions clock() et GetTickCount() n’éliminent pas le bruit. De plus elles sont très imprécises (15 ms) : exécuter Sleep(1) ou Sleep(10) donnera dans les deux cas dt = 15 ms. Il n’y a aucun réglage possible et la situation s’aggrave encore si on doit cumuler un grand nombre de dt partiels pour avoir un dt global.
* La fonction QueryPerformanceCounter () n’élimine pas le bruit mais c’est une fonction extrêmement précise qui possède de plus des réglages permettant de le réduire (voir ici). Exemple d’utilisation sous une forme simple (voire simpliste) :
double Qtime(void)
{
LARGE_INTEGER frequency ;
LARGE_INTEGER t ;
QueryPerformanceFrequency(&frequency);
QueryPerformanceCounter(&t);
return(t.QuadPart * 1000.0 / frequency.QuadPart) ;
}
* la fonction GetProcessTimes() (cf. la doc de Visual)
BOOL WINAPI GetProcessTimes(
__in HANDLE hProcess,
__out LPFILETIME lpCreationTime,
__out LPFILETIME lpExitTime,
__out LPFILETIME lpKernelTime,
__out LPFILETIME lpUserTime
);
UserTime donne le temps d’exécution du programme et semble donc résoudre le problème (voir ici). Un petit bémol, la précision est faible : 15ms.
A suivre.
- Modifié sergeil17 mardi 17 avril 2012 20:09
-
QueryPerformanceCounter est la plus précise des méthodes pour obtenir une durée d'exécution, plus précise que GetProcessTimes, et surtout que GetTickCount. GetTickCount n'est basé que sur l'horloge de Windows, et ne tient pas du tout compte du multitâche.
Maintenant il faut aussi prendre en compte le fait que Windows n'est pas un OS temps-réel (destiné à effectuer des mesures de temps précises). Essayer de mesurer des temps inférieurs à 10 ms n'est pas raisonnable, c'est tomber dans la marge d'erreur. Windows n'est pas fait pour cela.
-
Vous ne pouvez pas dire que le travail du Kernel Windows ou des autres processus, dont les Services que vous utilisez peut-être directement ou indirectement soient du bruit.
Vous avez besoin de tout cela pour que votre programme tourne.
Le temps passé par le Kernel pour satisfaire vos appels système comme la lecture ou l'écriture sur le disque, n'ont pas à être pris en compte ?
sans compter le caractère extrêmement asynchrone de ce genre d'action,
et que le prefetching des lectures de fichier de l'OS permet d'amoindrir (mais il paraît que c'est du bruit ;-) )
C'est comme vouloir faire une Formule1 qui gagne des grands prix juste en optimisant sa vitesse de pointe, malheureusement, il y a des virages sur les circuits. ;-)
Il est possible d'avoir des informations bien plus précises que celles fournies par les API Windows, mais avant de vous engagez dans du code assembleur non portable entre CPU, je pense qu'il faudrait mieux que vous vous tourniez vers les programmes de profiling, au lieu de bricoler un profileur du paléolithique. ;-)
Paul Bacelar, Ex - MVP VC++
- Modifié Paul BacelarModerator mercredi 18 avril 2012 14:50
-
Bonjour Paul
Mon problème, vous l’avez compris, n’est pas tant de mesurer le temps CPU d’une fonction que de comparer les temps CPU de deux fonctions concurrentes et il est clair qu’un logiciel de profilage est la solution parfaite. Mais y a-t-il un tel logiciel sur Visual studio Express (si oui, merci de m’indiquer un lien me permettant de l’utiliser) ou bien m’invitez-vous à changer pour un EDI en possédant un ? A défaut, on « bricole » !
En ce qui concerne ce que j’appelle un « bruit », vous ne devriez pas vous en indigner comme cela. Toute perturbation aléatoire (je pense que cette précision est importante) de la valeur d’une grandeur que l’on cherche à mesurer peut être appelée un « bruit », sans aucune connotation péjorative et sans jugement de valeur quant aux causes de cette perturbation. Pour la réception des ondes radio, les éruptions solaires sont un « bruit » mais personne ne remet en cause l’importance du soleil !
Les fonctions dont on cherche le temps d’exécution ne devraient pas comporter d’éléments aussi peu réguliers que les accès disque mais admettons : s’ils font partie de ma fonction, il n’y aucune raison de les inclure dans le « bruit » : idem pour toute autre action déclenchée par la fonction. Mais si durant son exécution, Windows effectue des opérations étrangères à ma fonction (tentative de mise à jour, vérification de routine sur des fichiers, etc.) alors oui, il faut inclure ces temps d’exécution dans le « bruit ».
Cordialement.
- Modifié sergeil17 jeudi 19 avril 2012 23:12
-
-
Les profilers sous VS, c'est pas ça qui manque.
Il y en a déjà un dans les versions payant de VS.
Il y a aussi
AMD CodeAnalyst :http://developer.amd.com/tools/codeanalyst/Pages/default.aspx
etc...
Voici une discussion mentionnant pas mal de ces profilers
http://stackoverflow.com/questions/67554/whats-the-best-free-c-profiler-for-windows-if-there-are
Pourquoi "bricoler" ???
Paul Bacelar, Ex - MVP VC++
-
Le profiler Microsoft n'est dispo que dans les versions Premium et Ultimate, pas dans la version Profesionnal.
Ensuite, pour un besoin précis, il peut être plus simple d'ajouter une ligne TRACE avec QueryPerformanceCounter que d'installer un logiciel et apprendre à l'utiliser.
L'un et l'autre ont leur usage je pense.