StopWatch et QueryPerformanceCounter

Signaler
Messages postés
44
Date d'inscription
mardi 13 juin 2006
Statut
Membre
Dernière intervention
31 mars 2008
-
Messages postés
5
Date d'inscription
mercredi 21 mai 2008
Statut
Membre
Dernière intervention
15 décembre 2010
-
Salut !

J'ai tenté d'effectuer des mesures de temps de l'ordre de la µsec voir moins à l'aide de cet API ou avec la fonction du kernel32.

Malheureusement entre de simples instructions j'obtiens des temps énormes. J'ai testé de manière hardware confirmant le problème !
J'ai un processeur Intel dual core 2X 1,8 Ghz.

Dou ce problème peut-il provenir ? Processus qui tournent ?
Voici le code en question

class HighTimer
    {
        //IMPORT DES DLL'S
        [DllImport("KERNEL32")]
        private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);

        [DllImport("Kernel32.dll")]
        private static extern bool QueryPerformanceFrequency(out long lpFrequency);

        //VARIABLES
        private long start;
        private long stop;
        private long frequency;
        Decimal multiplier = new Decimal(1.0e9);

        public HighTimer()
        {
            if (QueryPerformanceFrequency(out frequency) == false)
            {
                // Fréquence non supportée
                throw new Win32Exception();
            }
        }

        //FONCTIONS
        public void Start()
        {
            QueryPerformanceCounter(out start);
        }

        public void Stop()
        {
            QueryPerformanceCounter(out stop);
        }

        public double Duration()
        {
            return (((double)(stop - start) * (double)multiplier) / (double)frequency);
        }

        public void sleep(double Time_in_nanoseconds)
        {
            //Temps de départ
            Start();

            //Sleeping
            do
            {
                Stop();   
            } while (Duration()<=Time_in_nanoseconds);
        }

    }

Lors d'un sleep, entre le Start() et le Stop(), voici les résultats obtenus :
        stop            15678315831066    long
        start            15678315567292    long
        frequency    1866700000            long
        stop - start   263774                    long

Merci !!!

@"#+++
A voir également:

9 réponses

Messages postés
5487
Date d'inscription
dimanche 4 août 2002
Statut
Membre
Dernière intervention
20 juin 2013
58
Relis peut-être un peu ce topic
Lutinoire t'as clairement dit qu'ils étaient wrapper dans la classe StopWatch. Donc plus besoin de faire des DllImport !

Tu fais simplement un Start, puis un Stop, et tu ensuites tu vas chercher le nombre de ticks qui sont passés.
Pour savoir la valeur d'un tick, regarder en fin du topic, je donne une solution...

<hr size="2" />VC# forever
Messages postés
5487
Date d'inscription
dimanche 4 août 2002
Statut
Membre
Dernière intervention
20 juin 2013
58
Bon je dois avouer que j'ai une fréquence un peu plus intéressante que toi, 2 millard 600 millions contre 1 millard 800 millions pour toi, mais tu devrais quand meme avec des mesures de l'ordre de la nanoseconde...

<hr size="2" />VC# forever
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
41
Et moi 3 milliards sur mon 3Ghz.

Dans mon code j'ai utilisé  [System.Security.SuppressUnmanagedCodeSecurity] c'est pas que pour faire joli.. ça evite de perdre un temps fou en remontant la pile des appels.
Messages postés
5487
Date d'inscription
dimanche 4 août 2002
Statut
Membre
Dernière intervention
20 juin 2013
58
Ca te fais un tick tout les 333 picosecondes contre 384 pour moi et 530 pour brixi.
Est-ce que c'est vraiment possible d'avoir des valeurs aussi petites (actuellement on peut trouver des 4Ghz sans trop de problemes => 250 psecondes) ??

<hr size="2" />VC# forever
Messages postés
44
Date d'inscription
mardi 13 juin 2006
Statut
Membre
Dernière intervention
31 mars 2008

J'utilise les imports pour rester compatible en 1.1.

La valeur du tick est évidemment liée à la fréquence du processeur et c'est tout à fait plausible les valeurs que tu donnes. Mais ca ne regle le problème en rien puisque l'important c'est le nombre de ticks entre mes deux instructions qui est énorme (263774). Je vais essayer de résoudre le souci avec la solution de lutinore...


Je vous tiens au courant ...


un grand merci encore ;-)

@"#+++
Messages postés
5487
Date d'inscription
dimanche 4 août 2002
Statut
Membre
Dernière intervention
20 juin 2013
58
Brixi> Pour un 3Ghz, ça fait environ un tick tout les 0.00000009 secondes ! Personnellement, j'aurais jamais pensé qu'on puisse être aussi précis. Je me demande même si cette valeur est vraiment représentative...

<hr size="2" />VC# forever
Messages postés
44
Date d'inscription
mardi 13 juin 2006
Statut
Membre
Dernière intervention
31 mars 2008

Je vois pas comment tu es arrivé à ce résultat pour ton tick.
un tick correspond à une incrémentation compteur.
Si tu utilises queryperformancecounter un tick correspond à l'inverse de la valeur retournée par queryperformancefrequency qui est tout simplement la fréquence de fonctionnement du timer. Celle-ci est soit celle du CPU soit du chipset soit... Je sais pas comment l'OS fait son choix mais quoiqu'il en soit c'est un timer hardware, il ne dépend pas des processus externes et c'est donc normal et 100% plausible d'avoir des ticks de l'orde de la nanoseconde. Idem pour le stopwatch sauf que c'est l'inverse de StopWatch.frequency qui donne la période d'un tick.
La durée de ton tick me parait bien élevée pour un 3Ghz.

Sinon même en utilisant         [System.Security.SuppressUnmanagedCodeSecurity]
j'ai toujours un nombre très élevé de ticks entre un start et un stop qui se suivent et je ne comprend pas pourquoi

@"#+++
Messages postés
44
Date d'inscription
mardi 13 juin 2006
Statut
Membre
Dernière intervention
31 mars 2008

Après plusieurs tests, je constate que ce résultat est des plus normal.
la durée entre un start() stop() est de quelques µsecondes.

@"#+++
Messages postés
5
Date d'inscription
mercredi 21 mai 2008
Statut
Membre
Dernière intervention
15 décembre 2010

Oui, en effet.
J'ai corrigé le calcul de Bidou sur le topic qu'il cite.
Cdt,
Jonathan