CPUコアの温度を取得する
~マエガキ~
手元にAMDのCPUが無いのでIntel製CPUのみを調べる対象にしています。
また、この記事を書く最中に内容を一度消してしまっているので、説明が適当でない部分も多々。
参考文書
・Intel 64 and IA-32 Architectures Software Developer's Manuals
特に参考となる箇所
・Volume 3A - 13.5.5 On Die Digital Thermal Sensors
・Volume 3B - Appendix B.1 Architectual MSRs
CPU温度はMSRと呼ばれる、CPU内部の特殊なレジスタのアドレス 0x19C から読み取ることができるらしい。
MSRにどうやってアクセスするのか調べていたところ、WinRing0 を発見!
というわけで、これを使ってMSRにアクセスしCPU温度を読み取るプログラムを作ってみた。
コンパクトにまとめるとこんな感じ。
// MSR取得
//-----------------------------------------------------------------------------
uint index = 0, eax = 0, edx = 0; index = 0x0000019C; // アドレス(0x19c)
RdmsrEx(index, ref eax, ref edx, (UIntPtr)1);//MSRの指定アドレスの値を取得(WinRing0使用)
//-----------------------------------------------------------------------------
// 取得した値からCPU温度を算出
//-----------------------------------------------------------------------------
uint tempr = (eax & 0x003F0000);
tempr = tempr >> 16;
tempr = 100 - tempr;//今回TCCは100とする。CPUの種類によってはTCCの値が異なってくるかも。 System.Windows.Forms.MessageBox.Show(tempr.ToString());//CPU温度の値を表示
MSRへのアクセスにはRDMSR命令(0F 32)を使います。
WinRing0ではRdmsrEx関数がそれに相当します。
MSRから値を取得したあと、ビット演算(論理積)でCPU温度(Digital Readout)の値を抜き出しています。
ここでC#では2進数が使えないので、16進数を使っています。
その後、ビット列を右にシフトして TCCから今の値を引くと、CPU温度になります。
ちなみにCore2Duoプロセッサでは TCC=100 となっています。
TCCについては各プロセッサのデーターシートを参照してください。
↑TCCの情報はTjunctionと同じような扱い(非公開)だったと思います。