2003.04.12 (土) 03:38:33 <Heracules> ちょっとだけ書いてみた>CPUIDが使用可能かのチェック・VendorID、CPUType、Family、Model、Stepの所得方法
2003.04.12 (土) 04:54:07 <Heracules> ClawHammerのCPUIDは0f00hのようです
2003.04.16 (水) 00:12:51 <Heracules> CrusoeはMMXのみ対応、SSEや3DNow!は現状では未対応の模様
2003.04.26 (土) 17:24:40 <Heracules> CPUID.pas完成しました。FASSの次期verにて組み込みます(pasファイルは公開予定)
2003.04.27 (日) 11:39:24 <Heracules> Intelの資料によると、486の一部+Pentium以降全てでCPUID命令実行可能=386は全て不可能なので組み込む必要がない。
2003.04.27 (日) 11:40:00 <Heracules> なのですが、海外のサイトをまわってみたところ、一部の386はCPUID実行が可能なようですので、一応組み込みました。
2003.04.27 (日) 13:38:47 <Heracules> PenII系まではL2でのみ判別しなければならないようです>Celeronとか
2003.04.27 (日) 13:39:06 <Heracules> Pen!!!以降はブランドIDでの識別が可能なようです。
2003.04.28 (月) 22:41:09 <Heracules> Pentium4のL2が識別時0KBになる問題を修正。これでCPU識別関係はほぼ完璧かと。
2003.05.01 (木) 02:24:44 <Heracules> CPUID.pas v0.3.3を公開しました。ライセンス関係についてはまだ決めてませんがたぶんGPL。
2003.05.01 (木) 02:31:59 <Heracules> バックログをファイル化、他、資料をファイル化し添付。
2003.05.01 (木) 02:52:12 <Heracules> GetCPUName関数はコード自体が時間がなかったのでかなり汚いと思います。近々まとめて直すのでご了承ください。
2003.05.02 (金) 01:15:35 <Heracules> L3キャッシュ1MB版XeonDP(Gallatinと同等、Northwoodコア)が登場したそうです。
2003.05.02 (金) 01:17:30 <Heracules> L3キャッシュ1MB搭載したPentium4(Gallatinと同等、Northwoodコア)もIntelは用意してい“た”そうです(サンプルプロセッサが存在する可能性あり、対応することが好ましいかも)。
2003.05.02 (金) 15:55:07 <Heracules> CPUID.pas v0.4.5を公開しました。
2003.05.02 (金) 15:55:29 <Heracules> Opteronのモデルナンバー算出ルーチンを実装。
2003.05.02 (金) 15:56:28 <Heracules> VIA C3(Samuel2/Ezra/Ezra-T)とAMD Duron(0630h)のL2所得を正常になるようにしました。
2003.05.02 (金) 15:56:56 <Heracules> GetL2Cache関数を廃し、GetCPUCache関数を実装。
2003.05.02 (金) 16:17:42 <Heracules> v0.4.6公開(L1容量所得ルーチンのバグ修正)。
2003.05.02 (金) 20:24:47 <u*j*2*6*> CPUID.pasは、最終的に全部のCPU情報をとれるようにするのかな?
2003.05.02 (金) 20:25:29 <u*j*2*6*> 「各CPUへの最適化」プロジェクトがまちどおしい!
2003.05.05 (月) 05:47:01 <Heracules> v0.4.6:CyrixとCentaurに両方WinChip2A/Bがありますが、正しくはCentaurだけです(誤入力
2003.05.05 (月) 07:03:22 <Heracules> Sleep APIの精度の壁にぶつかりました@クロック所得関数
2003.05.05 (月) 07:29:34 <Heracules> Sleepの代わりにtimeGetTime?使うことで解決しそうです
2003.05.05 (月) 09:37:09 <Heracules> CPUID.pas v0.5.0を公開しました。
2003.05.17 (土) 01:21:24 <Heracules> timeGetTime?よりもっと精度の高いQueryPerformanceTimer?を使用するように書き換え中です
2003.05.17 (土) 01:22:12 <Heracules> FSBや倍率を所得するのにはRDMSR命令を使用します(特権命令)
2003.05.17 (土) 01:23:04 <Heracules> 特権命令は、9x/meではそのまま使えますが、nt/2k/xpではドライバの作成が必要になります
2003.05.20 (火) 00:02:03 <Heracules> QueryPerformanceCounter使用のサンプル(Delphi6用)を書いてみたんですが、ウマく動いてくれないです(−−;
2003.05.20 (火) 00:33:06 <u*j*2*6*> マイクロソフトのサイトにこんな情報があったけど関係ないかな:2ギガ以上のCPUでQPC使うときの注意
2003.05.20 (火) 00:34:30 <u*j*2*6*> もう1コおまけ
2003.05.20 (火) 01:37:50 <Heracules> 2GHz以上の〜 のやつは32bit変数型を使用した場合の問題なので、違うと思います(HyperThreading?もAthlonXPなのでないですし)。
2003.05.20 (火) 01:47:02 <Heracules> 一応、VC用の各種サンプルなどを参考に書いたので・・・間違ってないと思うんだけど(最初に0除算で引っかかって、あとはエラーを吐きまくってる模様(−−;←やっぱり間違ってるかなーw
2003.05.24 (土) 00:58:16 <Heracules> 精度に関わる処理なので、timeGetTimeAPIを呼ぶ場合にも、MMSystemのラッピングしたものではなくwinmm.dllを直接呼び出したほうが精度がよくなると思って軽く書き直してみたら、かなり精度があがりました(CPUクロック表示時で10MHzぶんくらいw
2003.05.24 (土) 01:00:57 <Heracules> usesのMMSystemをはずして、function timeGetTime: Int64; external 'winmm.dll';を追加すればok(あとでpasファイル更新します
2003.05.24 (土) 01:43:38 <Heracules> ・・・メインスレッドが終了時にえらー吐くようになっちゃってちょっと検証できなくなったのであとまわし(−−;
2003.05.24 (土) 04:49:26 <Heracules> DWORD(=Longword)でいいかも>timeGetTimeの戻り値
2003.05.24 (土) 04:50:36 <Heracules> コンパイルは通るけど実行するとエラー吐くようになっちゃった(−−;
2003.07.04 (金) 23:12:23 <Heracules> ひよひよ氏(CrystalDewWorld?)より、AMD製CPUのMobile版とDesktop版の識別ルーチンを提供していただきました。
2003.07.04 (金) 23:15:43 <Heracules> Thortonへの対応:既存Barton(CPUID:06Ax)識別コードでのL2キャッシュ容量チェック(512K: Barton/256K: Thorton)にて可能と思われます(現物がリリースされてないので不明ですが)。
2003.07.05 (土) 16:29:24 <Heracules> Intel製CPUの場合のDesktop/Mobile識別方法について(箇条書き)
2003.07.05 (土) 16:30:12 <Heracules> ・Celeron(Northwood)の場合、MobileCeleron?のL2キャッシュは256KですがDesktopのCeleronは128Kなので識別が可能
2003.07.05 (土) 16:31:03 <Heracules> ですが、・・・他のCPUの識別について、なんらかの案を考える必要があるかと思います。
2003.07.05 (土) 16:31:54 <Heracules> 実際に存在するクロックとHyperThreading?の対応の有無などの詳細な情報をテーブル化すれば、不可能ではないかもしれませんが・・・。SpeedStep?の有無をチェックする方法でもいいかも>Pentium系は。
2003.07.29 (火) 02:19:31 <Heracules> Pen4 M-0ステップ、CPUID:0F25h。9/1登場予定らしい。
2003.07.29 (火) 02:22:53 <Heracules> Thortonは「AthlonFX」になるらしい。
2003.07.29 (火) 02:46:39 <Heracules> CPUID.pas v0.6.0はモバイルCPUとデスクトップCPUの識別などが詳しくできるようになる予定
2003.07.29 (火) 02:46:59 <Heracules> マルチプロセッサには現状では対応できてませんw
2003.09.01 (月) 05:13:10 <Heracules> Durom 1.4/1.6/1.8GHzはModel8らしいです。
2003.09.01 (月) 05:13:34 <Heracules> >Thoroughbredとの識別が新たに必要になると思います。
2003.09.01 (月) 05:15:59 <Heracules> http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25848.PDF
2003.09.01 (月) 06:37:59 <Heracules> L2キャッシュの容量とModel8であることからDuronと判別するように書けばひとまず問題ないと思う(Stepがいくつなのかが不明のため暫定処理)
2003.09.01 (月) 14:04:47 <Heracules> AMDの資料から>L2キャッシュ256KB以上:Athlon、未満:Duron
2003.09.01 (月) 14:05:16 <Heracules> AthlonXPとMPの識別:Extendedのbit19(MP Capable)で可能。
2003.09.01 (月) 14:06:02 <Heracules> ちなみに、Duron Model 8は0680hと0681hの二つが存在する模様。
2003.09.01 (月) 14:08:04 <Heracules> v0.6.0を近いうちに出します。予定:AthlonXP/MP/MobileAthlonXP(4)の識別に対応、Pen4 M-0 stepに対応、Duron Model 8に対応。
2003.09.02 (火) 03:38:36 <Heracules> CPUID.pas v0.6.0
2003.09.02 (火) 03:39:10 <Heracules> SSE3、Prescottにも対応。
2003.09.02 (火) 03:39:50 <Heracules> Itanium2はFamily15で、ExtFamily?が1。通常のFamilyだけではPen4と区別ができません。
2003.09.03 (水) 20:28:44 <Heracules> CPUID.pas v0.6.0のCheckAMDMobile関数ですが、ちょっと勘違いしてた。
2003.09.03 (水) 20:29:49 <Heracules> C言語の理解が甘いからなんですが・・・「>>」はシフトで、ようは2bit目をチェックしてその結果をIntで返してるみたい・・・w
2003.09.03 (水) 20:30:29 <Heracules> さっきひよひよさんに聞きましたw 感謝です。
2003.09.03 (水) 20:31:15 <Heracules> Delphi版ではBoolで返すようにしたのでif (dwEDX and $2)=$2 then Result:=True else Result:=False;にすればokかと。
2003.09.05 (金) 17:49:48 <Heracules> CPUID.pas v0.7.0で関数の互換性がなくなります。ご了承ください。
2003.09.05 (金) 17:50:23 <Heracules> アセンブラで書けそうなところを極力アセンブラで書く方針。

SlavaDevにアセンブラを組み込んでみようというプロジェクトです。
ひとまずはCPU情報の所得から開始ということで「CPUID」プロジェクトとなりました。
CPUID.pas v0.5.0 by Heracules

#areaedit

・CPUIDが使用できるかのチェック:フラグレジスタの21ビット目が
 書き換えられるかどうかでチェック
・ベンダーIDの所得:EAXレジスタに0を入れてCPUID命令実行ののち、
 EBX>EDX>ECXの順に並べる
・CPUType/Family/Model/Step所得:EAXレジスタに1を入れてCPUID命令実行、
 EAXレジスタに値が戻る。下位14bit(上位から2bitがType、
 以下4bitずつFamily、Model、Stepの順)。
・Intel製CPUの識別にはCPUIDだけではなくBrandIDも利用する(PenIII系以降)。
 PenII系はL2容量にて識別。その際、TLB位置を予測・推測してコードを
 書いてはならない。
・L2所得
 Intel製CPU 'GenuineIntel' - EAXに2を入れてCPUID、EAXの8〜31、
  EBX,ECX,EDX全bit計15個のTBLのどこかにL2キャッシュ容量の情報TBLが存在。
 Centaur製CPU 'CentaurHauls' - EAXに80000006hを入れてCPUID、ECXの上位8bit。
 他ベンダ製CPU - EAXに80000006hを入れてCPUID、ECXの上位16bit。

#areaedit(end)

CPU Type
11  reserved 
10  secondary CPU 
01  overdrive CPU 
00  primary CPU 

CPUID.pas v0.5.0現在実装されている関数

・GetCPUID CPUID実行関数。
  引数1:EAXレジスタに投入する値(: 整数型)
  引数2:戻り値の格納先(: TCPUID)
・GetCPUName CPU名称所得関数。
  引数は取りません。
・GetCPUCache キャッシュ容量所得関数。
  引数:戻り値の格納先(: TCPUCache)
・EnableRDTSC RDTSC命令が使用可能かどうかをチェックするだけの関数。
  引数は取りません。
・GetCPUClock CPU動作クロック所得関数。
  引数は取りません。

v0.3.xとの互換のために - 下記の関数を組み込み呼び出すことで互換を取ることが出来ます。

function GetL2Cache: Integer;
var
  CPUCache : TCPUCache;
  L2Cache  : Integer;
begin
  if GetCPUCache(CPUCache) then
    L2Cache:=CPUCache.L2;
  Result:=L2Cache;
end;

QueryPerformanceCounterのDelphiでの使用

==宣言部==
function QueryPerformanceCounter(var X: Int64): Boolean; external 'Kernel32';
function QueryPerformanceFrequency(var X: Int64): Boolean; external 'Kernel32';

==呼び出し部==
var
  iStart   : Int64;
  iEnd     : Int64;
  iFreq    : Int64;
  totalTime: Int64;
begin
  QueryPerformanceFreq(iFreq);
  QueryPerformanceCounter(iStart);
//  測定したい処理を書く
  QueryPerformanceCounter(iEnd);
  totalTime := (iEnd - iStart) / (iFreq div 1000) // ミリ秒
// totalTime := (iEnd - iStart) / iFreq // 秒
end;

AMD製CPUのMobile版とDesktop版の識別

int CCPUInfo::CheckAMDMobile()
{
	DWORD dwEDX;
	_asm{
		mov eax,0x80000007
		cpuid
		mov dwEDX , edx
	}
	return (dwEDX >> 1) & 0x1;
}

ソースコード提供:ひよひよ氏(CrystalDewWorld)

アセンブラで書き直したらエラーが出る関数(原因わかる方・・・(苦笑

function EnableRDTSC: Boolean;
begin
  asm
    push ebx
    mov eax, $00
    dw $A20F
    cmp eax, $00
    jz @@ERR
    mov eax, $01
    dw $A20F
    shr edx, $04
    and edx, $01
    cmp edx, $00
    jz @@ERR
    mov @Result, $01
    jmp @@EXIT
@@ERR:
    mov @Result, $00
@@EXIT:
    pop ebx
  end;
end;