Comment utiliser moins de CPU avec des boucles?

J’ai une boucle qui ressemble à ceci:

while (elapsedTime < refreshRate) { timer.stopTimer(); elapsedTime=timer.getElapsedTime(); } 

J’ai lu quelque chose de semblable à ceci ailleurs ( boucle principale C sans processeur 100% ), mais cette boucle exécute une timer haute résolution qui doit être précise. Alors, comment suis-je censé ne pas utiliser 100% du processeur tout en conservant une haute résolution?

Vous ne devriez pas vous occuper, attendez, mais plutôt que le système d’exploitation vous dise quand le temps est écoulé.

http://msdn.microsoft.com/en-us/library/ms712704(VS.85).aspx

Minuteries haute résolution (supérieures à 10 ms)

http://msdn.microsoft.com/en-us/magazine/cc163996.aspx

Lorsque vous dites que votre timer doit être “précise”, à quel sharepointvez-vous être précis? Si vous avez seulement besoin d’être précis à la milliseconde près, vous pouvez append une demi-milliseconde de sumil dans la boucle. Vous pouvez également append un énoncé de sumil à changement dynamic basé sur le temps qu’il vous rest à dormir. Pensez à quelque chose comme (pseudocode):

 int time_left = refreshRate - elapsedTime; while (time_left > 0) { if (time_left > threshhold) sleep_for_interval(time_left / 2); update_timestamp(elapsedTime); time_left = refreshRate - elapsedTime; } 

Avec cet algorithme, votre code dormira pour de courtes rafales s’il détecte que vous avez encore du temps à attendre. Vous voudriez exécuter des tests pour trouver une valeur optimale pour le threshhold qui équilibre les économies d’utilisation du processeur pour le risque de dépassement (causé par la perte du processeur par votre application lorsqu’elle dort et par le temps).

L’autre méthode de synchronisation à haute résolution consiste à utiliser une timer matérielle qui déclenche une interruption périodique. Votre gestionnaire d’interruptions enverrait un signal à un thread pour qu’il se réveille et fasse quelque chose, après quoi il se rendormit et attend que le prochain signal arrive.

Les systèmes d’exploitation en temps réel ont des façons de faire ce genre de choses intégrées au système d’exploitation. Si vous faites de la programmation Windows et que vous avez besoin d’un timing extrêmement précis, sachez que ce n’est pas le genre de chose qu’un système d’exploitation général comme Windows gère très bien.

Regardez quelques timers fournies par le système d’exploitation, comme POSIX usleep .
D’un autre côté, si vous avez besoin d’hyper précision, votre code ne fonctionnera pas non plus, car le système d’exploitation va briser cette boucle après avoir épuisé son quantum de temps de processus et accéder à l’espace du kernel pour effectuer certaines tâches système. À cette fin, vous auriez besoin d’un système d’exploitation spécial avec un kernel interruptible et des outils fournis par celui-ci. Recherchez le mot-clé RTOS.

En règle générale, vous cédez à l’OS d’une certaine manière. Cela permet au système d’exploitation de prendre une pause dans votre programme et de faire autre chose.

Évidemment, cela dépend de l’OS, mais:

 #ifdef _WIN32 #include  #else #include  #endif void yield(void) { #ifdef _WIN32 Sleep(0); #else usleep(1); #endif } 

Insérez un appel pour céder avant d’arrêter la timer. Le système d’exploitation indiquera moins de temps d’utilisation par votre programme.

N’oubliez pas que cela rend votre timer “moins précise”, car elle risque de ne pas être mise à jour aussi souvent que possible. Mais vous ne devriez vraiment pas compter sur une extrême précision, c’est trop difficile. Les approximations vont bien.