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 :

comment faire une pause précise (1/10000 s)


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Février 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 42
    Par défaut comment faire une pause précise (1/10000 s)
    Bonjour,

    Je cherche une méthode *fiable* pour faire des pauses précises au 1/10 de milliseconde (voire à 1 milliseconde).

    J'ai exclu usleep qui est d'une précision ridicule (ne descend pas en dessous de 15 ms, sauf si j'indique usleep(1), alors là le temps d'attente varie de 1/2 à 1 microseconde.


    La seule solution que j'ai trouvé actuellement est d'utiliser l'interruption RDTSC des x86 et faire une boucle d'attente. Cette interruption indiquant un nombre de cycles d'horloge, il me faut une base de temps (nombre de cycles pour une période donnée).

    Je procède donc comme suit :

    je récupère une 1ère valeur d'horloge
    je fais un "usleep(500000)" qui semble être assez précis pour cette durée
    je récupère la 2ème valeur d'horloge
    j'en déduit un nombre de cycles pour une micro-seconde, et enfin, je peux faire une boucle d'attente.

    Cette solution ne me convient cependant guère, d'une part parce que cela occupe 100% du cpu, d'autre part car je me base sur le fait que usleep(500000) est toujours juste (ce qui n'est apparement pas le cas sur un vieux portable PIII) et que la frequence du cpu ne varie pas (ce qui est faux par exemple sur une plateforme centrino).

    Je cherche donc une solution plus fiable, et m'en remet à vos conseils.

    Je précise que je dois faire un code compilable pour windows et linux.

    Note : J'ai tenté de voir comment procedait la librairie LiveMedia (utilisée par VLC pour le streaming) pour appliquer le delai d'attente entre deux paquets. Mais je n'arrive pas à saisir comment cela fonctionne. (S'il y en a qui connaissent, je pense que ça se passe dans DelayQueue.cpp)

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Deux questions :

    1/ Pourquoi as-tu besoin d'une telle précision ?
    2/ Qu'attendrais-tu comme résultat d'une pause de 0.1 ms, alors que ces systèmes d'exploitation ont des quantum de temps de plusieurs dizaines de millisecondes par processus ?

  3. #3
    Membre expérimenté
    Avatar de David Fleury
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    253
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 253
    Par défaut
    Citation Envoyé par Laurent Gomila
    Deux questions :

    2/ Qu'attendrais-tu comme résultat d'une pause de 0.1 ms, alors que ces systèmes d'exploitation ont des quantum de temps de plusieurs dizaines de millisecondes par processus ?

    juste pour ma culture, ce ne serait pas 15 ms pour Windows XP ?
    (disons pour un réglage de l'OS par défaut)

  4. #4
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Citation Envoyé par Hylvenir
    juste pour ma culture, ce ne serait pas 15 ms pour Windows XP ?
    (disons pour un réglage de l'OS par défaut)
    Personnellement je n'en ai aucune idée. J'ai souvenir de chiffres tels que 10, 20 ou 50, mais je suis incapable de les remettre dans un contexte précis.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Février 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 42
    Par défaut
    J'ai besoin de ces pauses pour implémenter un protocole de streaming (c'est un projet de cours) RTP/RTCP.

    Je dois donc diffuser des paquets à intervals réguliers qui devraient à priori être compris entre 15 et 100 ms (la valeur choisi est défini par le "débit" du média).

    Edit : je n'ai pas vraiment besoin d'une précision de 1/10 ms, disons que c'est juste par mesure de précaution, une précision de l'ordre de la milliseconde est suffisant. En fait, il se peut que j'ai besoin d'une précision un peu moins grande, mais je n'en suis pas sûr (car je ne suis pas sûr que la méthode que j'emploie soit suffisament fiable).

    Edit 2 : S'il y a un moyen de connaître les temps minimums alloués par l'OS, ça m'intéresse (je pourrais m'en servir en complément de la méthode que j'utilise afin de libérer du temps processeur).

    Edit3 : J'ai également testé les boost::timer qui ne sont pas vraiment plus fiables que usleep :/

  6. #6
    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
    Pour ce genre de précision, des OS comme windows ou linux ne sont pas très appropriés. Le mieux que j'ai trouvé pour ce genre de valeur sur ce types d'OS, c'est l'attente active, après avoir passé le processus en priorité haute, et en ne faisant rien d'autre sur la machine.

    Pour le temps de cadencement de base de windows, je crois bien que c'est effectivement autour de 16ms, mais avec des timers, et dans un environnement clean (pas d'encodage mp3 en tâche de fond, on évite de toucher à la souris...) on peut avoir des trucs relativement précis de quelques ms.
    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.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Février 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 42
    Par défaut
    Bon en fait, j'ai fait une mauvaise analyse du comportement de la fonction usleep ...

    Celle-ci ne descend bel et bien en dessous de 15ms jusqu'à 1ms. Elle réagis cependant bizzarement, elle fait des sauts de d'environ 900-1000 µs (parfois moins) à chaque fois que le chiffre des milliers est incrémenté.

    Par exemple sleep(17000) dure 17847µs alors que sleep(16999) dure 16874µs.

    Mais bon je devrais pouvoir me débrouiller avec ça.


    PS : Je viens de me rendre compte que j'aurais du poster dans le forum C (désolé donc)

  8. #8
    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
    Tu peux aussi utiliser WinMM qui possede un certains nombre d'utilitaire de timers...
    Genre:
    http://msdn.microsoft.com/library/de...mesetevent.asp
    Mais 1ms minimum pour la lib multimédia.

    En même... pour du RTP... 1ms (voire 10ms) devrait être largement suffisant pour le serveur.
    Et côté client, c'est le son qui fait office de synchro

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Février 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 42
    Par défaut
    WinMM aurait pu être un bon moyen en effet, mais je en fait souhaite faire un code portable au moins sous windows et linux, donc pour ça c'est râpé.

    Mais j'ai pu me débrouiller finalement avec ces usleep, je fais juste varier la durée de la pause en fonction des durées précédentes, pour obtenir une moyenne la plus proche possible du débit thérorique à atteindre.

    Du coup, le débit varie parfois un peu (pour un débit de 192kbps, ça varie entre 189 et 195) mais le buffer de vlc semble absorber cette variation sans broncher

    Merci pour ces conseils en tout cas.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 9
    Dernier message: 18/12/2009, 00h36
  2. [VBA]Comment faire une pause
    Par Thierry'' dans le forum VBA Access
    Réponses: 14
    Dernier message: 14/04/2007, 14h42
  3. comment faire une pause
    Par delavega dans le forum ASP
    Réponses: 1
    Dernier message: 19/02/2007, 23h58
  4. [console]Comment faire une pause?
    Par aminee009 dans le forum MFC
    Réponses: 5
    Dernier message: 20/10/2005, 10h33

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