Windows XP에서 시스템 등록 정보에 보면 컴퓨터에 대한 정보가 나옵니다.
방법은?
  1. 탐색기 -> 마우스 포인터를 "내 컴퓨터" 위로 옮기고 마우스 오른쪽 버튼 -> 속성(R)
  2. 키보드 윈도 버튼 + Pause Break 버튼

XP는 위의 그림과 같이 아주 간단한 CPU 정보(위 그림의 빨간 상자안)를 보여줍니다.
Intel(R) Core(TM)2 Quad CPU
 Q9400 @ 2.66GHz

이와 같은 정보를 프로그램적으로 얻을 수 있는 방법은 없을까?


레지스트리를 보면?

다음 레지스트리의 ProcessorNameString 문자열 키값을 보면 동일한 정보("Intel(R) Core(TM)2 Quad CPU    Q9400  @ 2.66GHz")가 들어 있습니다.
[HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0]


레지스트리 정보는 왠지 누군가(?) 바꿔 놓을 수도 있을 것 같다는 생각이 듭니다. 근데 누가 왜 이걸 바꾸죠? 여하튼 누군가 이걸 바꿔 놓는다면 힘들게(?) 얻어온 값이 의미가 없어지겠군요.  프로그램적으로 레지스트리를 보지 않고 이런 정보를 얻을 수 있는 방법이 없을 까요?


프로그램에서 얻을 수 있는 방법

동영상에 관심이 있으신 분들은 키플님이 만드신 바닥이라는 프로그램을 아실 것입니다. 한 시대를 풍미했던 유명한 동영상 변환 프로그램입니다. 그런데 바닥이라는 프로그램은 mencoder를 사용합니다. mencoder는 MPlayer라는 유명한 오픈소스 동영상 재생/인코딩 소프트웨어에 들어 있는 프로그램입니다. 여기서 잠깐 바닥에 들어있는 mencoder를 실행해보면 다음과 같은 결과가 나옵니다. (키플님 고맙습니다.)

C:\BADAK>mencoder.exe
MEncoder dev-SVN-r28034 (for BADAK) (C) 2000-2008 MPlayer Team
CPU: Intel(R) Core(TM)2 Quad CPU    Q9400  @ 2.66GHz (Family: 6, Model: 23, Stepping: 10)
CPUflags: Type: 6 MMX: 1 MMX2: 1 3DNow: 0 3DNow2: 0 SSE: 1 SSE2: 1
Compiled with runtime CPU detection.
No file given

Exiting... (error parsing command line)

C:\BADAK>

보이시나요? 위에서 봤던 동일한 정보가 보입니다. 추가로 CPU에 대한 자세한 정보가 나옵니다. 그렇습니다. mencoder 소스 코드를 보면 어떤 방법으로 구현이 가능한 지 알 수 있을 것 같습니다. 참고로 MPlayer는 윈도가 아닌 Linux 등 다른 환경에서도 잘 돌아가는 녀석이라 분명히 레지스트리 정보를 이용하지는 않았을 것이라고 생각했습니다.

실제 MPlayer 소스코드를 받아서 "CPU:"로 검색해 봤더니 cpudetect.c 파일에 관련 정보가 있었습니다. 코드를 보다보니 중요한 부분은 do_cpuid() 함수였습니다. 보시면 아시겠지만 인라인 어셈(inline assembly)으로 cpuid 명령(instruction)을 실행하고 있습니다.
static void
do_cpuid(unsigned int ax, unsigned int *p)
{
#if 0
	__asm__ volatile(
	"cpuid;"
	: "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
	:  "0" (ax)
	);
#else
// code from libavcodec:
    __asm__ volatile
	("mov %%"REG_b", %%"REG_S"\n\t"
         "cpuid\n\t"
         "xchg %%"REG_b", %%"REG_S
         : "=a" (p[0]), "=S" (p[1]),
           "=c" (p[2]), "=d" (p[3])
         : "0" (ax));
#endif
}
여기서 cpuid라는 명령이 어떤 명령인지 알고 싶어졌습니다. Wikipedia관련 정보가 있습니다. 이 명령은 CPU에 대한 자세한 정보를 얻을 수 있는 명령이었습니다. 참고로 486 이상에서는 동작합니다. 

설명을 보면 "EAX = 80000002h, 80000003h, 80000004h: Processor Brand String" 이라는 부분이 있습니다. 그렇군요. 위의 간단한 CPU 정보가 Processor Brand String 이었던 것입니다.

이 정보를 이용해서 아래와 같이 간단히 코드를 만들어 실행해봅니다.
void do_cpuid(int idType, int *val)
{
	int reg_ax, reg_bx, reg_cx, reg_dx;
	__asm {
		mov eax, idType;
		cpuid;
		mov reg_ax, eax;
		mov reg_bx, ebx;
		mov reg_cx, ecx;
		mov reg_dx, edx;
	}
	*(val + 0) = reg_ax;
	*(val + 1) = reg_bx;
	*(val + 2) = reg_cx;
	*(val + 3) = reg_dx;
}

int main(int argc, char* argv[])
{
	printf("Hello World!\n");

	int val[5];
	val[4] = 0;
	do_cpuid(0x80000002, val);
	printf("%s\r\n", &val[0]);
	do_cpuid(0x80000003, val);
	printf("%s\r\n", &val[0]);
	do_cpuid(0x80000004, val);
	printf("%s\r\n", &val[0]);
	return 0;
}

결과는 다음과 같습니다.
Hello World!
Intel(R) Core(TM
)2 Quad CPU    Q
9400  @ 2.66GHz

그렇습니다. CPU 정보는 CPU에게 물어보면 되는 것이었습니다!!!

그런데 위 Wikipedia의 정보를 보다보면 MSDN에 이에 대한 정보가 있다고 합니다. 들어가봤더니 intrinsic으로 __cpuid()를 지원합니다. CPU한테 물어봐서 얻을 수 있는 정보도 잘 정리되어 있고 예제 코드도 있습니다. __cpuid()는 위의 간단한 예제 코드를 intrinsic으로 만들어 놓은 것이군요. 털썩! 

하나 더, __cpuid()는 VC++ 6.0 에서 동작하지 않습니다. 그렇습니다. 최근 툴을 쓰면 위와 같은 노가다를 뛸 필요없이 바로 실행되는 코드를 만들 수 있었던 것입니다. VC++ 2005 이상에서는 동작하네요. 그 사이 버전은 어떨 지 모르겠습니다. VC++ 6.0을 사용하지 말아야 하는 이유가 하나 더 늘었군요.


정리해보면 ...

CPU 정보를 얻고 싶으면 cpuid라는 명령을 사용해서 CPU에게 물어보면 된다. 노가다를 덜 뛰려면 최근 툴을 사용해라. (뭔가 결론이 이상하긴 합니다. ^^;)


그런데 여기서 궁금증이... CPU-Z로 유명한 CPUID는 이 명령을 가지고 놀다가 만들어진 회사일까?

신고

'프로그래밍' 카테고리의 다른 글

CPU 정보를 어떻게 알 수 있을까?  (0) 2010.04.23
Win32 API Multithreading 시 주의점  (0) 2010.04.20
top

Write a comment





티스토리 툴바