LISTORY
[윈도우즈 시스템 프로그래밍] WIN32 vs WIN64 본문
뇌를 자극하는 윈도우즈 시스템 프로그래밍 유투브 강의 3장. WIN32 vs WIN64 정리이다.
⊙ YouTube 주소 ⊙ ☞ 3장. WIN32 vs WIN64
WIN32 vs WIN64
하드웨어 관점에서 32비트와 64비트 시스템을 설명해 보겠다.
시스템이 몇 비트인가 구분하는 데에는 두가지 기준이 있다.
① 한번에 송수신 가능한 데이터 크기
② 데이터 처리 능력
한번에 송수신 가능한 데이터 크기는 I/O 버스에 의존적이다. 즉, I/O 버스가 한번에 송수신 할 수 있는 데이터 크기를 뜻한다.
데이터 처리 능력은 CPU가 한번에 읽어들일 수 있는 명령어의 크기를 뜻한다.
만일 32비트 시스템이라 하면 16비트짜리 명령어 2개를 한번에 Fetch 가능하고, 한번에 CPU에서 32비트의 명령어를 처리할 수 있다는 뜻이다.
버스로 이동시킬땐 64비트를 이동시켰는데, 처리는 32비트만 할 수 있다면 완벽한 64비트 시스템이라 할 수 없다.
반면 프로그래머 입장에서의 64비트 시스템은 어떠한 의미를 지닐까?
사실 프로그래머 입장에서 별로 차이를 느끼지 못할 경우가 많다. 프로그래밍 하는 방식이 32비트나 64비트나 크게 다르지 않기 때문이다.
하지만 이에는 엄격한 차이가 있다.
이 차이에 대해 설명하기 전에 기본 배경이 되는 지식을 먼저 정리하겠다.
⊙ 우리가 4바이트 포인터에 익숙한 이유!
일반적으로 32비트 시스템에서는 포인터가 32비트(4바이트)이다. 마찬가지로, 64비트 시스템에서는 포인터가 64비트(8바이트)이다.
포인터가 크면 클수록 개발자에게 유리하다. 왜냐면 우리가 표현 가능한 주소의 값이 커지기 때문이다.
예를 들어 4비트로 주소 값을 표현한다하면, 우리는 16개의 주소만 표현할 수 있다.
⊙ 4비트로 주소 표현
0 0 0 0
0 0 0 1
0 0 1 0
...
1 1 1 1
즉, 포인터의 크기가 크다는 것은 그만큼 접근할 수 있는 메모리의 공간이 커진다는 것을 뜻한다.
이렇게 포인터의 크기가 크면 클수록 좋지만 하나의 문제점이 있다. 바로 버스의 크기가 몇이냐는 것이다.
만일 포인터의 크기가 128비트이고, 버스의 크기가 64비트라 가정해보자.
포인터의 크기는 바로 주소값이므로 128비트의 주소가 버스로 흘러가게 된다.
하지만 버스의 크기는 64비트이므로 이 주소를 두번에 나눠 보내줘야 한다. 이것은 시스템에 전체적인 성능 저하를 가져온다.
그렇기 때문에 32비트 시스템에서 64비트 어드레싱 방식을 쓰는 것은 상당한 성능 저하를 일으킨다.
다시 한번 정리를 해보겠다.
① 포인터의 크기는 크면 클수록 좋다.
② 포인터의 크기는 Bus가 한번에 송수신 할 수 있는 크기여야 한다.
그러므로 보편적으로 메모리는 크면 클수록 좋지만, 버스에서 한번에 전송할 수 있는 크기만큼 키워주는 것이 일반적이다.
이제껏 우리는 (현재는 64비트 시스템을 사용하지만) 32비트 시스템의 컴퓨터를 주로 사용하였으므로 4바이트의 포인터에 익숙한 것이다.
이제 다시 프로그래머에 있어 32비트와 64비트 시스템의 차이에 대해 정리하겠다.
예를 들어 우리에게 1GB의 메모리가 있다고 가정해보자. 이 메모리는 우리가 접근 가능한 메인메모리이다.
우리가 이 메모리를 접근할 때, 윗부분을 접근하던 아랫부분을 접근하던 어드레싱 타입은 일치해야한다.
이 말은 메모리의 어느 포인트를 가던 한번에 주소값을 읽을 수 있어야 한다는 말이고, 즉, 전체를 어드레싱할 수 있도록 주소값(포인터)의 크기가 충분히 커야한다는 뜻이다.
32비트 시스템에서는 한번에 access 할 수 있는 메모리의 크기는 2^32이므로 총 4GB 이다.
반면 64비트 시스템에서 access 할 수 있는 메모리는 0 ~ 2^64 -1 만큼의 크기가 된다.
이는 우리가 프로그램상에서 활용할 수 있는 최대 메모리의 크기가 증가했다는 뜻이다.
⊙ 활용 가능한 메모리의 확장
우리가 활용할 수 있는 메모리 크기가 커졌다는 것이 어떤 의미가 있는가에 대해 간단한 예로 설명해보겠다.
만일 활용 가능한 메모리가 50바이트라 가정해보자.
우리가 돌려야 하는 코드는 이렇다.
int _tmain(void)
{
TCHAR str[100];
_tscanf(_T("%s"), str);
_tprintf(_T("%s"), str);
return 0;
}
안타깝게도 이 코드는 돌아가지 않는다.. 우리는 50바이트의 메모리만 가지고 있는데 코드에서는 100바이트를 필요로하기 때문이다.
이 코드가 돌아가게 하려면 메모리를 최소화해서 사용할 수 있도록 코드를 바꾸어주어야 한다.
int _tmain(void)
{
TCHAR ch;
do
{
_tscanf(_T("%c", &ch);
_tprintf(_T("%c", ch);
} while(ch != "\n");
return 0;
}
이렇게 하면 문자열의 끝을 볼 때까지 한 바이트씩만 읽고있으므로 코드를 돌릴 수 있다.
'IT > 윈도우 프로그래밍' 카테고리의 다른 글
[윈도우즈 시스템 프로그래밍] 컴퓨터 구조의 접근 방법(1) (0) | 2018.05.19 |
---|---|
[윈도우즈 시스템 프로그래밍]프로그램 구현 관점에서의 WIN32 vs WIN64 (0) | 2018.05.18 |
[윈도우즈 시스템 프로그래밍] MBCS와 WBCS의 동시지원 (0) | 2018.05.12 |
[윈도우즈 시스템 프로그래밍] Windows에서의 유니코드(UNICODE) (0) | 2018.05.12 |
[윈도우즈 시스템 프로그래밍] 프로그램의 실행과정/하드웨어 구성의 재접근 (0) | 2018.05.12 |