none
Durée d'exécution d'un calcul RRS feed

  • 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

    samedi 14 avril 2012 16:30

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;
    

    dimanche 15 avril 2012 00:03
    Auteur de réponse
  • 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


    Suivez MSDN sur Twitter   Suivez MSDN sur Facebook


    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.

    mardi 17 avril 2012 08:51
  • 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
    mardi 17 avril 2012 15:32
  • 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.

    mardi 17 avril 2012 23:20
    Auteur de réponse
  • 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++


    mercredi 18 avril 2012 14:37
    Modérateur
  • 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
    jeudi 19 avril 2012 23:11
  • Est-ce que QueryPerformanceCounter répond à vos besoins ? Si oui, vous pouvez marquer cette discussion résolue. Si non n'hésitez pas à décrire votre problème.
    mardi 24 avril 2012 13:10
    Auteur de réponse
  • 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++

    mercredi 2 mai 2012 11:10
    Modérateur
  • 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.

    mercredi 2 mai 2012 12:53
    Auteur de réponse