這里有一段非常簡(jiǎn)單的代碼,取自網(wǎng)絡(luò),我稍加修改,貼在這里。用來(lái)檢查CPU的生產(chǎn)商和品牌,以及當(dāng)前工作頻率,如果是臺(tái)式機(jī)CPU,頻率應(yīng)該恒定,但是移動(dòng)版本的CPU,頻率不停地在變。以下代碼用Visual C++編譯,因?yàn)閮?nèi)嵌一點(diǎn)匯編,造成移植性變差(例如:GCC匯編跟AT&T匯編語(yǔ)法類似,但是MS匯編跟Intel匯編語(yǔ)法類似),以下代碼如果希望在MinGW(GCC)下編譯,需要修改那點(diǎn)內(nèi)嵌的匯編。
#include "stdafx.h"
#ifndef CPUID_HPP_
#define CPUID_HPP_
#include <string>
#include <cstring>
#include <iostream>
#include <windows.h>
typedef unsigned long DWORD;
typedef __int64 LONGLONG;
class CPUID
{
public:
CPUID() : m_eax(0), m_ebx(0), m_ecx(0), m_edx(0){}
std::string vendor(); //哪個(gè)廠商出的?Intel, AMD, VIA ?
std::string name(); //這是CPU的整體描述
LONGLONG frequency(DWORD stime = 1000);//CPU的當(dāng)前工作頻率
private:
void Executecpuid(DWORD veax);
LONGLONG cycles() const
{
DWORD h, l; //不能直接讀取,用變量過(guò)渡一下
__asm
{
rdtsc //把當(dāng)前CPU周期讀入寄存器
mov l, eax
mov h, edx
}
LONGLONG high = h, low = l;
return high << 32 | low;
}
DWORD m_eax;
DWORD m_ebx;
DWORD m_ecx;
DWORD m_edx;
};
void CPUID::Executecpuid(DWORD veax)
{
DWORD deax;
DWORD debx;
DWORD decx;
DWORD dedx;
__asm
{
mov eax, veax
cpuid
mov deax, eax
mov debx, ebx
mov decx, ecx
mov dedx, edx
}
m_eax = deax;
m_ebx = debx;
m_ecx = decx;
m_edx = dedx;
}
std::string CPUID::vendor()
{
const DWORD S = sizeof(DWORD);
char cVID[S*3+1];
std::memset(cVID, 0, sizeof(cVID));
Executecpuid(0);
std::memcpy(cVID+S*0, &m_ebx, S);
std::memcpy(cVID+S*1, &m_edx, S);
std::memcpy(cVID+S*2, &m_ecx, S);
return std::string(cVID);
}
std::string CPUID::name()
{
const DWORD vendorID = 0x80000002;
const DWORD S = sizeof(DWORD);
char cvendor[S*4*3+1];
std::memset(cvendor, 0, sizeof(cvendor));
for(DWORD i = 0; i < 3; i++)
{
Executecpuid(vendorID + i);
// 每次執(zhí)行結(jié)束后,保存四個(gè)寄存器里的ascii碼到數(shù)組
std::memcpy(cvendor + i*S*4 + S*0, &m_eax, S);
std::memcpy(cvendor + i*S*4 + S*1, &m_ebx, S);
std::memcpy(cvendor + i*S*4 + S*2, &m_ecx, S);
std::memcpy(cvendor + i*S*4 + S*3, &m_edx, S);
}
return std::string(cvendor);
}
LONGLONG CPUID::frequency(DWORD stime)
{
HANDLE hp = GetCurrentProcess();
HANDLE ht = GetCurrentThread();
DWORD pc = GetPriorityClass(hp);
DWORD tp = GetThreadPriority(ht);
BOOL flag1 = FALSE, flag2 = FALSE;
flag1 = SetPriorityClass(hp, REALTIME_PRIORITY_CLASS); //優(yōu)先級(jí)設(shè)置最高
flag2 = SetThreadPriority(ht, THREAD_PRIORITY_HIGHEST);//優(yōu)先級(jí)設(shè)置最高
//由于CPU本身時(shí)間波動(dòng)較大,因此時(shí)間從系統(tǒng)讀取,這樣比較平均
//周期除以時(shí)間就是工作頻率,即單位時(shí)間內(nèi)的周期
Sleep(stime);
LARGE_INTEGER fq, st, ed;
QueryPerformanceFrequency(&fq);
QueryPerformanceCounter(&st);
LONGLONG start = cycles();
Sleep(stime);
QueryPerformanceCounter(&ed);
LONGLONG end = cycles();
if(flag1)
SetPriorityClass(hp, pc);
if(flag2)
SetThreadPriority(ht, tp);
CloseHandle(hp);
CloseHandle(ht);
return (end - start) * fq.QuadPart / (ed.QuadPart - st.QuadPart);
}
#endif
#include <cstdio>
#include <cstdlib>
int main()
{
CPUID cpu;
std::printf("Vendor: %s\n", cpu.vendor().c_str());
std::printf("Full name: %s\n", cpu.name().c_str());
const unsigned TIMES = 3;
std::printf("Frequency(testing %d times): ", TIMES);
const double UNIT = 1000.0;
for(unsigned i = 0; i < TIMES; ++i)
{
double fre = cpu.frequency() / UNIT; // 假設(shè)CPU主頻高于1000Hz
if(fre > UNIT)
fre /= UNIT;
std::printf("%f%s ", fre, (fre > 10.0 ? "MHz" : "GHz"));
}
printf("\n");
std::system("PAUSE");
return 0;
}