SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

CPUIDチュートリアル

CPUID命令によるCPUの性能・機能の把握

インテル系のCPUに実装されているCPUID命令の考察


  • X ポスト
  • このエントリーをはてなブックマークに追加

littleCPUIDの実装

littleCPUIDによるデモ

  • CPUID命令表示機能[Dump]
  • CPUID命令で取得できたデータの全ての値を出力します。プロセッサが複数ある場合、各プロセッサごとに取得します。
  • CPUがサポートしている機能の表示[Feature Flags]
  • CPUID命令よりCPUがどの機能をサポートしているかを判断し表示します。サポートしていない機能についてはグレーで表示し、ボタンが押せないようにしています。完成図の表示例の場合、「MMX」や「SSE」はサポートしているものの「HTT(Hyper-Threading)」はサポートしていないことが分かります。
    また実際には使用できないケースでもCPUが対応している場合は有効と表示しています。例えばWindows XP(32-bit版)で動作していてもCPUがx64(AMD64/EM64T)に対応している場合は、表示は有効になります。また、EISTやHyper-Threading機能などの場合、CPU以外にもBIOSやChipsetの対応も必要で、CPUのみが対応していてもトータルで対応出来ない場合があります。この場合でもCPUが対応しているとFlagを立てているのを優先し、有効としています。CPUが対応しているからと言って対応可能だと判断しないよう気をつけてください。
  • SyncHackへの接続[Enable SyncHack Connection]
  • この設定が有効(デフォルトでは無効)にし「Feature Flags」のボタンを押すことで該当する SyncHack のWebページに接続する機能を加えました。SyncHackは私が運営するWebページで、より詳しい内容を掲載出来たら面白いなと思い、実装しました。例えばMTRRが有効だった場合、[Enable SyncHack Connection]にチェックを入れて[MTRR]ボタンを押すとSyncHackの該当するWebページである CPU/CPUID/MTRR - SyncHack を開きます。
    今の所、まだあまりSyncHackの方が充実していないので面白くないかもしれません。私のパワー不足です。ごめんなさい。

littleCPUIDのアルゴリズム

 CPUIDの特性上、動的に変更されることはほとんど無いはずです。よって起動時にCPUID命令で取得できるデータを取れるだけ取って、そのデータを使いまわすことにしました。以下のアルゴリズムで全てのCPUIDの値を取得しています。

  1. CPUID(0) の取得
  2. CPUID命令をサポートしているCPUは必ず何らかの値を返却します。CPUID(0)が返却されない場合、CPUID命令をサポートしていないと判断します。またCPUID(0) の返却値EAXよりCPUIDの最大長が分かります。例えばEAXが4の場合、CPUID(0)、CPUID(1)、CPUID(2)、CPUID(3)、CPUID(4) で有効な値が返却されます。このケースでは例えば最大長以上のCPUID(1000) を取得しようとした場合、CPUIDの最大値であるCPUID(4) の値が返却されます。
  3. CPUID(x) の取得
  4. CPUID(0) のEAXより有効なCPUID(0)-CPUID(x) の全ての値を取得します。
  5. CPUID(8000-0000h) の取得
  6. 8000-0000hより上のCPUIDは 拡張CPUIDとして区別されており、別途対応可能か確認する必要があります。Extended CPUIDの場合もEAXに最大長が返却されます。例えばCPUID(8000-0000h) のEAXが8000-0004hだった場合、CPUID(8000-0000h)、CPUID(8000-0001h)、CPUID(8000-0002h)、CPUID(8000-0003h)、CPUID(8000-0004h) が有効な値となります。
  7. 拡張CPUID(y)の取得
  8. CPUID(8000-0000h) のEAXより有効なCPUID(8000-0000h)-CPUID(y) の全ての値を取得します。

「システムのプロパティ表示の不思議」の考察

 以下は上記の「システムのプロパティ」を表示しているPCのCPUIDです。

littleCPUIDで出力したIntel製CPUのCPUIDの返却値
idx=[00000000], eax=[00000002], ebx=[756E6547], ecx=[6C65746E],
 edx=[49656E69]
idx=[00000001], eax=[00000F27], ebx=[00010809], ecx=[00000400],
 edx=[BFEBFBFF]
idx=[00000002], eax=[665B5101], ebx=[00000000], ecx=[00000000],
 edx=[007B7040]
idx=[80000000], eax=[80000004], ebx=[00000000], ecx=[00000000],
 edx=[00000000]
idx=[80000001], eax=[00000000], ebx=[00000000], ecx=[00000000],
 edx=[00000000]
idx=[80000002], eax=[20202020], ebx=[20202020], ecx=[20202020],
 edx=[6E492020]
idx=[80000003], eax=[286C6574], ebx=[50202952], ecx=[69746E65],
 edx=[52286D75]
idx=[80000004], eax=[20342029], ebx=[20555043], ecx=[30342E32],
 edx=[007A4847]

 ちなみに0x20はASCII文字で表すと空白(' ')を示します。

 どうやら「システムのプロパティ」は拡張CPUIDの「プロセッサ・ブランド・ストリング(80000002-80000004h)」が影響しているようです。上記のレジスタの値より「プロセッサ・ブランド・ストリング」をASCIIで表すと以下の文字列になります('「'、'」' は含みません)。

上記のCPUのプロセッサ・ブランド・ストリング
「              Intel(R) Pentium(R) 4 CPU 2.40GHz」

 つまり先頭の空白はシステムのプロパティが「プロセッサ・ブランド・ストリング」をそのまま出力していると考えられます。

 ちなみにCPUIDはIntel社が開発したものですが拡張CPUIDは、AMD社が開発しています。AMD社の「プロセッサ・ブランド・ストリング」は頭に空白は無く、先頭から文字列が始まっています。一方、Intel社はPentium 4より拡張CPUIDを採用していますが、採用当初から先頭が空白になっていたようです。

 なぜ先頭を空白にしているかは私には分かりませんでした。多分、技術的以外の問題がそうさせているのではないでしょうか。

まとめ

 CPUID命令により、CPUに実装されている多くの機能をソフトウェアより知ることが可能であることが分かりました。

 CPUID命令を使用することにより「あらかじめ」ソフトウェア側でCPUの性能・機能を知ることができ、新しい機能を使用するか、古い機能で代用するかを切り分ける用途にも使用できます。

コラム:このような場面でもCPUID命令は使用されている、という一例
 最近、米AMD社が米Intel社に対して独占禁止法の違反があるとして訴訟を起こしたニュースが話題になっています。
 この訴訟の一つ(正確には訴訟文(PDF)の第123項)にインテル製のコンパイラがCPUIDにてAMD社製のCPUかどうか検知し、意図的に最適化されないパスに落とし込んでいる、と訴えています。AMD社の言っていることももっともなのですが、Intel社からしても販促の意味合いの強いコンパイラで他社のCPUの動作まで保障するか、と言われるとそれは難しいことなのかもしれません。

最後にお願いなど

 申し訳ないのですが下記のCPUをお持ちの方、是非littleCPUIDの[Dump]から得られた情報の提供に協力してください。CPU-Zのテキストダンプでも可能ですがCrystalCPUIDの場合、情報が足りません。

  • Pentium Extreme EditionでProcessorが4つ見えている状態
  • Opteron(Dual-core)*2でProcessorが4つ見えている状態
  • Pentium DでProcessorが2つ見えている状態
  • Athlon 64 X2でProcessorが2つ見えている状態
  • Opteron *2(Multi-processor)でProcessorが2つ見えている状態

 送信方法はCodeZineの送信箱 でも構いませんし、直接、一番下にある[メッセージを投稿]ボタンより投稿してもらっても構いません。

 現在、『CPUID命令の考察』の続きとして『マルチコアの検出方法の調査』というのを書いている最中です。CPUIDの情報だけでマルチコア、Hyper-Threading、Multi-processingを検出し、物理的に使用しているCPU数を検出するサンプルプログラムの作成をしたら面白いんじゃないか、と模索しています。

 一応、仕様書に記載している通りに実装する所までは終えています。ただ今の所、私の手元にはデュアルコアやMulti-processingの実機が無く、実際動作するかどうか確認出来ない状態です。確認でき次第『マルチコアの検出方法の調査』の方を投稿する予定にしています。

 また、littleCPUID自身はIntel/AMD以外はサポートしていません(Other CPUとして扱っています)。他のCPUももっとサポートしてほしいとお考えのアナタ、サポートはやぶさかではありません。実機を持っていないことにより対応できていないだけで、アナタの協力さえあれば対応は可能です。

 ぜひ、よろしくお願いします。

参考資料

インテル

  • 日本語技術資料のダウンロード
  • 上記のサイトにある『AP-485 インテル プロセッサの識別とCPUID命令』という資料が役に立ちます。翻訳されたAP-485は最新版の英語版とは同期が取れていませんので、常に最新情報という訳ではありませんので注意してください。必要があれば英語版を別途取得しましょう。

AMD

  • AMD Athlon 64 Processor Tech Docs
  • 上記のサイトにある『BIOS and Kernel Developer's Guide for AMD Athlon 64 and AMD Opteron Processors』(26094)という資料が役に立ちます。URLは変わりやすいので見つからない場合には再度、上記の資料を検索し直してみてください。

参考にしたサイト

  • IA-32 architecture CPUID
  • AMD/Intel以外の様々なx86系CPUのCPUIDがまとめられています。他にもsandpile.orgは仕様書にも記載されていない興味深い情報が多く、お勧め。

参考にしたツール類

  • EXDEBのダウンロード先
  • 旧NIFTY-Serveのフォーラムを中心として開発されていました。Windows標準で付属されている「debug.exe」(debug.com)ではレジスタが16-bitまでしか扱うことが出来なく、しかもCPUIDやMMXなどの比較的新しいニーモニックもいまだにサポートされていません。EXDEBは32-bitまでレジスタを扱うことが可能でCPUID命令やMMXなどのニーモニックにも対応しています。私はQuick Hackによく使用していました。
  • CPU-Zの配布場所
  • CPUID情報よりCPUの情報を表示するソフトウェアです。CPUID以外にも多くの情報を表示出来ます。
  • CrystalCPUIDの配布場所
  • CPU-Zと同じくCPUID情報よりCPUの情報を表示するソフトウェアです。こちらもCPUID以外のPC情報を表示できます。日本の方が開発していますのでコミュニケーションも日本語で出来るのはメリットかも。しかもSourceも公開しています。素晴らしい。

関連書籍

  • 『はじめて読む8086―16ビット・コンピュータをやさしく語る』 蒲地輝尚 著、アスキー、1987年3月
  • 私がアセンブラに携わった時に初めて読んだ書籍です。特にMS-DOSより付属されているDEBUGコマンドによる実習は非常に有用な情報でした。今回、EXDEBによるCPUID命令のテストを思いついたのもこの書籍のお陰です。8086ベースなので今見るとかなり古い情報になってしまいますが、CPUの基本命令であるMOV命令やADDADC)/SUBSBB)命令など、その場でアセンブラを体験できる楽しみはこの書籍以外には見たことがありません。
    これから初めてアセンブラを学んでみたいと考えている方に8086系CPUを勧めるのは若干気がひけるのですが、その場で体験できる実感はなにより大切ではないかと考えています。
  • 『はじめて読むPentiumマシン語入門編』 蒲地輝尚・水越康博 著、アスキー、2004年7月
  • 実習環境がDEBUGコマンド→Visual C++に変更されています。現状に即したアセンブラ開発が学べると思います。ちなみにlittleCPUIDもVisual C++のインラインアセンブラ機能を使用して開発を行っています。
修正履歴

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
CPUIDチュートリアル連載記事一覧

もっと読む

この記事の著者

Mc.N(エムシイエヌ)

SyncHack 管理人。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/168 2006/01/06 16:08

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング