Page 1 sur 1

Plus précis que ElapsedMilliseconds()

Publié : mar. 02/nov./2010 14:12
par DjPoke
Bonjour,

Je suis en train de développer un programme purebasic qui doit pouvoir lancer de temps en temps une procedure en asm, qui elle, doit ne pas dépasser 0,1 micro secondes, et pouvoir être lancée à intervalles réguliers pendant une durée pouvant être jusqu'à plusieurs heures et plus. (Je bosse sur un outil GUI qui permettra de fabriquer des émulateurs de divers bécanes en assemblant des composants divers, et de lancer l'émulations des signaux, certains signaux comme les oscillateurs/horloges processeurs requérant une grande rapidité)

Je souhaiterais donc savoir s'il existe un appel au système (je suis sous windows) que je peux utiliser pour réaliser ceci, étant donné que la commande ElapsedMilliseconds() se limite à la milliseconde.
J'ai fait des tests, purebasic est beaucoup plus rapide que la milliseconde, même en basic. :)

Merci, bonne journée
DjPoke

EDIT:
Je crois avoir trouvé l'astuce. Si j'émule par exemple un Zilog Z80a tournant à 3Mhz, je ne dois pas chercher à appeler le processeur virtuel toutes les 1/3000000 secondes, mais plutôt essayer, par exemple, toutes les 1ms, d'effectuer 3000 boucles. (où un truc proche de cela)
Si cela intéresse quelqu'un...

Re: Plus précis que ElapsedMilliseconds()

Publié : mar. 02/nov./2010 23:38
par PAPIPP
Bonjour DjPoke
Voici une procédure qui compte les cycles machine.

Code : Tout sélectionner

ProcedureDLL.q nbcs()
!RDTSC
  ProcedureReturn
EndProcedure


t1.q=nbcs()
t2.q=nbcs()
Debug nbcs()
Debug T2-T1
; http://www.purebasic.fr/french/viewtopic.php?f=1&t=8982&p=97997&hilit=RDTSC#p97997
Pour plus de précision voir :
http://www.purebasic.fr/french/viewtopi ... RDTSC#p979
A+

Re: Plus précis que ElapsedMilliseconds()

Publié : mer. 03/nov./2010 0:47
par Backup
peut etre l'utilisation des timers ?

http://www.purebasic.fr/french/viewtopi ... highlight=

Re: Plus précis que ElapsedMilliseconds()

Publié : mer. 03/nov./2010 6:16
par DjPoke
Merci de vos réponses.
Je vais examiner cela.

EDIT:
Impeccable, merci beaucoup, ça à l'air de marcher ! :)
Est-ce que quelqu'un qui a un processeur ne tournant pas à 3 Ghz pourrait tester ?

Code : Tout sélectionner

ProcedureDLL.q nbcs()
  !RDTSC
  ProcedureReturn
EndProcedure

t1.q=nbcs()
Delay(1000)
t2.q=nbcs()
Debug "Vous avez un processeur "+Str((t2-t1)/1000000000)+" Ghz"
Debug "Vous avez donc "+Str((t2-t1)/1000000000)+" tics/ns"

Re: Plus précis que ElapsedMilliseconds()

Publié : mer. 03/nov./2010 7:29
par flaith
Salut,

Info PC du bureau :
AMD Athlon II X2 215
Processeur 2.93 GHz
Résultat :
[07 :24 :48] Vous avez un processeur 2 Ghz
[07 :24 :48] Vous avez donc 2 tics/ns
En modifiant un peu le programme :

Code : Tout sélectionner

ProcedureDLL.q nbcs()
	!RDTSC
	ProcedureReturn
EndProcedure

t1.d=nbcs()
Delay(1000)
t2.d=nbcs()
Debug "Vous avez un processeur "+StrD((t2-t1)/1000000000, 2)+" Ghz"
Debug "Vous avez donc "+StrD((t2-t1)/1000000000, 2)+" tics/ns"
on obtient :
[07 :28 :50] Vous avez un processeur 2.69 Ghz
[07 :28 :50] Vous avez donc 2.69 tics/ns
:mrgreen:

Re: Plus précis que ElapsedMilliseconds()

Publié : mer. 03/nov./2010 7:32
par DjPoke
Oups... Merci beaucoup pour avoir rectifié cet erreur de ma part.
Je vais pouvoir continuer à bosser.
Bonne journée :)

Re: Plus précis que ElapsedMilliseconds()

Publié : mer. 03/nov./2010 11:39
par flaith
En allant sur ce site http://www.haypocalc.com/wiki/Fr%C3%A9q ... processeur
j'en ai fait une version PureBasic :

Code : Tout sélectionner

ProcedureDLL.q nbcs()
	!RDTSC
	ProcedureReturn
EndProcedure

Procedure.i CPUFrequency(*adr_frequence)
Protected.q Twin_avant, Twin_apres
Protected.q Tcpu_avant, Tcpu_apres
Protected.q Fwin
Protected.f Fcpu

  ; Lit la frequence du chronomêtre Windows
  If Not QueryPerformanceFrequency_(@Fwin) : ProcedureReturn 0 : EndIf
  PrintN("Frequence du compteur Windows = "+StrF((Fwin/1e9), 2)+" Ghz")

  ; Avant
  Tcpu_avant = nbcs()
  QueryPerformanceCounter_(@Twin_avant)

  ; Attend quelques itérations (10 000) du chronomètre Windows
  While (Twin_apres-Twin_avant) < 10000
    QueryPerformanceCounter_(@Twin_apres)
  Wend

  ; Apres
  Tcpu_apres = nbcs()
  QueryPerformanceCounter_(@Twin_apres)

  ; Calcule la fréquence en MHz
  Fcpu = (Tcpu_apres - Tcpu_avant)
  Fcpu * (Fwin / 1000000000.00)
  Fcpu / (Twin_apres - Twin_avant)
  PokeF(*adr_frequence, Fcpu)

  ProcedureReturn 1
EndProcedure

OpenConsole()
  frequence.f
  freq.i = CPUFrequency(@frequence)

  If freq 
    PrintN("Frequence du processeur = "+StrF(frequence,2))
    Input()
  EndIf

CloseConsole()

Re: Plus précis que ElapsedMilliseconds()

Publié : mer. 10/nov./2010 18:00
par SPH
Avec le premier code de flaith :
Vous avez un processeur 0.42 Ghz
Vous avez donc 0.42 tics/ns
Avec le deuxieme :
Frequence du compteur Windows = 0.01 Ghz
Frequence du processeur = 2.00

Re: Plus précis que ElapsedMilliseconds()

Publié : mer. 10/nov./2010 23:00
par Droopy
ya aussi ce code basé sur Erix14 & Djes :

Code : Tout sélectionner

;{ MeasureIntervalHiRes (Start)                                  
; Idea from Erix14 / Djes
; Return the time elapsed between Start & Stop in second
; 0.001 = 1 ms
; 0.000001=1 µs
; Caution ! : If the installed hardware supports a high-resolution performance counter
; MeasureHiResIntervalStart return 1 / 0 if no hardware support 
; Use this functions for measure interval < 1 ms

Global MeasureHiResIntervalTime.l

ProcedureDLL MeasureHiResIntervalStart()
  QueryPerformanceFrequency_(@retour)
  If retour <>0 : retour = 1 : EndIf
  QueryPerformanceCounter_(@MeasureHiResIntervalTime)  
  ProcedureReturn retour
EndProcedure

ProcedureDLL.f MeasureHiResIntervalStop()
  QueryPerformanceCounter_(@Temp)
  Difference=Temp-MeasureHiResIntervalTime
  QueryPerformanceFrequency_(@HiResTimerFrequency)
  Periode.f=1/HiResTimerFrequency
  DureeTotale.f=Difference*Periode
  ProcedureReturn DureeTotale
EndProcedure


; ;/ Test1 : For Next
; If MeasureHiResIntervalStart()
  ; For n=0 To 10000
  ; Next n
  ; Debug MeasureHiResIntervalStop()
; EndIf
; 
; ;/ Test2 : Repeat : Until
; If MeasureHiResIntervalStart()
  ; Repeat
    ; a+1
  ; Until a=10000
  ; Debug MeasureHiResIntervalStop()
; EndIf
; 
; Debug "The fastest is For/Next"

;} MeasureIntervalHiRes (End)

Re: Plus précis que ElapsedMilliseconds()

Publié : mer. 05/janv./2011 19:09
par bombseb
Si j'émule par exemple un Zilog Z80a tournant à 3Mhz
tu code un émulateur Z80 ?

Re: Plus précis que ElapsedMilliseconds()

Publié : mer. 05/janv./2011 20:09
par DjPoke
J'avais commencé un programme pour créer visuellement des émulateurs, mais je l'ai laissé en plan finalement.
Je verrai plus tard.

Re: Plus précis que ElapsedMilliseconds()

Publié : ven. 30/sept./2011 14:04
par dayvid
Super !, je cherchais justement une commande plus rapide que ElapsedMilliseconde :D