• 04 Juin 2026, 12:04:43


Auteur Sujet: Timer imprécis.  (Lu 3911 fois)

0 Membres et 1 Invité sur ce sujet

Hors ligne 3klips

  • *
  • Tueur
  • Messages: 62
    • Voir le profil
Timer imprécis.
« le: 21 Novembre 2009, 22:43:13 »
Bonjour, voila, je suis en train de créé un petit FS de course, alor pour le chrono, je calle un peu car les Timer sont très imprécis, 1 seconde = 1,1 seconde, des fois 1 seconde = 1,5, y a-t-il des soluces pour contourner ce probleme? Merci

Hors ligne Ssk

  • *
  • Lulu's Stunt - Le serveur stunt de Lulu !
  • Messages: 8154
    • Voir le profil
Re : Timer imprécis.
« Réponse #1 le: 21 Novembre 2009, 23:08:39 »
non dommage

Pour t expliquer pourquoi c' est imprecis c 'est un peu long mais c' est comme ca sur les ordinateur car le CPU travail sur un process a la fois donc c' est jamais precis


trop flemard pour expliquer lol



Derrière tout programme se cache un programmeur, je considère le monde comme un programme.
Mon blog

Hors ligne cristab

  • *
  • Messages: 8379
    • Voir le profil
Re : Timer imprécis.
« Réponse #2 le: 21 Novembre 2009, 23:24:21 »
en gros cpu qui travaille comme toi a l'ecole il ralentit
pas d'aide en PM, vous êtes sur un forum est il me semble que vous êtes la pour avoir de l'aide donc pourquoi MP une seul personne qui ne vous répondra pas alors qu'il y a plein de membre ici

Hors ligne 3klips

  • *
  • Tueur
  • Messages: 62
    • Voir le profil
Re : Timer imprécis.
« Réponse #3 le: 21 Novembre 2009, 23:44:27 »
Argh dommage, je dois faire un chrono avec un gettime un truc comme sa pour avoir quelque chose de précis alor..
Je vais regarder d'autre FS.

Hors ligne Ssk

  • *
  • Lulu's Stunt - Le serveur stunt de Lulu !
  • Messages: 8154
    • Voir le profil
Re : Timer imprécis.
« Réponse #4 le: 22 Novembre 2009, 11:59:38 »
Je te recherche la page qui explique tout ca ^^


Apres avoir tout reinstaller mon tit frere ma retirer Windows >.<



Derrière tout programme se cache un programmeur, je considère le monde comme un programme.
Mon blog

Hors ligne Syg

  • Expert programmeur C/C++/PAWN
  • *
  • The GTAOnline Jesus
  • Messages: 3908
    • Voir le profil
Re : Timer imprécis.
« Réponse #5 le: 25 Novembre 2009, 12:21:58 »
Un timer n'est pas liés au CPU mais à l'horloge du PC qui elle est très précise.
Il ne serait donc pas normal qu'un timer identique varie selon qu'il est exécuté sur une machine ou sur une autre.
Sous Windows, en C, les timers sont très précis.

Je me suis donc décidé à faire des tests sur les timers pour découvrir le pourquoi du comment des timers de SAMP.

Voici le gamemode que j'ai utilisé pour mes tests :
#include <a_samp>

#define VALEUR_TIMER 300

forward MonTimer ();
new T1, T2;

main ()
{
}

public OnGameModeInit ()
{
// Set timer of 1 second.
SetTimer ("MonTimer", VALEUR_TIMER, 1);
T1 = GetTickCount ();
return 1;
}

public MonTimer ()
{
T2=GetTickCount();
printf("Difference :  %d %%", (T2-T1-VALEUR_TIMER)/(VALEUR_TIMER/100));
T1=T2;
}

J'ai fait plusieurs tests en modifiant la valeur de VALEUR_TIMER
Le résultat est encourageant, la différence est toujours de 17 % (du moins sur ma machine du boulot).
En affinant les calculs, la différence est en fait de 17.2 %
Il semblerait que ce soit un bug de SAMP.

NB : J'aimerais savoir si cette valeur est la même sur d'autres machines. Donc si quelqu'un pouvait faire le test et poster les résultats ici, ce serait cool, merci.

Mais il est très facile de trouver la valeur qui permet d'avoir exactement le temps qu'on veut.
Par exemple pour avoir un timer  qui "tombe" toutes les 1000 ms, il suffit de mettre la valeur du timer à 1000/1.172 = 853 ms.

Exemple :
#include <a_samp>

#define VALEUR_TIMER 853

forward MonTimer ();

main ()
{
}

public OnGameModeInit ()
{
// Set timer of 1 second.
SetTimer ("MonTimer", VALEUR_TIMER, 1);
return 1;
}

public MonTimer ()
{
printf ("GetTickCount = %d", GetTickCount());
}

Voici le résultat :
[12:01:28] GetTickCount = 786283984
[12:01:29] GetTickCount = 786284985
[12:01:30] GetTickCount = 786285987
[12:01:31] GetTickCount = 786286989
[12:01:32] GetTickCount = 786287991
[12:01:33] GetTickCount = 786288993
[12:01:34] GetTickCount = 786289995
[12:01:35] GetTickCount = 786290997
[12:01:36] GetTickCount = 786291999
[12:01:37] GetTickCount = 786293001
[12:01:38] GetTickCount = 786294003
[12:01:39] GetTickCount = 786295005
[12:01:40] GetTickCount = 786296007
[12:01:41] GetTickCount = 786297009
[12:01:42] GetTickCount = 786298011
[12:01:43] GetTickCount = 786299013


A 1 ou 2 ms seconde près, ce timer de 1 seconde n'est pas mal !!

On peut même se faire une fonction qui recalcule l'intervalle du timer automatiquement :
MonSetTimer (Fonction[], Intervalle, Repetition)
{
   SetTimer (Fonction, Intervalle/1.172, Repetition);
}

NB : Il n'est malheureusement pas possible de la faire pour la fonction SetTimerEx car elle a un nombre variable de paramètres

++
Syg
Courtesy of GtaManiac

Hors ligne cristab

  • *
  • Messages: 8379
    • Voir le profil
Re : Timer imprécis.
« Réponse #6 le: 25 Novembre 2009, 12:35:45 »
voila de mon coter
[12:34:34] Difference :  8 %
[12:34:34] Difference :  8 %
[12:34:35] Difference :  8 %
[12:34:35] Difference :  12 %
[12:34:35] Difference :  10 %
[12:34:36] Difference :  11 %
[12:34:36] Difference :  11 %
[12:34:36] Difference :  11 %
[12:34:37] Difference :  10 %
[12:34:37] Difference :  10 %
[12:34:37] Difference :  11 %
[12:34:38] Difference :  9 %
[12:34:38] Difference :  6 %
[12:34:38] Difference :  10 %
[12:34:39] Difference :  10 %
[12:34:39] Difference :  7 %
[12:34:39] Difference :  10 %
[12:34:40] Difference :  11 %
[12:34:40] Difference :  10 %
[12:34:40] Difference :  11 %
[12:34:41] Difference :  10 %
[12:34:41] Difference :  8 %
[12:34:41] Difference :  8 %
[12:34:42] Difference :  10 %
[12:34:42] Difference :  9 %
[12:34:42] Difference :  11 %
[12:34:43] Difference :  8 %
[12:34:43] Difference :  10 %
[12:34:43] Difference :  8 %
[12:34:44] Difference :  8 %
[12:34:44] Difference :  6 %
[12:34:44] Difference :  10 %
[12:34:45] Difference :  5 %
[12:34:45] Difference :  10 %
[12:34:45] Difference :  11 %
[12:34:46] Difference :  11 %
[12:34:46] Difference :  11 %
[12:34:46] Difference :  12 %
[12:34:47] Difference :  10 %
[12:34:47] Difference :  11 %
pas d'aide en PM, vous êtes sur un forum est il me semble que vous êtes la pour avoir de l'aide donc pourquoi MP une seul personne qui ne vous répondra pas alors qu'il y a plein de membre ici

Hors ligne Ssk

  • *
  • Lulu's Stunt - Le serveur stunt de Lulu !
  • Messages: 8154
    • Voir le profil
Re : Timer imprécis.
« Réponse #7 le: 25 Novembre 2009, 12:52:14 »
7 à 13 %

Avec firefox et MediaPlayer Ouvert


Puis comme je sais que ca depend du CPU ( meme si tu le contredit syg ca depend du CPU j' en suis sur )


J ai ouvert Visual Studio

Et la ca a fait des pique a 85 % donc cela depend du CPU avec les programme Ouvert ^^


EDIT:

Voici un test que j ai fait

#include <a_samp>

#define VALEUR_TIMER 300

forward MonTimer ();
new T1, T2;

main ()
{
}

public OnGameModeInit ()
{
SetTimer("MonTimer",VALEUR_TIMER,1);
return 1;
}
public MonTimer ()
{
T1 = GetTickCount();
printf("Ms ecouler %d",T1 - T2);
T2 = T1;
}

Voici les valeurs


Ms ecouler 1145608
Ms ecouler 333
Ms ecouler 332
Ms ecouler 338
Ms ecouler 331
Ms ecouler 332
Ms ecouler 334
Ms ecouler 335
Ms ecouler 319
Ms ecouler 307
Ms ecouler 463
Ms ecouler 320
Ms ecouler 349
Ms ecouler 373
Ms ecouler 324
Ms ecouler 323
Ms ecouler 326
Ms ecouler 331
Ms ecouler 335
Ms ecouler 336
Ms ecouler 326
Ms ecouler 330
Ms ecouler 329
Ms ecouler 388
Ms ecouler 340
Ms ecouler 373
Ms ecouler 321
Ms ecouler 344
Ms ecouler 331
Ms ecouler 328
Ms ecouler 335
Ms ecouler 328
Ms ecouler 326
Ms ecouler 329
Ms ecouler 331
Ms ecouler 334
Ms ecouler 331
« Modifié: 25 Novembre 2009, 13:03:01 par sasuke78200 »



Derrière tout programme se cache un programmeur, je considère le monde comme un programme.
Mon blog

Hors ligne Mr_C30

  • *
  • Gangster
  • souvent conquise jamais soumise
  • Messages: 1937
    • Voir le profil
Re : Timer imprécis.
« Réponse #8 le: 25 Novembre 2009, 13:22:58 »
tu as fait le test en C sausuke ?



Radis du soir bonsoir !


Hors ligne Ssk

  • *
  • Lulu's Stunt - Le serveur stunt de Lulu !
  • Messages: 8154
    • Voir le profil
Re : Timer imprécis.
« Réponse #9 le: 25 Novembre 2009, 13:27:27 »
non en pawn ^^


Je test en C dans quelque minutes pour voir ^^



Derrière tout programme se cache un programmeur, je considère le monde comme un programme.
Mon blog

Hors ligne Syg

  • Expert programmeur C/C++/PAWN
  • *
  • The GTAOnline Jesus
  • Messages: 3908
    • Voir le profil
Re : Timer imprécis.
« Réponse #10 le: 25 Novembre 2009, 14:09:07 »
C'est quand même très bizarre car sur ma machine du boulot (Core 2 Duo), j'ai toujours 17 % de différence, ni plus ni moins.
Même lorsque j'ouvre des programmes.

En en réfléchissant, je pensais que les timers SAMP sont des timers Windows (qui fonctionne sur l'horloge du PC) mais en fait, ce n'est peut-être pas vrai car les timers Windows n'existent pas sous Linux.La team SAMP a certainement du les récrire pour que le code soit compatible avec les deux plateformes (Linux et Windows).

++
Syg
Courtesy of GtaManiac

Hors ligne Ssk

  • *
  • Lulu's Stunt - Le serveur stunt de Lulu !
  • Messages: 8154
    • Voir le profil
Re : Timer imprécis.
« Réponse #11 le: 25 Novembre 2009, 14:13:58 »
Voila la preuve de ce que je disais ^^


Qu'est-ce que vient faire l'OS là-dedans ?

Oh mais l'OS a tout à faire là-dedans : c'est lui qui contrôle les programmes qui tournent !
Votre programme va donc dire à l'OS : "Je dors, réveille-moi dans 1 seconde". Mais l'OS ne va pas forcément le réveiller au bout d'une seconde exactement.

En effet, il aura peut-être un peu de retard (un retard de 10ms en moyenne environ, ça dépend des PC). Pourquoi ? Parce que votre CPU ne peut travailler que sur un programme à la fois. Le rôle de l'OS est de dire au CPU ce sur quoi il doit travailler : "Alors, pendant 40ms tu vas travailler sur firefox.exe, puis pendant 110ms tu vas travailler sur explorer.exe, et ensuite pendant 80ms tu vas travailler sur programme_sdl.exe, puis tu vas retravailler sur firefox.exe pendant 65ms" etc etc...
L'OS est le véritable chef d'orchestre de l'ordinateur !

Maintenant, imaginez qu'au bout d'une seconde un autre programme soit encore en train de travailler : il faudra qu'il ait fini de travailler pour que votre programme puisse "reprendre la main" comme on dit, c'est-à-dire être traité à nouveau par le CPU.

Tout ça pour dire quoi ? o_O


Ooops, excusez-moi j'étais en train de dériver :-°
En gros, j'essayais de vous expliquer que votre CPU ne pouvait pas gérer plus d'un programme à la fois. Pour donner l'impression que l'on peut faire tourner plusieurs programmes en même temps sur un ordinateur, l'OS "découpe" le temps et autorise les programmes à travailler au tour par tour.

Or, cette gestion des programmes est très complexe et on ne peut donc pas avoir la garantie que notre programme sera réveillé au bout d'une seconde exactement.

Toutefois, ça dépend des PC comme je vous l'ai dit plus haut. Chez moi, la fonction SDL_Delay est assez précise.

A cause de ce problème de "granularité du temps", vous ne pouvez donc pas mettre en pause votre programme pendant un temps trop court. Par exemple, si vous faites :
Code : C

1



SDL_Delay(1);


Vous pouvez être sûrs que votre programme ne sera pas mis en pause 1ms mais un peu plus (peut-être 9-10ms).


En résumé : SDL_Delay c'est cool, mais ne lui faites pas trop confiance. Elle ne mettra pas en pause votre programme pendant le temps exact que vous indiquez.
Ce n'est pas parce que la fonction est mal codée, c'est parce que le fonctionnement d'un ordinateur est très complexe et ne permet pas d'être très précis à ce niveau.

Source: http://www.siteduzero.com/tutoriel-3-14136-maitrisez-le-temps.html


Sinon Syg ton CPU est cadence a combien de Hertz ?


EDIT: Voici des test sur des timer d' une secondes c' est vraimenent pas précis quand on met secondes

Ms ecouler 1111
Ms ecouler 1117
Ms ecouler 1105
Ms ecouler 1109
Ms ecouler 1110
Ms ecouler 1110
Ms ecouler 1116
Ms ecouler 1107
Ms ecouler 1074
Ms ecouler 1096
Ms ecouler 1119
Ms ecouler 1115
Ms ecouler 1116
Ms ecouler 1110
Ms ecouler 1101
Ms ecouler 1113
Ms ecouler 1117
Ms ecouler 1109
Ms ecouler 1108
Ms ecouler 1112
Ms ecouler 1101
« Modifié: 25 Novembre 2009, 14:17:12 par sasuke78200 »



Derrière tout programme se cache un programmeur, je considère le monde comme un programme.
Mon blog

Hors ligne Syg

  • Expert programmeur C/C++/PAWN
  • *
  • The GTAOnline Jesus
  • Messages: 3908
    • Voir le profil
Re : Timer imprécis.
« Réponse #12 le: 25 Novembre 2009, 22:41:02 »
Ce que tu cites dates un peu, les CPU de maintenant peuvent effectuer 2, 4 ou 8 instructions à la fois (dualcore, quadcore ou quadcore+hyperthreading comme le i7).
De plus, ton article parle d'un retard de 10 ms en moyenne, ce qui en vrai, c'est en fait la précision des timers sous Windows.
D'ailleurs, c'est de ça que parles cette article, qui est aussi valable pour la fonction Sleep() de Win32.

Les timers sous Windows sont gérés par interruptions (logicielles certes) mais reste à un niveau très bas.

Dans notre cas, et mes test le montre bien, le décalage n'est pas de 10 ms mais est proportionnel au temps du timer :
17 % dans le cas de ma machine au boulot (Core2 Duo 2.8 Ghz je crois)
17 % encore dans le cas de mon PC perso principal à la maison (Core2 Duo 3.16Ghz)
17 % encore dans le cas de mon deuxième PC perso (i7 920)

Je n'ai pas fait de tests sur un serveur Linux.

Les valeurs que tu montres sont conformes à ce que je trouve mais dans ton cas, la décalage est de 11 %.
Essaies le même test que celui que tu as fais avec 2 secondes puis 10 secondes pour ton timer, tu trouveras des valeurs de 2220 environs dans le premier cas et 11100 environs dans le second.

Voici un très court programme en C qui ressemble à celui de sazuke, il affiche le GetTickCount à chaque échéance du timer. Sa précision est impeccable si rien d'autre ne tourne et il y a un décalage de 10-15 ms lorsque je fait un "dir c: /s" en même temps, ce qui est conforme à l'article que tu cites (Je te conseille de l'essayer sazuke) :
#include <stdio.h>
#include <windows.h>

VOID CALLBACK MaFonctionTimer (HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
{
   /* Fonction nécessaire mais non utilisée */
}

void main (void )
{
HWND hwndTimer;
MSG msg;

   if (SetTimer (NULL, 0, 1000, MaFonctionTimer)==0)
   {
      printf ("Impossible de creer le timer\n");
   }
    while (GetMessage(&msg, // message structure
            NULL,           // handle of window to receive the message
            NULL,           // lowest message to examine
            NULL))          // highest message to examine
    {
 
        // Post WM_TIMER messages to the hwndTimer procedure.
 
        if (msg.message == WM_TIMER)
        {
            msg.hwnd = hwndTimer;
            printf ("GetTickCount = %d\n", GetTickCount ());
        }
 
        TranslateMessage(&msg); // translates virtual-key codes
        DispatchMessage(&msg);  // dispatches message to window
    }
}

Ma conclusion c'est que la team SAMP a réécrit les timers de SAMP pour que le code soit portable entre Windows et Linux (pour qu'il soit plus facile à maintenir).
Mais en faisant ça, ils ont introduit un décalage proportionnel au temps du timer.
Et comme on ne sait pas comment ils ont écrit leurs timers, on ne peut faire que des suppositions sur la façon de contourner le problème.

++
Syg
Courtesy of GtaManiac

Hors ligne Ssk

  • *
  • Lulu's Stunt - Le serveur stunt de Lulu !
  • Messages: 8154
    • Voir le profil
Re : Timer imprécis.
« Réponse #13 le: 25 Novembre 2009, 23:03:58 »
Apres avoir essayez et arranger le code pour me simplifier les calcules voila ce que j ai !!

Temps pour timer d' une seconde = 1014
Temps pour timer d' une seconde = 1014
Temps pour timer d' une seconde = 1014
Temps pour timer d' une seconde = 1014
Temps pour timer d' une seconde = 1014
Temps pour timer d' une seconde = 1014
Temps pour timer d' une seconde = 1014
Temps pour timer d' une seconde = 1014
Temps pour timer d' une seconde = 1014
Temps pour timer d' une seconde = 1014
Temps pour timer d' une seconde = 1014
Temps pour timer d' une seconde = 1014
Temps pour timer d' une seconde = 1014
Temps pour timer d' une seconde = 1014
Temps pour timer d' une seconde = 1014

impecable et precis ( tres propre meme )

je test avec samp et j' edit ^^


Pawn pour un timer de deux secondes !

Ms ecouler 2207
Ms ecouler 2224
Ms ecouler 2224
Ms ecouler 2241
Ms ecouler 2227
Ms ecouler 2237
Ms ecouler 2213
Ms ecouler 2204
Ms ecouler 2224
Ms ecouler 2212
Ms ecouler 2209
Ms ecouler 2220


C

Pour un timer de deux secondes

Temps pour timer d' une seconde = 2012
Temps pour timer d' une seconde = 2013
Temps pour timer d' une seconde = 2012
Temps pour timer d' une seconde = 2012
Temps pour timer d' une seconde = 2013
Temps pour timer d' une seconde = 2012
Temps pour timer d' une seconde = 2013
Temps pour timer d' une seconde = 2012
Temps pour timer d' une seconde = 2012
Temps pour timer d' une seconde = 2013
Temps pour timer d' une seconde = 2012
Temps pour timer d' une seconde = 2013
Temps pour timer d' une seconde = 2012
Temps pour timer d' une seconde = 2012
Temps pour timer d' une seconde = 2013

Encore plus precis que pour une secondes ^^



Sinon je tient a preciser que les test en pawn sont bien sur fait sur des GM vide on est pas sur des resultat sur de gros GM avec joueurs
« Modifié: 25 Novembre 2009, 23:08:31 par sasuke78200 »



Derrière tout programme se cache un programmeur, je considère le monde comme un programme.
Mon blog

Hors ligne Syg

  • Expert programmeur C/C++/PAWN
  • *
  • The GTAOnline Jesus
  • Messages: 3908
    • Voir le profil
Re : Timer imprécis.
« Réponse #14 le: 26 Novembre 2009, 09:32:32 »
Ca confirme que les timers SAMP n'ont rien à voir avec les timers Windows.
Il faudra donc faire avec leur imperfection.
En espérant que la team SAMP puisse les corriger.

Et j'ai fait comme toi sazuke, tous mes tests sous SAMP ont été fait avec un GM vide.

++
Syg
Courtesy of GtaManiac