Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
5068 connectés 

 


Dernière réponse
Sujet : [VC++] retrouver la fréquence d'un CPU
MiniCooler :pt1cable:  :pt1cable:

Votre réponse
Nom d'utilisateur    Pour poster, vous devez être inscrit sur ce forum .... si ce n'est pas le cas, cliquez ici !
Le ton de votre message                        
                       
Votre réponse


[b][i][u][strike][spoiler][fixed][cpp][url][email][img][*]   
 
   [quote]
 

Options

 
Vous avez perdu votre mot de passe ?


Vue Rapide de la discussion
MiniCooler :pt1cable:  :pt1cable:
z51 y'a pas de quoi ...  :)  
 
Par contre je me suis planté :D  : ticks0 et ticks1 sont des unsigned long, et non pas des float.
MiniCooler merci beaucoup z51, ça c'est ce que l'on appelle une réponse précise.
 
JWhy, je n'ai pas Delphi  :cry:  :cry:
z51 Le problème vient du Sleep qui manque de précision (épargnez-moi les jeux de mots éculés SVP :D )
 
Le mieux est d'utiliser QueryPerformanceFrequency et QueryPerformanceCounter. Le problème de ces fonctions est qu'elles utilisent une base de temps différente selon le CPU et l'OS. Mais l'essentiel est d'avoir deux bases de temps, et pour l'autre on peut prendre le compteur de cycle interne (rdtsc), l'idée étant d'avoir deux deltas, un pour chaque base.
 
Donc :  
 

  • tu te mets en priorité maximale (comme tu l'as fait)


  • tu récupères la fréquence du QPC :

LARGE_INTEGER pf;
QueryPerformanceFrequency(&pf);
 

  • tu prends une mesure des deux compteurs :

LARGE_INTEGER valeur0;
float ticks0;
QueryPerformanceCounter(&valeur0);
__asm{
   rdtsc
   mov ticks0, eax
}
 

  • tu attends qques ms pour obtenir des deltas corrects, en utilisant une boucle de calcul par exemple... sa durée n'importe pas du tout dans la précision du calcul.


  • tu reprends à nouveau une valeur des deux compteurs.

LARGE_INTEGER valeur1;
float ticks1;
QueryPerformanceCounter(&valeur1);
__asm{
   rdtsc
   mov ticks1, eax
}
 

  • et voilà, la fréquence en Hz vaut :

freq = (float)(ticks1-ticks0) * pf.LowPart / (valeur1.LowPart - valeur0.LowPart).
 

  • tu te remets en priorité normale (comme tu l'as fait)


 
Avec un P2 ou un P3 sous NT, QueryPerformanceFrequency renvoie directement la fréquence du cpu, mais le calcul fonctionne quand même, car alors les deux deltas sont égaux.
 
 
oilà oilà ...

 

[edit]--Message édité par z51--[/edit]

JWhy minicooler, va jeter un oeil dans les sources de SetiSpy, y'a des appels assembleurs pour recuperer toutes ces infos...
MiniCooler ben voilà le code que j'utilise
 
int CCPUFeatures::GetCpuSpeed()
{
 int time;  
 int subtime;
 int nPriorityClass;
 int nPriorityThread;
 int nTmp;
 int result;
    nPriorityClass = GetPriorityClass(GetCurrentProcess);
    nPriorityThread = GetThreadPriority(GetCurrentThread);
    SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS);
    SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_TIME_CRITICAL);
 __asm  
 {
  cpuid
  rdtsc
  mov subtime, eax
  cpuid
  rdtsc
  sub eax, subtime
  mov subtime, eax
 
  cpuid
  rdtsc
  mov subtime, eax
  cpuid
  rdtsc
  sub eax, subtime
  mov subtime, eax
 
  cpuid
  rdtsc
  mov subtime, eax
  cpuid
  rdtsc
  sub eax, subtime
  mov subtime, eax  
 }
 __asm
 {
  cpuid    
  rdtsc    
  mov time, eax
 }
 Sleep(1500);
 __asm
 { cpuid    
  rdtsc    
  sub eax, time  
  mov time, eax
 }
 
 time = time - subtime;  
 SetThreadPriority(GetCurrentThread, nPriorityThread);
 SetPriorityClass(GetCurrentProcess, nPriorityClass);
 nTmp=time/1500000;
 switch(nTmp%100)
 {
 case 1:
  result=nTmp-1;
  break;
 case 51:
  result=nTmp-1;
  break;
 case 81:
  result=nTmp-1;
  break;
 case 67:
  result=nTmp-1;
  break;
 case 34:
  result=nTmp-1;
  break;
 case 99:
  result=nTmp+1;
  break;
 case 49:
  result=nTmp+1;
  break;
 case 79:
  result=nTmp+1;
  break;
 case 65:
  result=nTmp+1;
  break;
 case 32:
  result=nTmp+1;
  break;
 default:
  result=nTmp;
 }
 return result;  
}
 
à l'origine, c'était un sleep (2000), mais c'étais long et je trouvais que sur mes 2 PC (TBird 800@1050 et pétroi 700) les valeurs étaient correctes. j'ai aussi modifié en concéquence nTmp=time/1500000;
z51 Alors ça peut venir de ta méthode de calcul. Tu fais comment ?
MiniCooler ouaip j'ai u visu, mais je t'ai répondu ...
 
merci z51, mais c'est pourtant ce que j'ai fait (enfin ce qui est fait dans le bout de code)
VisualC++ Arg j'viens de te poster un truc minicooler mais sur Seti :lol:
z51 Pour obtenir une précision optimale, assure-toi que le bout de code tourne en priorité maximale :
process en REALTIME_PRIORITY_CLASS et thread en THREAD_PRIORITY_TIME_CRITICAL.
MiniCooler J'ai trouvé un bout de code qui me donne (via des instructions en assembleur) le type et la fréquance du cpu de la machine, mais il arrive que la valeur de la fréquence soit fausse (un peu trop élevée ou carrément négative).
 
Vous connaissez un moyen de récupérer ces infos ?

Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)