retrouver la fréquence d'un CPU [VC++] - Programmation
Marsh Posté le 13-05-2001 à 22:05:06
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.
Marsh Posté le 13-05-2001 à 23:30:48
Arg j'viens de te poster un truc minicooler mais sur Seti
Marsh Posté le 14-05-2001 à 20:24:58
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)
Marsh Posté le 14-05-2001 à 20:33:01
Alors ça peut venir de ta méthode de calcul. Tu fais comment ?
Marsh Posté le 14-05-2001 à 21:18:56
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;
Marsh Posté le 14-05-2001 à 21:20:39
minicooler, va jeter un oeil dans les sources de SetiSpy, y'a des appels assembleurs pour recuperer toutes ces infos...
Marsh Posté le 14-05-2001 à 22:25:48
Le problème vient du Sleep qui manque de précision (épargnez-moi les jeux de mots éculés SVP )
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 :
LARGE_INTEGER pf;
QueryPerformanceFrequency(&pf);
LARGE_INTEGER valeur0;
float ticks0;
QueryPerformanceCounter(&valeur0);
__asm{
rdtsc
mov ticks0, eax
}
LARGE_INTEGER valeur1;
float ticks1;
QueryPerformanceCounter(&valeur1);
__asm{
rdtsc
mov ticks1, eax
}
freq = (float)(ticks1-ticks0) * pf.LowPart / (valeur1.LowPart - valeur0.LowPart).
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]
Marsh Posté le 15-05-2001 à 20:40:42
merci beaucoup z51, ça c'est ce que l'on appelle une réponse précise.
JWhy, je n'ai pas Delphi
Marsh Posté le 15-05-2001 à 21:22:03
y'a pas de quoi ...
Par contre je me suis planté : ticks0 et ticks1 sont des unsigned long, et non pas des float.
Marsh Posté le 16-05-2001 à 20:11:11
Reply
Marsh Posté le 13-05-2001 à 21:10:39
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 ?
---------------
SetiCommander, le setiseur à la chaîne ...