IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Amélioration Hyperthreading temps de test


Sujet :

C#

  1. #1
    Membre régulier
    Inscrit en
    Novembre 2013
    Messages
    229
    Détails du profil
    Informations forums :
    Inscription : Novembre 2013
    Messages : 229
    Points : 109
    Points
    109
    Par défaut Amélioration Hyperthreading temps de test
    Bonjour

    Voila un bout de programme que j'essaie de faire , j'aimerais avoir qques idées pour améliorer.

    Le but étant de mesure le temps entre 2 mesure de multimètre et un génération de fréquence :

    Je mesure le temps entre le moment ou je déclenche les 2 thread et le moment je recois la 2eme mesure

    Les temps varie de 16 ms a un 100 ms

    Comment peut on améliorer SVP ?
    Peut détecter la fin des thread ?

    Le but étant de tendre au maximum vers Les 16 ms


    init sert a initialiser les appareils (ne compte pas dans le temps de test)
    threadDMM1 et threadDMM2 mesure de tensions

    Merci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    namespace toto_C
    {
        public partial class Form1 : Form
        {
            public string DMM1 = "GPIB0::7::INSTR";
            public string DMM2 = "GPIB0::22::INSTR";
            public string PS1 = "GPIB0::5::INSTR";
            public string GBF1 = "GPIB0::9::INSTR";
            public string result = "toto";
            ResourceManager managerDMM1 = new ResourceManager();
            FormattedIO488 connectionDMM1 = new FormattedIO488();
     
            ResourceManager managerDMM2 = new ResourceManager();
            FormattedIO488 connectionDMM2 = new FormattedIO488();
     
            ResourceManager managerGBF1 = new ResourceManager();
            FormattedIO488 connectionGBF1 = new FormattedIO488();
     
            Stopwatch compteur = new Stopwatch();
            public long TempMesure;
            public int tour = 0;
            public long total = 0;
            public long moyenne = 0;
            public int debut, fin,diff;
     
            public Form1()
            {
                InitializeComponent();
     
            }
            delegate void SetTextCallback1(string text);
            delegate void SetTextCallback2(string text);
     
            Thread mesureOnDMM1;
            Thread mesureOnDMM2;
            private void Form1_Load(object sender, EventArgs e)
            {
     
     
            }
     
            private void threadDMM1()
            {
     
                connectionDMM1.WriteString("READ?", true);
                this.SetText1(connectionDMM1.ReadString());
     
     
            }
     
            private void threadDMM2()
            {
     
                connectionDMM2.WriteString("READ?", true);
                this.SetText2(connectionDMM2.ReadString());
     
     
            }
     
            private void button1_Click(object sender, EventArgs e)
            {
     
                init();
            }
            private void init()
            {
     
                connectionDMM1.IO = (IMessage)managerDMM1.Open(DMM1, AccessMode.NO_LOCK, 0, "");
                connectionDMM2.IO = (IMessage)managerDMM2.Open(DMM2, AccessMode.NO_LOCK, 0, "");
                connectionGBF1.IO = (IMessage)managerGBF1.Open(GBF1, AccessMode.NO_LOCK, 0, "");
     
                connectionDMM1.IO.Clear();
                connectionDMM2.IO.Clear();
                connectionGBF1.IO.Clear();
     
                connectionDMM1.WriteString("*IDN?", true);
                textDMM1.Text = connectionDMM1.ReadString();
     
                connectionDMM2.WriteString("*IDN?", true);
                textDMM2.Text = connectionDMM2.ReadString();
     
                connectionGBF1.WriteString("*IDN?", true);
                textGBF1.Text = connectionGBF1.ReadString();
     
                connectionDMM1.WriteString("CONF:VOLT:DC 10,0.003", true);
                connectionDMM2.WriteString("CONF:VOLT:DC 10,0.003", true);
     
     
            }
            private void close()
            {
     
                connectionDMM1.IO.Close();
                connectionDMM2.IO.Close();
                connectionGBF1.IO.Close();
            }
     
     
            private void MesureDMM1()
            {
     
                compteur.Start();
                connectionDMM1.WriteString("READ?", true);
                textBox2.Text = connectionDMM1.ReadString(); 
                compteur.Stop();
                total = total + compteur.ElapsedMilliseconds;
                compteur.Reset();
     
     
            }
     
            private void MesureDMM2()
            {
     
                compteur.Start();
                connectionDMM2.WriteString("READ?", true);
                textBox3.Text = connectionDMM2.ReadString();
                compteur.Stop();
                total = total + compteur.ElapsedMilliseconds;
                compteur.Reset();
     
     
            }
     
     
     
     
     
            private void button6_Click(object sender, EventArgs e)
            {
                timer2.Enabled = true;
            }
     
     
            private void timer2_Tick(object sender, EventArgs e)
            {
                debut = Environment.TickCount;
                this.mesureOnDMM1 = new Thread(new ThreadStart(this.threadDMM1));
                this.mesureOnDMM1.Priority = ThreadPriority.Highest;
                this.mesureOnDMM2 = new Thread(new ThreadStart(this.threadDMM2));
                this.mesureOnDMM2.Priority = ThreadPriority.Highest;
                this.mesureOnDMM1.Start();
                this.mesureOnDMM2.Start();
            }
     
     
     
            private void SetText1(string text)
            {
                // InvokeRequired required compares the thread ID of the
                // calling thread to the thread ID of the creating thread.
                // If these threads are different, it returns true.
                if (this.textBox2.InvokeRequired)
                {
                    SetTextCallback1 d = new SetTextCallback1(SetText1);
                    this.Invoke(d, new object[] { text });
                }
                else
                {
                    this.textBox2.Text = text;
                }
     
     
            }
     
            private void SetText2(string text)
            {
                // InvokeRequired required compares the thread ID of the
                // calling thread to the thread ID of the creating thread.
                // If these threads are different, it returns true.
                if (this.textBox3.InvokeRequired)
                {
                    SetTextCallback2 d = new SetTextCallback2(SetText2);
                    this.Invoke(d, new object[] { text });
                }
                else
                {
                    this.textBox3.Text = text;
     
                    fin = Environment.TickCount;
                    diff = fin - debut;
                    if (diff > 50)
                    {
                        timer2.Enabled = false;
                        MessageBox.Show(diff.ToString());
                    }
                    this.textBox4.AppendText(diff.ToString() + "\n");
                    /*MessageBox.Show(diff.ToString());*/
                }
     
     
     
     
            }
        }
    }

  2. #2
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Bonjour.

    * Tu devrais mesurer la durée de ReadString() seule, sans la mise à jour de l'UI.

    * Démarrer un thread est une tâche coûteuse. Utilise deux theads permanents avec une boucle while.

    * Si tes deux threads sont en priorité highest, tu cannibalises peut-être le temps de MAJ de l'UI et du timer. Tout dépend de la façon dont ReadString() est codée et du scheduler de Windows.

    * Avoir recours à plusieurs threads n'est pas forcément judicieux dans ce cas-ci puisque ReadString() dure peu de temps en principe et puisqu'il ne s'agit pas d'une consommation de temps CPU mais d'une attente IRQ. Par ailleurs l'appel sera a priori instantané si une valeur est déjà en attente. Tout dépend de l'implémentation de ReadString(). Essaye une solution à un seul thread, avec une boucle while qui lit les deux connexions, met à jour l'UI, puis enfin appelle Application.DoEvents().

    * Tu peux changer la résolution du timer Windows, ce qui affecte le scheduler. Voir timeBeginPeriod (MSDN).

    * Concernant les événements interthreads tu peux soit utiliser une attente active (polling - une boucle while surveillant un booléen volatile), soit une attente passive avec EventWaitHandle (le thread appelant Wait() est mis en sommeil en attendant l'appel de Set()).

  3. #3
    Membre régulier
    Inscrit en
    Novembre 2013
    Messages
    229
    Détails du profil
    Informations forums :
    Inscription : Novembre 2013
    Messages : 229
    Points : 109
    Points
    109
    Par défaut
    Ou lalal , tu a l'air d’être un connaisseur (lol)


    Merci de tes réponses , je vais essayer de décoder tout cela,

    Je vais commencer par l'idée d'un thread.

    grand merci a toi

  4. #4
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 757
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 757
    Points : 10 541
    Points
    10 541
    Billets dans le blog
    21
    Par défaut
    Bonjour,

    Je pense que DonQuiche a dit à peu près tous les points à envisager.

    Parmis ceux à prioriser (sans jeu de mot) :
    • la réutilisation des tâches, au lieu de les créer (car la création d'une tâche coûte effectivement cher !). Tu peux soit créer les threads une bonne fois pour toute, soit utiliser le pool de thread (cf. la série d'articles que j'ai écrits dessus)
    • modifier la résolution du timer de Windows n'est pas recommandé. Cela affecte tout le système et pas seulement l'application. A n'utiliser que si on sait ce que l'on fait !


    Au passage, le titre de la discussion est trompeur. Rien à voir avec l'hyperthreading
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  5. #5
    Membre régulier
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2011
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2011
    Messages : 79
    Points : 118
    Points
    118
    Par défaut
    Bonjour,

    Est-il possible de récupérer une info de temps écoulé directement auprès des appareils de mesure ?

    Cela permettrait de ne plus se baser sur l'horloge du PC qui à mon sens ne vaut pas grand chose en
    dessous des 50 voir 100 msec...

    A titre d'exemple, je pilote des contrôleurs temps réel à plusieurs kHz de fréquence, et toute la mesure
    de temps est déportée hors PC. Les données qui remontent vers le PC sont horodatées, avec bien sur
    une plus grande fiabilité que l'horloge du PC !

    Concernant la priorité des Thread, on peut gagner encore un petit peu en changeant de langage :
    en C++, on a accès à la valeur TIME_CRITICAL, qui est supérieure à Highest en .NET

    Je ne sais d'ailleurs pas pourquoi cela n'a pas été reconduit dans .NET...

    @+,
    Philippe

  6. #6
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 757
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 757
    Points : 10 541
    Points
    10 541
    Billets dans le blog
    21
    Par défaut
    Citation Envoyé par phil_tema Voir le message
    Concernant la priorité des Thread, on peut gagner encore un petit peu en changeant de langage :
    en C++, on a accès à la valeur TIME_CRITICAL, qui est supérieure à Highest en .NET

    Je ne sais d'ailleurs pas pourquoi cela n'a pas été reconduit dans .NET...
    La réponse est assez simple. Un thread Windows et un thread .Net sont deux notions différentes. Un thread Windows peut exécuter plusieurs threads .Net et un thread .Net peut s'exécuter sur plusieurs Thread Windows tout au long de sa vie. Il n'y a pas de corrélation entre les deux.

    La seule chose dont on soit sûre, c'est qu'un thread .Net, lorsqu'il est en cours d'exécution, s'exécute sur un seul thread Windows en même temps, mais peut très bien être interrompu et reprendre son exécution sur un autre thread Windows.
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  7. #7
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Citation Envoyé par phil_tema Voir le message
    Cela permettrait de ne plus se baser sur l'horloge du PC qui à mon sens ne vaut pas grand chose en
    dessous des 50 voir 100 msec...
    Tu confonds la résolution du timer Windows, qui n'est mis à jour que toutes les 15,6 ms par défaut, avec la résolution de l'horloge du PC, de l'ordre de 100ns.

    Ici le post original utilise correctement Stopwatch, qui exploite directement l'horloge matérielle et non un timer Windows. Ses mesures sont donc précises.

  8. #8
    Membre régulier
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2011
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2011
    Messages : 79
    Points : 118
    Points
    118
    Par défaut
    Merci à DonQuiche pour cette info que je ne connaissait pas. Cela dit, l'instant de mesure dépend toujours du PC, avec tous les aléas possibles (% proc, accès disque...)
    Mon idée était de faire transférer l'aspect "temps" au matériel qui a probablement beaucoup moins de chose à faire qu'un PC. Après on peut toujours chicaner sur la précision
    d'une horloge du matériel !

    Merci aussi à F. Dorin, même si je n'ai pas saisi la subtilité... Je ne comprend pas comment un thread .NET une fois lancé peut être interrompu et exécuté par un autre thread windows.

    Philippe

  9. #9
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 757
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 757
    Points : 10 541
    Points
    10 541
    Billets dans le blog
    21
    Par défaut
    Citation Envoyé par phil_tema Voir le message
    Merci aussi à F. Dorin, même si je n'ai pas saisi la subtilité... Je ne comprend pas comment un thread .NET une fois lancé peut être interrompu et exécuté par un autre thread windows.
    Vois les threads Windows comme les processeurs pouvant exécuter les threads .Net
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  10. #10
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Citation Envoyé par François DORIN Voir le message
    Vois les threads Windows comme les processeurs pouvant exécuter les threads .Net
    En réalité dans l'implémentation standard un thread managé est simplement un wrapper autour d'un thread Windows.

    Mais puisque la plateforme a été conçue pour être universelle, portable sur d'autres OS ou pour utiliser des coroutines sous Windows, on ne peut pas présumer de l'implémentation sous-jacente. Même si dans 99,99999% des cas c'est un thread natif Windows/POSIX.

    En pratique je ne sais pas s'il existe une VM basée sur des coroutines mais dans un tel cas un thread n'y rendrait jamais la main spontanément, ce qui violerait les spécifications dotnet et rendrait invalide des programmes correctement conçus.

Discussions similaires

  1. Amélioration du temps de calcul pour creer des figures
    Par comoliv02 dans le forum MATLAB
    Réponses: 2
    Dernier message: 17/10/2007, 11h23
  2. Améliorer le temps d'éxécution d'un script
    Par totoc1001 dans le forum MATLAB
    Réponses: 8
    Dernier message: 21/12/2006, 10h46
  3. CpteDom - amélioration des temps de réponse
    Par Domi2 dans le forum Access
    Réponses: 2
    Dernier message: 25/10/2006, 14h29
  4. [Optimisation] Améliorer les temps de réponse
    Par n@n¤u dans le forum JOnAS
    Réponses: 5
    Dernier message: 24/08/2006, 11h04
  5. Améliorer le temps d'ouverture d'un fichier ?
    Par Sunchaser dans le forum C++Builder
    Réponses: 1
    Dernier message: 05/06/2006, 22h19

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo