[Programming] 64bit CPU에 대해서
64bit환경 컴파일을 해야 할 일이 생겨서 컴파일을 하는 중 개념이 불확실한 것들이 있어서 검색하다가 알게된 지식들을 정리해봅니다. by skyilover
저는 처음에 64bit CPU의 종류가 하나밖에 없는줄 알았습니다.
64bit용 OS에서는 64bit프로그램만 돌아가고 32bit프로그램을 돌릴려면 당연히 내부에서 에뮬레이팅을해서 돌아간다고 생각했습니다.
x64라고 부르는 놈이 64bit CPU를 말하는 이름인줄 알았죠...
하지만 64bit CPU는 두가지 종류가 있었습니다.
우선은 진짜 64bit CPU입니다. IA-64아키텍쳐를 사용합니다.
이 아키텍쳐는 Intel과 HP가 공동연구로 개발된 아키텍쳐입니다.
판매되고 있는 제품으로는 인텔의 Itanium(아이테니엄) CPU가 이에 해당됩니다. 이 CPU는 64비트 명령어셋밖에 존재하지 않기 때문에 32bit프로그램을 실행하려면 별도의 에뮬레이팅을 해야지만 실행을 할 수 있습니다.
당연히 에뮬레이팅을하면 성능이 떨어지겠구요.. IA-64용 윈도우에서는 wow64라는 플렛폼에서 에뮬레이팅해서 동작하게 된다고합니다.(실제로 해본적은 없어서 ㅠ;;)
다음은 반쪽 64bit CPU입니다. x86-64아키텍쳐를 이용하여 만들어진 CPU들입니다.
처음에 AMD에서 Intel의 64bit CPU(IA-64)들을 대항하기위해 32bit에 64bit확장을하여 32bit호환 64bit아키텍쳐를 내놓았고 그것을 AMD64ISA(AMD 64 Instructure Set Architecture)라고 명명했습니다.
Intel에서도 이미 그러한 연구들이 진행이 되고 있었지만 AMD에서 먼저 내게되고 Intel은 뒤늦게 EM64T를 발표하게 되었죠.
이 둘을 합쳐서 x86-64라고하고 x64로 줄여서 부릅니다.
AMD64와 EM64T는 구현에 조금 불명확한 몇가지 차이점이 있지만 x64용 윈도우는 어느곳에서나 잘 동작합니다.
AMD64는 Legacy mode를 통해 64bit에서도 32bit를 사용할 때 에뮬레이터를 하지 않고 Native로 사용 할 수 있습니다. Long mode는 64bit만 쓰는 모드라고합니다. 자세한건 영문위키:x86-64에서 보시면 됩니다.
64bit윈도우에서 wow64를 이용해 32bit 프로그램들을 실행 시킬수 있습니다.
(그냥 32bit프로그램을 실행시키면 자동으로 인식하고 wow64모드로 동작시킵니다.)
여기서 실행하는 32bit 프로그램들은 에뮬레이팅해서 동작하는것이 아닌 실제 CPU명령어셋을 이용하여 실행하기 때문에 성능상 32bit환경에서 실행하는것과 거의 똑같다고 합니다.
아무래도 64bit OS에서 실행하는 것이기 때문에 32bit 환경에서 실행하는것과 속도가 동일하진 않겠죠.
CPU에 대해서는 알아봤으니 64bit로 포팅할 때 주의사항을 알아보겠습니다.
외부환경이나 참고사항은 이쪽블로그에서 확인하시면 도움이 될것입니다.
여기서는 제가 참고한 몇가지만 적어보도록하겠습니다.
1. int의 크기는 몇byte?
보통 int의 크기는 플랫폼에따라 계속 변한다고 익히 들어왔습니다.
예전에 16bit환경이였을 때 int는 16bit였고 32bit환경이 되면서 32bit로 바꼈기 때문에 64bit가 등장하게되면 당연히 int도 64bit로 될것이라고 생각했기 때문이죠.
하지만 실제로 등장한 64bit OS들은 그렇지 않았습니다.
영문위키에서 설명 하길 "64bit데이터 모델에 따라 다르다." 라고 합니다.
그 데이터 모델은 LLP64,LP64,ILP64,SILP64가 있다고 합니다.
이게 정확히 컴파일러에서 판단하는것인지 OS에서 판단하는건지의 문제를 잘 모르겠습니다만.. (컴파일을 하게되면 sizeof()같은것들은 상수 처리가 되니 컴파일러가 아닐까 생각되지만요)
Microsoft Win64(X64/IA64)는 LLP64모델이고
대부분의 Unix(Solaris같은)와 Unix와 비슷한시스템(Linux같은)은 LP64모델이라고합니다.
그리고 ILP64는 사용되는 OS는 없지만. 하드웨어(아마 디바이스 드라이브?)에서 사용하고있는 모델인것 같습니다.
위키에보면 모델에따라 데이터 사이즈가 잘 정리되어있습니다.
(지금보니 LLP는 Long Long,Pointer만 64bit고 LP는 long,long long(Long), Pointer가 64bit, ILP는 Int,long,long long(Long),Pointer가 64등.. 이렇게 해서 정해진 이름이군요 ㄱ-;;;)
유닉스계열에선 long을 64bit로 표현하는것을 보면 Winapi사이트에서 알려준 아래 내용과는 다른 내용이군요...
long은 컴파일러에따라 32bit, 64bit가 될수 있다는 것을 알아둬야 할 것 같습니다.
여기부분은 gcc와 msvc(visual studio계열)에 따라 정의가 조금 다른것 같습니다.
저는 msvc2005를 쓰고 있으므로.. msvc2005를 기준으로 쓰겠습니다.
msvc2005 컴파일러에서 64bit로 컴파일하면 기본적으로 정의해주는 define은 _WIN32, _WIN64, _M_AMD64, _M_X64_ 입니다.
도대체 왜 _WIN32를 정의해주는지는 의문입니다;
참고로 혹시나 vs2005에서 기본적으로 셋팅되는 WIN32 predefine을 지우지 않아서 그렇지 않는가라 생각하고 계시는분! WIN32매크로는 지운 상태입니다 ㅎㅎ
추가로 windows.h를 include하게되면 WIN32매크로까지 정의해버리죠. windef.h파일의 위쪽쯤에보면 아래와 같은 정의가 있습니다.
(추가 : MSDN에서 확인한 결과.. _WIN32 "Defined for applications for Win32 and Win64. Always defined." 라는 문구가 있더군요 ㄷㄷ;;)
이렇게 정리하고나니.. msvc는 포인터만 64bit로 바꼈다고 생각하면 되겠군요 ㅎㅎ
참고 사이트들 : 더 많은 정보를 알고 싶으시면 방문하셔서 읽으면 많은 도움이 될 것입니다.
http://winapi.co.kr/clec/cpp1/3-3-2.htm
http://en.wikipedia.org/wiki/64-bit
http://www.filewiki.net/tc/71
http://www.gpgstudy.com/forum/viewtopic.php?p=114455
http://blog.naver.com/dynaopt?Redirect=Log&logNo=20055001791
http://www.microsoft.com/korea/msdn/msdnmag/issues/06/05/x64/
http://tong.nate.com/mahyun/49940673
http://blog.naver.com/yunoske?Redirect=Log&logNo=10029335090
저는 처음에 64bit CPU의 종류가 하나밖에 없는줄 알았습니다.
64bit용 OS에서는 64bit프로그램만 돌아가고 32bit프로그램을 돌릴려면 당연히 내부에서 에뮬레이팅을해서 돌아간다고 생각했습니다.
x64라고 부르는 놈이 64bit CPU를 말하는 이름인줄 알았죠...
하지만 64bit CPU는 두가지 종류가 있었습니다.
우선은 진짜 64bit CPU입니다. IA-64아키텍쳐를 사용합니다.
이 아키텍쳐는 Intel과 HP가 공동연구로 개발된 아키텍쳐입니다.
판매되고 있는 제품으로는 인텔의 Itanium(아이테니엄) CPU가 이에 해당됩니다. 이 CPU는 64비트 명령어셋밖에 존재하지 않기 때문에 32bit프로그램을 실행하려면 별도의 에뮬레이팅을 해야지만 실행을 할 수 있습니다.
당연히 에뮬레이팅을하면 성능이 떨어지겠구요.. IA-64용 윈도우에서는 wow64라는 플렛폼에서 에뮬레이팅해서 동작하게 된다고합니다.(실제로 해본적은 없어서 ㅠ;;)
다음은 반쪽 64bit CPU입니다. x86-64아키텍쳐를 이용하여 만들어진 CPU들입니다.
처음에 AMD에서 Intel의 64bit CPU(IA-64)들을 대항하기위해 32bit에 64bit확장을하여 32bit호환 64bit아키텍쳐를 내놓았고 그것을 AMD64ISA(AMD 64 Instructure Set Architecture)라고 명명했습니다.
Intel에서도 이미 그러한 연구들이 진행이 되고 있었지만 AMD에서 먼저 내게되고 Intel은 뒤늦게 EM64T를 발표하게 되었죠.
이 둘을 합쳐서 x86-64라고하고 x64로 줄여서 부릅니다.
AMD64와 EM64T는 구현에 조금 불명확한 몇가지 차이점이 있지만 x64용 윈도우는 어느곳에서나 잘 동작합니다.
AMD64는 Legacy mode를 통해 64bit에서도 32bit를 사용할 때 에뮬레이터를 하지 않고 Native로 사용 할 수 있습니다. Long mode는 64bit만 쓰는 모드라고합니다. 자세한건 영문위키:x86-64에서 보시면 됩니다.
64bit윈도우에서 wow64를 이용해 32bit 프로그램들을 실행 시킬수 있습니다.
(그냥 32bit프로그램을 실행시키면 자동으로 인식하고 wow64모드로 동작시킵니다.)
여기서 실행하는 32bit 프로그램들은 에뮬레이팅해서 동작하는것이 아닌 실제 CPU명령어셋을 이용하여 실행하기 때문에 성능상 32bit환경에서 실행하는것과 거의 똑같다고 합니다.
아무래도 64bit OS에서 실행하는 것이기 때문에 32bit 환경에서 실행하는것과 속도가 동일하진 않겠죠.
CPU에 대해서는 알아봤으니 64bit로 포팅할 때 주의사항을 알아보겠습니다.
외부환경이나 참고사항은 이쪽블로그에서 확인하시면 도움이 될것입니다.
여기서는 제가 참고한 몇가지만 적어보도록하겠습니다.
1. int의 크기는 몇byte?
보통 int의 크기는 플랫폼에따라 계속 변한다고 익히 들어왔습니다.
예전에 16bit환경이였을 때 int는 16bit였고 32bit환경이 되면서 32bit로 바꼈기 때문에 64bit가 등장하게되면 당연히 int도 64bit로 될것이라고 생각했기 때문이죠.
하지만 실제로 등장한 64bit OS들은 그렇지 않았습니다.
영문위키에서 설명 하길 "64bit데이터 모델에 따라 다르다." 라고 합니다.
그 데이터 모델은 LLP64,LP64,ILP64,SILP64가 있다고 합니다.
이게 정확히 컴파일러에서 판단하는것인지 OS에서 판단하는건지의 문제를 잘 모르겠습니다만.. (컴파일을 하게되면 sizeof()같은것들은 상수 처리가 되니 컴파일러가 아닐까 생각되지만요)
Microsoft Win64(X64/IA64)는 LLP64모델이고
대부분의 Unix(Solaris같은)와 Unix와 비슷한시스템(Linux같은)은 LP64모델이라고합니다.
그리고 ILP64는 사용되는 OS는 없지만. 하드웨어(아마 디바이스 드라이브?)에서 사용하고있는 모델인것 같습니다.
위키에보면 모델에따라 데이터 사이즈가 잘 정리되어있습니다.
| Data model | short | int | long | long long | pointers |
| LLP64 | 16 | 32 | 32 | 64 | 64 |
| LP64 | 16 | 32 | 64 | 64 | 64 |
| ILP64 | 16 | 64 | 64 | 64 | 64 |
| SILP64 | 64 | 64 | 64 | 64 | 64 |
(지금보니 LLP는 Long Long,Pointer만 64bit고 LP는 long,long long(Long), Pointer가 64bit, ILP는 Int,long,long long(Long),Pointer가 64등.. 이렇게 해서 정해진 이름이군요 ㄱ-;;;)
유닉스계열에선 long을 64bit로 표현하는것을 보면 Winapi사이트에서 알려준 아래 내용과는 다른 내용이군요...
long은 컴파일러에따라 32bit, 64bit가 될수 있다는 것을 알아둬야 할 것 같습니다.
Winapi사이트 인용 : 반면 long형은 그 크기가 4바이트로 고정되어 있어 어떤 플랫폼에서나 4바이트이다. int와 long이 동일한 크기를 가지는 것은 32비트 플랫폼에서 뿐이며 16비트에서는 서로 다른 타입이고 64비트에서도 달라질 것이다. 꼭 4바이트를 쓰고 싶으면 long형으로 선언하고 플랫폼의 환경에 따라 적절한 크기를 자동으로 선택하고 싶다면 int형으로 선언하면 된다.2. 매크로 정의는 무엇으로?
여기부분은 gcc와 msvc(visual studio계열)에 따라 정의가 조금 다른것 같습니다.
저는 msvc2005를 쓰고 있으므로.. msvc2005를 기준으로 쓰겠습니다.
msvc2005 컴파일러에서 64bit로 컴파일하면 기본적으로 정의해주는 define은 _WIN32, _WIN64, _M_AMD64, _M_X64_ 입니다.
도대체 왜 _WIN32를 정의해주는지는 의문입니다;
if defined(_WIN32) elif defined(_WIN64) endif이런식으로 하면 안될것입니다. 반드시 _WIN64를 맨위에다가 해줘야겠죠;;
참고로 혹시나 vs2005에서 기본적으로 셋팅되는 WIN32 predefine을 지우지 않아서 그렇지 않는가라 생각하고 계시는분! WIN32매크로는 지운 상태입니다 ㅎㅎ
추가로 windows.h를 include하게되면 WIN32매크로까지 정의해버리죠. windef.h파일의 위쪽쯤에보면 아래와 같은 정의가 있습니다.
(추가 : MSDN에서 확인한 결과.. _WIN32 "Defined for applications for Win32 and Win64. Always defined." 라는 문구가 있더군요 ㄷㄷ;;)
#ifndef WIN32 #define WIN32 #endif3. 그 외 데이터형 사이즈
| Data Type | 32bit | 64bit |
| short | 2 | 2 |
| short int | 2 | 2 |
| int | 4 | 4 |
| long int | 4 | 4 |
| __int32 | 4 | 4 |
| float | 4 | 4 |
| __int64 | 8 | 8 |
| long long | 8 | 8 |
| double | 8 | 8 |
| WORD | 2 | 2 |
| DWORD | 4 | 4 |
| DWORD_PTR | 4 | 8 |
| void* | 4 | 8 |
| WPARAM | 4 | 8 |
| LPARAM | 4 | 8 |
이렇게 정리하고나니.. msvc는 포인터만 64bit로 바꼈다고 생각하면 되겠군요 ㅎㅎ
참고 사이트들 : 더 많은 정보를 알고 싶으시면 방문하셔서 읽으면 많은 도움이 될 것입니다.
http://winapi.co.kr/clec/cpp1/3-3-2.htm
http://en.wikipedia.org/wiki/64-bit
http://www.filewiki.net/tc/71
http://www.gpgstudy.com/forum/viewtopic.php?p=114455
http://blog.naver.com/dynaopt?Redirect=Log&logNo=20055001791
http://www.microsoft.com/korea/msdn/msdnmag/issues/06/05/x64/
http://tong.nate.com/mahyun/49940673
http://blog.naver.com/yunoske?Redirect=Log&logNo=10029335090
Track this back : http://skyilover.ruree.net/soojung/trackback.php?blogid=353
Commented by
IRIS
at 09/12/18 16:35
나중에 64비트 프로그램을 만들 일이 있다면 많은 참고가 되겠네요
유익한 내용임다 근데 과연 그런 때가 올런지는.. ㄷㄷ
유익한 내용임다 근데 과연 그런 때가 올런지는.. ㄷㄷ
Commented by
치이
at 09/12/23 14:15
ㅎㅎㅎㅎ 머지않아 그런날이 오겠죠ㅋㅋ



