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 :

Avoir un Sleep() précis pour courte durée?


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 3
    Par défaut Avoir un Sleep() précis pour courte durée?
    Bonjour,
    pour une appli en C/C++, j'aurais besoin qu'un thread se mette en pause pour une durée courte (1,2,5 ou 10ms) de facon fiable. Mon but étant de faire un simulateur, cette précision est importante.
    En faisant des tests avec des fonctions qui regarde l'heure :
    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
    static LARGE_INTEGER freq;
    static bool init_fq(false);
     
    double current_time()
    {
     if (!init_fq) {
      QueryPerformanceFrequency(&freq);
      init_fq = true;
     }
     QueryPerformanceCounter(&count);
     
    return static_cast<double>(count.QuadPart) / freq.QuadPart;
    }
     
    void attendre(unsigned long time){
     double start = 1000*current_time(); // en millisecondes.
     Sleep(1);
     printf("TIME after: %f\n",1000*current_time()-start);
    }
    Je vois qu'un sleep(1) dure environs 1.8 ms (l'appel de la fonction current_time est négligeable, de l'ordre de la centime de millisecondes)
    un Sleep(2) dure 2.8ms également en moyenne (avec des rares pointes à 17-33ms).
    J'ai lu de nombreuses fois sur le net que les sleep courts sont imprécis (et je l'ai bien constaté) puisqu'ils bloquent le thread pour une durée minimale.

    Pour contourner ce problème, j'ai essayé un truc du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void attendre(unsigned long time){
     double start = 1000*current_time(); // en millisecondes.
     SetThreadPriority(GetCurrentThread(),15);
     
     while (1000*current_time() < (start+time)){
     }
     
     SetThreadPriority(GetCurrentThread(),0);
     printf("TIME after: %f\n",1000*current_time()-start);
    }
    J'arrive à obtenir des temps d'attentes tout à fait raisonnables (1.00ms) et assez stable, mais j'ai également des pointes ponctuelles au dela des 10-20ms d'attentes.
    Le fait de changer de priorité le thread n'a en fait que peu d'influence, surtout que le but n'est pas de bloquer le reste de la machine sur laquelle tourne une application serveur video et une socket de réception sur un thread parallèle.

    J'ai meme essayé de combiner un Sleep(1) puis while (1000*current_time() < (start+time)) (pour une attente de 2ms par exemple..) Là encore je suis la plupart du temps stable, mais avec les mêmes pointes.

    Y a-t-il une solution pour éviter d'avoir des pointes d'attentes si élevée ou moins fréquement?

    Le fait d'avoir 3 choses qui tournent en même temps sur le pc (Win XPau passage) est surement une des clés du problèmes, mais pas de la solution.
    Passer sur un ensemble complètement linéaire (serveur+socket+appli en un seul thread) résoudrait-il le problème?(ou alors de toute facon, le fait d'avoir windows et n'importe quoi derrière ca plante tout..?)

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 14
    Par défaut
    J'ai déja eu à traiter un problème (sous linux) qui m'a confronté à l'imprécision des Sleep.

    Le problème n'est pas tant dans le fait de chercher à magouiller sur le Sleep (sous linux il existe un "nanosleep" pour les Sleep de courte duré, à voir sous windows, mais ça ne change rien au problème), c'est dans la façon dont l'ordonnanceur de ton OS gère ses processus, et tu ne peux pas énormèment intervenir dessus. Au mieux tu dois pouvoir influencer sur sa priorité voir sur la façon dont il gère l'ordonancement de processus.

    Pour info sur mon problème (en espérant que ça t'aide), la principale perte de précision dans les Sleep venait du temps nécessaire à l'OS pour effectuer le changement de contexte (mettre le processus endormie en arrière plan, laisser éventuellement un autre s'exécuter, puis à la fin du Sleep le réveiller et recharger son contexte), cette durée était d'au minimum quelques ms, donc impossible de passer outre cette barrière et d'avoir un temps de réponse précis et déterminé. (de plus étant sur un système multi-tâche, le processus peut à tout moment être interrompue pour laisser un autre plus prioritaire s'exécuter le temps de quelques ms, pour une utilisation "bureautique" de l'informatique ça ne s'y connais pas, mais pour faire de la précision c'est catastrophique puisque les temps d'exécution varieront nécessairement de quelques ms, c'est pour ça qu'il existe des noyaux dit temps réels qui garantissent ce genre de précision)

    Pour résoudre mon problème je suis passé par un noyau temps réel (RT-linux), qui te permet de gérer de façon précise le temps, nottement en utilisant son propre gestionnaire d'intérruption (j'ai ainsi pu avoir des précisions à la microseconde).

    Je ne sais pas ce qu'il en est du temps réel sous windows, j'espère t'avoir donné une piste !

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 3
    Par défaut
    Ok, merci pour tes précisions.
    Malheureusement, ca me conforte un peu dans l'idée que je peux pas faire grand chose avec windows.
    Quelqu'un a déja fait fasse à ce problème sur windows?

  4. #4
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,
    Citation Envoyé par Arateris
    Ok, merci pour tes précisions.
    Malheureusement, ca me conforte un peu dans l'idée que je peux pas faire grand chose avec windows.
    Quelqu'un a déja fait fasse à ce problème sur windows?
    Je n'ai jamais fait face à ce problème, et je n'ai aucune solution à te proposer, mais je tiens à souligner le fait que, ainsi que l'a sous entendu Espadrilles, c'est clairement insoluble sous windows...

    Ainsi qu'il l'a fait remarquer, la seule solution est de passer à un noyau (et donc à un OS) spécialement prévu pour le temps réel, et il n'y en a aucun dans la game de microsoft, du moins à ma connaissance.
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #5
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Il n'y en a pas directement dans la gamme microsoft (même si je crois que windows CE est un peu meilleur que windows en terme de stabilité du cadencement, jamais testé personnellement), mais il existe RTX qui est une sous couche à windows (un peu comme RT-Linux est une sous couche de Linux) qui peut assurer une transition plus facile.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  6. #6
    Expert confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par défaut
    En même temps... tout dépend de ce que tu veux faire.

    Un simulateur, c'est un peu vague (dans le monde virtuel, tout programme n'est-il pas une forme de 'simulateur' ? ).

    Par exemple, dans un jeu, la simulation graphique est schedulée ("aussi vite que possible, mais pas au dela du refresh-rate, 60Hz par exemple"), la simulation d'entrée de l'utilisateur est en général tous les 0.1s, et la physique... ca dépend.
    Un simulateur physique est en général mis à jour "au moins toutes les 0.1s, et pas au delà de 0.5s" pour des raisons de stabilité des modèles.
    A noter que certains objets du simulateur physque peuvent avoir des traitements spécifiques.

    Dans tous les cas, c'est très très rare qu'on ai besoin d'une précision de 1ms quelque part, il y a tant de facteur qui entre en jeu, que rien ne peut assurer une synchronisation de tous les éléments à 1ms ! Même les informations de la souris ne parviennent pas à ce rythme à l'utilisateur... et un écran LCD peut mettre 3/4ms à afficher le résultat.

    Le seul moment ou j'ai jamais eu besoin d'une telle précision était dans l'implémentation software d'une boucle retour vidéo.

Discussions similaires

  1. Peut-on avoir deux fichier .htaccess pour 2 urlrewriting différents pour 1 même site
    Par JackBeauregard dans le forum Serveurs (Apache, IIS,...)
    Réponses: 3
    Dernier message: 30/09/2006, 08h35
  2. Avoir deux variables constantes pour requétes sql
    Par Talies dans le forum Requêtes et SQL.
    Réponses: 18
    Dernier message: 13/06/2006, 15h17
  3. [Appli] Recherche d'un type d'objet précis pour interface
    Par superpatate dans le forum Interfaces Graphiques en Java
    Réponses: 3
    Dernier message: 05/08/2005, 12h02
  4. Fonction du genre delay, sleep, wait pour attendre 1000ms
    Par FrankOVD dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 28/06/2005, 17h17

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