Announcement

Collapse
No announcement yet.

CPU- / FSB-Takt ausgeben

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • CPU- / FSB-Takt ausgeben

    Hallo,

    wie kann man den CPU- / und FSB- Takt ausgeben, am besten auch noch den Prozessor-Typ (Duron, T-Bird, XP, Pentium, ...)??

    Vielen Dank und Gruß, Jens

  • #2
    In der JCL(http://www.delphi-jedi.org, Download unter http://sourceforge.net/projects/jcl) gibt es einen Abschnitt Hardware welcher das gewünschte liefern sollte (Funktion CPUID)

    Comment


    • #3
      Die JCL ist leider bei diesen Sachen nicht komplett uptodate. Zumindest kennt sie nicht alle modernen Prozessoren beim Namen.<br>
      Das mit dem Takt ist schwieriger. Dazu gibt es naemlich kein standardisiertes API

      Comment


      • #4
        Grundsätzlich ist die Ermittlung der Taktfrequenz relativ einfach.<br>
        Das Problem damit, bzw. der meisten Sourcen im WEB, ist das die meisten einen schlechten bzw. falschen Algorithmus nutzen.<br>
        Um die Taktfrequenz zu ermitteln benötigt man immer eine Referenzfrequenz, sprich Timer. Relativ zu diesem Timer werden dann die CPU Takte gezählt, was dann die Taktfrequenz ergibt.<br>
        Wenn du im WEB suchst findest du einiges an Sourcen.<br>
        Die meisten nutzen als Referenztimer die Funktion Sleep(). Das ist aber Schwachsinn da Sleep() eben vom Processsheduler abhängig ist. Um Meßfehler zu vermeiden nutzen diese Sourcen SetProcessPriorityClass() SetThreadPriority() und setzen den Meßalgo. auf Realtime. Dies nützt aber nur wenig und deshalb wird meisten eine zu lange Zeitspanne zum messen benötigt. Mit Sleep() sollten es 1-10 Sekunden sein. Diese Messung wird mehrmals wiederholt und dann per aufwendigen statistischen Verfahren der Mittelwert gebildet.<br>
        All das macht es sehr kompliziert und ungenau. Ich glaube die JEDI Sourcen gehen so ähnlich vor.<br>

        ABER: der Fehler dieser Algos. besteht in deren Referenzquelle. Normalerweise hat jeder PC einen RTC = Real Timer Clock der mit >1.7 MHz getaktet wird. Im Gegensatz zum Sleep() das mit 1 KHz getaktet wird, sprich < 1/1000 Sekunde genau. Normalerweise wird der RTC über QueryPerformanceCounter() und QueryPerformanceFrequncy() ausgelesen.<br>

        So nun liegt die Lösung auf der Hand. Man nutzt den RTSC = Real Time Stamp Counter der CPU um den aktuellen Takzyklus zu ermitteln. Dann liest man mit QueryPerformanceCounter() den RTC aus. Nun wird ca. 1-10 ms gewartet. Es ist egal ob man mit Sleep() wartet, oder Application.ProcessMessages mehrmals aufruft. Diese Wartezeit sollte nur 1 ms übersteigen. Nun liest man wiederum den RTSC und RTC aus. Wir haben nun 4 Werte, die relativ zueinander zwei Timer/Frequnzen darstellen. Diese lassen sich sehr einfach in die Taktzyklen pro Sekunde = CPU Taktfrequnz umrechnen. Fertig.<br>

        Nun zur Genauigkeit: bei einem 1GHz Rechner wird mit Sleep(1000) eine Genaugikeit von 1/1000 Sekunde zu 1.000.000.000 Zyklen erreicht, sprich +- 1.000.000Hz = 1MHz. Mit QueryPerformanceFrequncy = 1.700.000Hz eine Genauigkei von +- 588 Hz. Damit ist die zweite Methode ca. 1700 mal genauer innerhalb einer Sekunde, oder aber man braucht nur 1700'tel Sekunde lang zu messen um die gleichen Resultate wie mit Sleep(1000) zu erreichen !!.<br>

        So es gibt aber noch einige Probleme:
        <li>die CPU muß ein RTSC haben, was bei allen neueren Rechner absolut der Fall ist
        <li>das OS muß den RTC = Timerchip auslesen können, was bei Windows OS der Fall ist, QueryPerformanceCounter()
        <li>das OS muß die RTC-Taktfrequenz uns mitteilen können, was mit QueryPerfromanceFrequncy() möglich ist.<br>

        Hier nochmal ein kleiner Pseudocode:

        <pre>

        function QueryRTSC: Int64;
        asm
        RTSC
        end;<br>

        var
        StartRTC,StopRTC,FreqRTC: Int64;
        StartRTSC,StopRTSC: Int64;
        CPUFreq: Double;
        begin
        StartRTC := QueryPerformanceCounter;
        StartRTSC := QueryRTSC;
        Sleep(10); // oder auch anderes
        StopRTC : QueryPerormanceCounter;
        StopRTSC := QueryRTSC;<br>

        CPUFreq := (StopRTC - StartRTC) * QueryPeformanceFrequncy / (StopRTSC - StartRTSC) / 1.000.000 {MHz};
        end;

        </pre>

        Als weitere Glättung des Resultats muß man nur wissen das die CPU Taktfrequnzen standardisiert wurden. D.h. die Schrittweiten der möglichen Taktfrequnzen sind bekannt. (abhängig vom Hersteller und CPU Typ). Somit kann man sehr schnell die ermittelte Takfrequnz an den nächsten, im Toleranzbereich liegenden Wert, angleichen. Sollte die Abweichung zu enorm sein, sprich +-50MHz dann liegt entweder ein grober Meßfehler vor oder man hat es mit einem übertakteten Motherborad zu tun. Einfach dann nochmal messen.<br>

        Ich selber habe einige CPU Routinen gecodet und komme mit obiger Methode auf eine Meßgenauigkeit von +-100Hz bei nur 1 Millisekunde Meßdauer auf jeweils 3 Meßrunden verteilet.<br>
        &#10

        Comment


        • #5
          D.h. die berechnete Frequenz von 666.73Mhz ist exakt für eine CPU mit 667MHz laut Hersteller.<br>

          Gruß Hage

          Comment


          • #6
            Hallo Hagen und alle anderen,

            wunderbar, vielen Dank!

            Gruß, Jen

            Comment


            • #7
              Der Jedi code kann dieses schoene Verfahern nicht nutzen, da er aus der Zeit vor dem RTSC stammt. Duerfen wir deine Source verwenden

              Comment


              • #8
                Jo warum nicht, ist ja kein vollständiger Source. Ich habe ja nur den notwendigen Algorithmus beschrieben

                Gruß Hage

                Comment

                Working...
                X