Mesure temporelle précise

Résolu
brixi69 Messages postés 44 Date d'inscription mardi 13 juin 2006 Statut Membre Dernière intervention 31 mars 2008 - 1 sept. 2006 à 16:06
hyperion56 Messages postés 5 Date d'inscription mercredi 21 mai 2008 Statut Membre Dernière intervention 15 décembre 2010 - 23 juil. 2009 à 16:59
Bonjour !

J'aimerais faire un échantillonnage sur le CTS d'un port COM à la µseconde près si c'est possible. Seulement je sais qu'il est difficile d'y arriver de part les interrupts windows etc...

Qqun a-t-il une solution pour m'aider ?

@"#+++

12 réponses

Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
5 sept. 2006 à 05:45
Non, StopWatch est un wrapper pour QueryPerformanceFrequency et QueryPerformanceCounter si le matériel supporte ces deux fonctions alors la précision est nettement inférieur à la milliseconde sinon c'est DateTime.Ticks qui est utilisé.

Une petite classe que j'avais fait avant .NET 2.0. En fait Microsoft m'a piqué mon code.

public sealed class HighTimer // .NET 1.1
{
    [System.Runtime.InteropServices.DllImport( "kernel32.dll"/*, SetLastError = true*/ )]
    [System.Security.SuppressUnmanagedCodeSecurity]
    private static extern bool QueryPerformanceFrequency( out long frequency );



    [System.Runtime.InteropServices.DllImport( "kernel32.dll"/*, SetLastError = true*/ )]
    [System.Security.SuppressUnmanagedCodeSecurity]
    private static extern bool QueryPerformanceCounter( out long count );



    [System.Runtime.InteropServices.DllImport( "winmm.dll" )]
    [System.Security.SuppressUnmanagedCodeSecurity]
    private static extern uint timeGetTime( );



    private bool high = false;
    private long ticks = 0;
    private long ticksPerSecond = 0;



    /// <summary>
    /// Indique si le timer est un timer de haute résolution.
    /// </summary>
    public bool HighResolution { get { return high; } }



    /// <summary>
    /// Nombre de graduations par milliseconde.
    /// </summary>
    public long TicksPerSecond { get { return ticksPerSecond; } }



    /// <summary>
    /// Nombre de graduations écoulées depuis le démarrage de Windows.
    /// </summary>
    public long Ticks
    {
        get
        {
            if ( high )
                QueryPerformanceCounter( out ticks );
            else
                ticks = ( long )timeGetTime( );



            return ticks;
        }
    }



    public HighTimer( ) : this( true ) { }



    /// <summary>
    /// Créer un timer haute résolution uniquement si le matériel supporte cette fonctionnalité.
    /// Dans le cas contraire le timer sera limité à 1000 graduations par seconde.
    /// </summary>
    public HighTimer( bool highResolution )
    {
        if ( highResolution )
            high = QueryPerformanceFrequency( out ticksPerSecond );



        if ( !high )
            ticksPerSecond = 1000L;



        this.ticks = this.Ticks; // JIT
    }
}
3
brixi69 Messages postés 44 Date d'inscription mardi 13 juin 2006 Statut Membre Dernière intervention 31 mars 2008
1 sept. 2006 à 16:31
Je pensais utiliser QueryPerformanceCounter/frequency etc ....

Bonne idée ?

MErci encore ;-)

@"#+++
0
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
4 sept. 2006 à 04:14
Salut,

oui, en NET 2.0 ces 2 fonctions sont encapsulées dans la classe StopWatch.
0
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
4 sept. 2006 à 08:46
Lutinore> La stopwatch se limite aux milisecondes non? Je ne crois pas qu'il y ait un moyen de mesurer des temps en dessous de la milliseconde....

<hr size="2" />VC# forever
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
5 sept. 2006 à 09:41
Donc dans la StopWatch, si je veux mesurer un temps en dessous de la miliseconde, j'utilise la Property Ticks? Si oui, comment savoir à combien équivaut un ticks ?

<hr size="2" />VC# forever
0
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
5 sept. 2006 à 15:38
En nanoseconde, je sais pas, c'est toi qui est bon en math.  Mais peu importe en fait.. un tick c'est un tick car stopwatch permet de mesurer un interval de temps sur un ordinateur donné, telle action prends 10000 ticks et une autre 20000.

ou bien

// temps écoulé sous forme de seconde fractionnaire.
MessageBox.Show( ( sw.ElapsedTicks / ( double )Stopwatch.Frequency ).ToString( ) );
0
brixi69 Messages postés 44 Date d'inscription mardi 13 juin 2006 Statut Membre Dernière intervention 31 mars 2008
5 sept. 2006 à 16:45
Exact !
Merci pour les infos

J'ai trouvé également quelques explications sur le site MSDN ...
> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag/html/scalenethowto09.asp

Une dernière chose. Serait il possible de créer une sorte de Timer haute résolution qui lors d'un Time-out donné permettrait de lancer un évenement ?

@"#+++
0
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
5 sept. 2006 à 18:27
Lutinore> Ok, ce que je connaissais pas (ou que j'avais pas encore découvert en fait) c'est l'existance de la Property static Frenquency. Avec ça, plus de problème, on peut sans autre savoir à quoi équivaiut un tick. Pour information à ceux qui ne le save pas :

"La valeur Frequency dépend de la résolution du mécanisme de minutage sous-jacent. Si le matériel et le système d'exploitation installés prennent en charge un compteur de performance haute résolution, la valeur Frequency reflète par conséquent la fréquence de ce compteur. Sinon, la valeur Frequency est basée sur la fréquence de l'horloge système." (msdn2)

J'ai fait un rapide teste chez moi pour savoir autour de quelle valeur on tournait :

long freq = System.Diagnostics.
Stopwatch.Frequency;

long nanoInSeconds = 1000000000L;

long val = freq / nanoInSeconds;

La valeur est de 2.6, c'est à dire que chaque ticks à lieu toute les 2.6 nanoseondes!
Et bien, c'est sacrément plus précis que ce que je pensais cette histoire...

<hr size="2" />VC# forever
0
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
5 sept. 2006 à 18:53
Euh non, ça veut dire que y'a 2.6 ticks par nanosecondes !
Ca ferait un tick toutes les 384 picosecondes ce qui me paraît presque impossible

<hr size="2" />VC# forever
0
hyperion56 Messages postés 5 Date d'inscription mercredi 21 mai 2008 Statut Membre Dernière intervention 15 décembre 2010
23 juil. 2009 à 16:24
> Bidou

Salut,

Je déterre ce vieux topic, désolé...

Je pense qu'il faut corriger le calcul ci-dessus.
En effet, pour connaître la période en secondes entre deux ticks, on prend l'inverse de la fréquence. Puis, on multiplie par 10^9 pour avoir la période en nanosecondes.

D'où ce code :

long frequence = Stopwatch.Frequency;
long periode = 1000000000L / frequence;
Console.WriteLine("période d'un tick = " + periode + " nanosecondes");


Sur ma machine je trouve un tick toutes les 279 nanosecondes.

Ai-je fait une erreur ?

Cordialement,

Jonathan
0
hyperion56 Messages postés 5 Date d'inscription mercredi 21 mai 2008 Statut Membre Dernière intervention 15 décembre 2010
23 juil. 2009 à 16:38
Oups, j'ai vu dans ce topic que Brixi69 a déjà rectifié l'erreur.

Cordialement,
0
hyperion56 Messages postés 5 Date d'inscription mercredi 21 mai 2008 Statut Membre Dernière intervention 15 décembre 2010
23 juil. 2009 à 16:59
D'ailleurs, j'ai fait la vérification suivante :

Stopwatch test = new Stopwatch();
// lancement du chrono
test.Start();
Thread.Sleep(1000);
// arrêt du chrono
test.Stop();

// durée mesurée en millisecondes
Console.WriteLine("millisecondes = " + test.ElapsedMilliseconds);
// durée mesurée en ticks
Console.WriteLine("ticks = " + test.ElapsedTicks);

// pour convertir les millisecondes en nanosecondes on multiplie par 10^6
// puis on divise par le nombre de ticks pour connaître la période d'un tick
long resultat = test.ElapsedMilliseconds * 1000000L / test.ElapsedTicks;

Console.WriteLine("période d'un tick = " + resultat + " nanosecondes");


Cdt,

Jonathan
0
Rejoignez-nous