PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Mhz Zahl einer CPU rausfinden


Unregistered
2003-04-27, 11:49:11
Wie in der Überschrift schon steht , möchte ich gerne wissen , wie man die Mhz Zahl eines Prozessors rausfinden kann. Gibst dafür einen spezialen WINAPI Aufruf oder muss man dies mit Assembler machen ?

micki
2003-04-27, 12:15:07
#include <windows.h>
#include <conio.h>
using namespace std;
DWORD GetMHZ()
{
DWORD value1 = 0;
DWORD value2 = 0;
DWORD value3 = 0;
DWORD value4 = 0;
__asm
{
rdtsc
mov value1, eax
mov value2, edx
}
Sleep(1000);
__asm
{
rdtsc
mov value3, eax
mov value4, edx
}
value1 = value3 - value1;
value2 = value4 - value2;
double MHZ = (value1+(value2*(2^32)))/1000/1000;
return (DWORD)MHZ;
}
int main()
{
cout << (int)GetMHZ() << " MHZ"<<endl;
getch();
return 0;
}

zeckensack
2003-04-27, 12:24:20
Originally posted by micki
2^32
1 << 32 :)

"^" ist der XOR-Operator :)

Unregistered
2003-04-27, 12:40:25
thx funktioniert richtig.Also wenn ich den Code richtig verstanden verschiebest du value1 und value 2 in CPU Register.Als nächstes wird der Betrieb für eine Sekunde unterbroche und dann werden value3 und value4 in die gleichen Register wie value1 und value2 kopiert.Als nächstes wird die Differenz zwischen value3 und value1 und von value4 und value2. Mir ist nur nicht klar was der rdtsc Befehl genau macht.Liefert der die Zeit an value1 und value2 zurück oder was?

zeckensack
2003-04-27, 12:45:07
RDTSC liest den time stamp counter des Prozessors aus, und legt ihn in EDX:EAX ab. Das ist ein 64bittiger Zähler, der einmal pro Taktzyklus erhöht wird. Gibt's ab dem Ur-Pentium :)

micki's Code schreibt den Counter in value1/value2, und nach der Verzögerung in value3/value4. Die dazwischenliegende Zeit ist mehr oder weniger bekannt (1 sekunde), also kann man aus der Differenz die Taktfrequenz ausrechnen.

Unregistered
2003-04-27, 13:20:51
thx , hab es jetzt verstanden

micki
2003-04-28, 11:46:45
ist nicht mein code, ich hab gegoogled.

MfG
micki

liquid
2003-04-28, 20:39:16
Kann mir bitte jemand das in AT&T Assembler übersetzen?
Ich hab versucht es spaßeshalber mal in meinen Code einzubauen, leider ohne Erfolg weil ja Intel Assembler.

Dann hab ich mich ein wenig mit dem GCC Assembler AS auseinandergesetzt und es sogar hinbekommen, dass er kompiliert. Leider meldet er beim Linken jetzt, dass er value0, value1, value2, value3 net finden kann (undefined reference). Was ich merkwürdig finde, da es doch möglich sein sollte (nach Anleitung) C-Variablennamen im ASM Code zu benutzen. Oder bin ich da auf dem Holzweg?

DWORD value0 = 0;
DWORD value1 = 0;
DWORD value2 = 0;
DWORD value3 = 0;

/*__asm__("rdtsc");
__asm__("movl %eax, value0");
__asm__("movl %edx, value1");

_sleep(1000);

__asm__("rdtsc");
__asm__("movl %eax, value2");
__asm__("movl %edx, value3");*/

value0 = value2 - value0;
value1 = value3 - value1;

std::cout << "CPU clock is: " << double(value0 + (value1 * 4294967296)) * 0.000001;

cya
liquid

Darkstar
2003-04-28, 20:45:12
Originally posted by zeckensack
time stamp counter
[…]
Gibt's ab dem Ur-Pentium :)Ausnahme sind hierbei die 6x86er Prozessoren (ohne MX) von Cyrix. Und hunderte inkompetente Spieleentwickler hatten nichts besseres zu tun, als kräftig Gebrauch von ihm zu machen (ohne vorherige Sicherheitsabfrage versteht sich). Der Time Stamp Counter gehörte damals allerdings noch nicht zum offiziellen Befehlssatz (tut er es eigentlich heute?). Außerdem ist er mitunter fehlerhaft implementiert (z. B. beim Pentium M (http://www.google.de/search?q=%22Specification+Update%22+%22Pentium+M%22+%22Time+Stamp+Counter%22&ie=ISO-8859-1&hl=de&btnG=Google+Suche); Quelle c’t 8/2003).

zeckensack
2003-04-28, 21:27:47
Originally posted by Darkstar
Ausnahme sind hierbei die 6x86er Prozessoren (ohne MX) von Cyrix. Und hunderte inkompetente Spieleentwickler hatten nichts besseres zu tun, als kräftig Gebrauch von ihm zu machen (ohne vorherige Sicherheitsabfrage versteht sich). Der Time Stamp Counter gehörte damals allerdings noch nicht zum offiziellen Befehlssatz (tut er es eigentlich heute?). Außerdem ist er mitunter fehlerhaft implementiert (z. B. beim Pentium M (http://www.google.de/search?q=%22Specification+Update%22+%22Pentium+M%22+%22Time+Stamp+Counter%22&ie=ISO-8859-1&hl=de&btnG=Google+Suche); Quelle c’t 8/2003). Das Vorhandensein des TSC (und damit des RDTSC-Befehls) läßt sich mittels CPUID sauber identifizieren. Es ist auch IIRC 'halbwegs sicher', wenn man mindestens einen Pentium MMX voraussetzt (eben weil der 6x86MX RDTSC unterstützt). Die vollständige Feature-Abfrage mit CPUID sollte man dennoch machen.

Oder so:
Würde man Software vermarkten, die RDTSC zwingend braucht, sollte man 'Pentium MMX class processer' oä unter 'Requirements' auf die Schachtel drucken.

Abe Ghiran
2003-04-28, 23:27:51
Hi everyone (Hi Dr. Nick.. :))...

Erst mal @liquid:
Bei mir tut das hier mit dem gasm (ich benutze die Bloodshed IDE unter Windows)

inline void readTSC(long long *ticks){
long long tickc;

asm("rdtsc"
: "=A" (tickc) // output registers
:
: "memory");

*ticks = tickc;
}

Zu benutzen dann so:

long long start, stop;
readTSC(&start);
sleep(1000);
readTSC(&stop);

Hz der cpu = stop-start;

Keine Ahnung, ob der Code in der Form schön ist, ich kann nämlich kein Stück Assembler. Ich bin nur in "Game Programming Gems 3" über einen "InEngine" Profiler gestolpert, der den tsc zur Performancemessung benutzt und musste dann auch fix den entsprechenden Intel asm code zum gasm portieren und bei mir funktioniert das da oben prima :).
Dabei hat mir übrigens diese Seite (http://www.delorie.com/djgpp/doc/brennan/brennan_att_inline_djgpp.html) sehr geholfen.

@all:
Bei Intel gibt es auch noch ein kleines & feines Dokument (http://cedar.intel.com/cgi-bin/ids.dll/content/content.jsp?cntKey=Legacy::imp_rdtscpm1_5744&cntType=IDS_EDITORIAL&catCode=0) zum Thema rdtsc und Performance Monitoring.

Was das vorhandesein von rdtsc angeht: Laut msdn gibt da zumindest unter WinNT/2k/XP die Funktion IsProcessorFeaturePresent (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/isprocessorfeaturepresent.asp) um das zu überprüfen. Ich habe die aber noch nicht selber benutzt, keine Ahnung wie zuverlässig die ist.
Bei meiner Suche zum Thema rdtsc bin auch noch über CPUTicker (http://www.codeproject.com/datetime/ccputicker.asp) gestolpert. Im Quellcode davon findet sich auch eine Funktion, die ziemlich penibel überprüft, ob rdtsc präsent ist.

Grüße, Jan

Darkstar
2003-04-29, 23:24:46
Originally posted by zeckensack
Das Vorhandensein des TSC (und damit des RDTSC-Befehls) läßt sich mittels CPUID sauber identifizieren.Genauso sehe ich das auch (beim Cyrix 6x86 war CPUID defaultmäßig abgeschaltet und mußte entweder über das BIOS oder per Software erst aktiv geschaltet werden – Windows98 hatte damit beispielsweise keine Probleme). Nur waren die sogenannten Spieleentwickler nicht in der Lage, die drei Zeilen Assembler irgendwo abzuschreiben und dann eine entsprechende Hinweismeldung anzuzeigen. Statt dessen bekam man halt eine nicht abgefangene Exception.

liquid
2003-04-30, 23:33:48
Thx@Abe Ghiran
Jetzt geht der Code auch bei mir!

cya
liquid

x-dragon
2003-11-03, 16:37:15
Ich wollte eigentlich diese Delphi-Funktion verwenden um die Taktfrequenz rauszufinden, aber leider schwankt das Ergebnis um einige 100 MHz. Kann man da noch was verbessern? Kenn mich mit asm nun überhaupt nicht aus ...
function CPUClock: Double;
const
DelayTime = 500;
var
TimerHigh,TimerLow : DWORD;
begin
SetPriorityClass(GetCurrentProcess,REALTIME_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread,THREAD_PRIORITY_TIME_CRITICAL);
Sleep(10);

asm
dw 310Fh
mov TimerLow,eax
mov TimerHigh,edx
end;

Sleep(DelayTime);

asm
dw 310Fh
sub eax,TimerLow
sbb edx,TimerHigh
mov TimerLow,eax
mov TimerHigh,edx
end;

Result := TimerLow / (1000.0 * DelayTime);
end;

micki
2003-11-03, 22:01:16
DelayTime höcher setzen *fg*

MfG
micki

x-dragon
2003-11-04, 10:58:18
Original geschrieben von micki
DelayTime höcher setzen *fg*

MfG
micki Helfen tut das leider nicht, also ob ich jetzt 500 wie oben oder 2000 einstelle, am Ergenis ändert das nix. Ich hab hier zum testen ein XP 2400+ (also ca 2 GHz) und ausgeben tut er immer um die 1,6 GHz.

micki
2003-11-04, 11:08:53
mach das mal weg

SetPriorityClass(GetCurrentProcess,REALTIME_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread,THREAD_PRIORITY_TIME_CRITICAL);


ansonsten versuch mal den source den ich oben gepostet habe, der lief bei mir recht zuverlässig.


und 2000 als delay sind wohl ok.

MfG
micki

x-dragon
2003-11-04, 11:55:38
Original geschrieben von micki
mach das mal weg

SetPriorityClass(GetCurrentProcess,REALTIME_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread,THREAD_PRIORITY_TIME_CRITICAL);


ansonsten versuch mal den source den ich oben gepostet habe, der lief bei mir recht zuverlässig.


und 2000 als delay sind wohl ok.

MfG
micki Hab beides versucht, aber immer gibt er mir als Werte 1500-1600 zurück ... irgendwas stimmt hier nicht :|. Zumindest Windows selber (Arbeitplatz/Eigenschaften wie auch bei dxdiag) gibt ~2 GHz zurück.

[edit]
und jetzt bekomme ich immer ein "Integer Overflow", Dword sollte doch bei Delphi die gleiche Größe haben wie bei C, oder?

micki
2003-11-04, 12:02:04
das problem ist:

du hast das delay, das ja stimmen sollte, weil es wohl mit dem systemtimer geregelt wird.
du hast den instructioncounter, der sollte auch stimmen, weil der bei jedem prozessor um 1 erhöcht wird bei jedem taktsignal.

folge:
du hast nur 1.6GHz ;)

aber mal im ernst, hast du was besonderes an deinem system? vielleicht ne mobil cpu die runtertaktet wenn nichts passiert?
versuch mal das system während des tests irgendwie unter last zu halten z.b. ein movie abspielen, wie ändern sich dann die werte?

an sich sind die messmethoden ja richtig, da muss bei dir was "komisches" im gange sein.

MfG
micki

x-dragon
2003-11-04, 12:37:03
Also eigentlich ist da nur eine normale XP 2400+ -CPU drin (und zwar hier drin: http://de.shuttle.com/sn45g.htm#sn45g).

Auch wenn er ausgelastet ist mißt er um die 1500 ... muss wohl noch mal ein anderen Meßprogramm ausprobieren.

x-dragon
2003-11-04, 13:40:12
ENTWARNUNG, funktioniert alles einwandfrei bis auf mein tolles nforce2-Board bzw dessen BIOS :motz:

Das nforce-Boards einige Macken haben, davon hab ich ja schon gehört aber das hatte ich auch nicht erwartet ... im BIOS war als FSB 133 MHz eingetragen und was ja x 15 ungefähr 2000 Mhz ergeben sollte, aber leider hat es zusätzlich noch eine Auto-Erkennuung drin (die leider nicht richtig funktioniert ...), weshalb der FSB real nur mit 100 MHz lief (x 15 = 1500!) bzw nach CPU-Z sehr stark zwischen 195-215 MHz (DDR) schwankte. Nach Deaktivierung dieser tollen Funktion läuft er jetzt endlich mit 2 GHz wie er es sollte.

Und das schönste dabei noch, das beim Start XP2400+ und Windows selber die Frequenz mit 2 Ghz angezeigt hat ...

micki
2003-11-04, 14:47:23
dann war meine these ja sogar richtig *lach*

MfG
micki

x-dragon
2003-11-04, 15:01:59
Original geschrieben von micki
dann war meine these ja sogar richtig *lach*

MfG
micki Ja eigentlich hätte ich das mal gleich überprüfen sollen .... aber weißt du vielleicht wie z.B. dxdiag auf die Taktfrequenz kommt? Ich dachte eigentlich die wird immer neu gemessen, aber wieso zeigte er mir zuerst 2 GHz an (obwohl 1,5) und jetzt 2,1 GHz (richtig)?

micki
2003-11-04, 15:39:59
könnte sein dass cpu-infos ausgelesen werden.

früher hat es einige fläschungen gegeben, weil leute einen p2-266 als p2-300 übertaktet und neu plakatiert verkauften. um das zu verhindern hat man eben einige informationen in die chips gebrannt.

deswegen sagt eine cpu eigentlich immer die gleiche kennung.
vielleicht hast du wegen der fummelei am bios nun die funktion zur erkennung abgeschaltet und dxdiag muss messen. du hast schätzungsweise 2133.33MHz (für einen 2600XP througbred) für was anderes wäre dein FSB zu klein. die anzeige müßte also stimmen denk ich mir.

wobei mir dann die 2Ghz von früher komisch vorkommen! wäre nämlich ein 2400XP was da deine cpu über sich sagt...

naja, so genau kenn ich mich nicht aus...

MfG
micki

x-dragon
2003-11-04, 15:55:38
Achso das könnte vielleicht die Ursache sein.

Normal hat die CPU 1995 MHz (133*15), allerdings läuft der FSB (dank meines Chefs der vorhin noch etwas im BIOS rumgespielt hat) aktuell auf 140, was dann also die 2100 MHz erklärt :).