Delphi - Processzor adatok lekérdezése

forráskód letöltése
Ha a készítendő programunkban szükségünk van a gépben lévő processzor vagy processzorok adataira, akkor jól jön az ebben a cikkben bemutatott komponens. A mellékelt példaprogram megnyitása előtt a CentralProcessor.pas-ban lévő komponenst telepítenie kell a Delphi alá.

Ha valaki abban a szerencsés helyzetben van, hogy több processzor is ketyeg a gépében, akkor a Processor property-n keresztül megadhatja, hogy melyik sorszámú CPU adataira kíváncsi. A NumberOfCPUs property-ből kiolvasható, hogy összesen hány processzor található a gépben. Az MHz property, mint a neve is mutatja, a processzor sebességét adja meg MHz-ben. Az Identifier a CPU szöveges azonosítója, míg a VendorIdentifier a gyártóé.
Mindezeket az adatokat a Registry-ben találhatjuk meg, a HKEY_LOCAL_MACHINE azonosítón belül a „\HARDWARE\DESCRIPTION\System\CentralProcessor” címen. A címen további kulcsokat találhatunk, amelyek a CPU-k adatait tartalmazzák. Az első processzor kulcsa a „0”, a másodiké „1”, stb.
A CPU adatait a Refresh eljárásban olvassuk ki a Registry-ből a TRegistry osztály felhasználásával. Miután sikerült megnyitni a fent említett címet, a TRegistry osztály GetKeyInfo eljárásával lekérdezzük az adott kulcs adatait egy TRegKeyInfo típusú változóba. Ennek a változónak most csak a NumSubKeys mezőjére vagyunk kíváncsiak, mivel ebből tudjuk meg a processzorok számát:
reg.GetKeyInfo(info);
FNumberOfCPUs:=info.NumSubKeys;
A következő lépésben megnyitjuk a kiválasztott processzorhoz (FProcessor) tartozó kulcsot, és kiolvassuk a megfelelő adatokat. A sebességre vonatkozó adatot (~MHz) sajnos csak Windows 2000 alatt találjuk meg a Registry-ben. Éppen ezért létrehozunk egy függvényt, ami kiszámolja a processzor órajelét. Ez a függvény a GetCPUSpeed.
Az órajel megállapításához az RDTSC gépi kódú utasítást használjuk, ami sajnos nincs implementálva a Delphi beépített assembly fordítójába. A kódja $310F, tehát ha ezt tudjuk akkor nincs baj, a következő megoldást használhatjuk:
  asm
    dw 310Fh
    mov tl, eax
  end;
Az RDTSC utasítás végrehajtása után az eredményt eltároljuk a lt változóban. Ezután várakozunk egy ideig, esetünkben 1 másodpercig:
  Sleep(1000);
Újra meghívjuk az RDTSC utasítást, és az eredményt kivonjuk az előzőleg eltárolt értékből. Így megtudhatjuk, hogy a várakozási idő alatt a számláló értéke mennyit változott.
  asm
    dw 310Fh
    sub eax, tl
    mov tl, eax
  end;
A kapott eredményből kiszámíthatjuk a processzor órajelét:
  Result:=Round(tl/1000000);