계산을 위한 공간, 메모리
컴퓨터의 계산을 위해서는 어딘가에 데이터를 보관할 공간이 필요합니다.
이것이 바로 메모리이며, 흔히 주기억 장치(주로 RAM)를 의미
하게 됩니다.
현재 우리가 주로 사용하는 IA-32 구조 (Intel architecture-32, Intel 에서 디자인한 32bit 구조)의 컴퓨터 메모리는 평면 메모리 구조를 사용합니다.
- 과거 IA-16이하 모델에서는 다소 복잡한 메모리 구조를 사용했습니다.
- C/C++ 에는 과거 메모리 구조의 흔적으로 'near' 와 'far' 같은 키워드가 남아있지만 현재는 거의 사용되지 않습니다.
평면 메모리 모델 (Flat memory model)
스프레드 시트는 열 측에 A,B,C,D,E ~ 로 이어지는 번호를, 행 측에 1,2,3,4,5,6 ~로 이어지는 번호를 사용합니다. 평면 메모리 구조는 A열 하나만 사용한다고 볼 수 있습니다.
- 32bit 의 경우 2의 32승 까지, 64bit 의 경우 2의 64승 까지.
글을 읽을 때, 왼쪽에서 오른쪽으로 차근차근 읽어 나갑니다.만약 다음과 같이 생겼다면 읽을 수 없을 것입니다.
글자 한 글자가 하나의 칸이라고 생각했을때, 한 칸에는 하나의 글자가 들어가야 정상적으로 읽어낼 수 있습니다.
대한민국의 집 주소를 생각해 봅시다.
위와 같은 Qaupot로 강좌길이라는 도로가 있다고 하면,
- 1번지에는 도넛집이, 2번지에는 커피집이, 3번지에는 도시락집이 존재
- 만약 커피집에 가고자 한다면 2번지를 찾아가면 됩니다.
그러나 이 '번지 수' 는 단순히 도시구획을 지칭하는 숫자로써, 그 수 자체에 실체가 존재하지는 않습니다.
컴퓨터 메모리 구조는 이와 비슷합니다.
하나의 큰 길이 있고, 차례대로 Address (주소)가 부여됩니다.
- 이 주소를 표현할때는 주로 0x00000001 같은 16진수 표현을 사용합니다.
주소와 메모리 크기
컴퓨터의 메모리 구조는 매우 정확하게 구획이 나뉘어 있습니다.
주소가 의미하는 메모리의 크기는 모두 같은 크기를 가집니다.
즉, 모든 건물이 30평이면 30평으로 통일되어 있다는 사실입니다.
60평 건물은 어떻게 표현할 수 있을까요?
- 60평 건물은 연속된 두개의 주소를 가지게 됩니다. 즉 2개의 구역을 합해 하나의 구역으로 쓰는 것입니다.
그렇다면 45평 건물은 어떻게 표현할 수 있을까요?
- 연속된 두개의 주소를 가져 60평의 구역을 차지합니다.
- 나머지 15평은 사용하지 않고 그대로 두게 됩니다.
대다수의 CPU 는 1byte 를 하나의 주소에 매칭합니다.
만약 4byte 를 하나의 번지에 매칭하면 어떤 일이 발생할까요?
- 하나의 번지는 4byte 이므로, 메모리에 접근할때마다 최소 4byte 의 데이터를 읽어와야 합니다.
- 모든 데이터가 4byte 단위라면 이는 높은 효율을 보일 것입니다.
- 또한 1byte 단위로 주소를 매칭시키는것보다 주소를 표현하는데에 필요한 비용이 1/4로 줄어들 것입니다.
반대로, 1byte 를 기록하는데에 4byte 의 데이터는 필요 없을 것이며, 모든 데이터가 1byte 로 이루어져 있다면, 성능이 1/4로 줄어드며, 메모리 낭비라고 할 수 있습니다.
다만, 이 크기는 CPU 목적 및 설계에 따르는 것이기 때문에 어떤 크기가 좋다고는 단정할 수 없습니다.
Endian
위의 그림에서, 각 주소에 해당하는 byte 들은 각각 내용을 담고 있습니다.
- 0x000000 만을 읽는다면 이 주소에 해당하는 byte 에는 0x58이 담겨져 있으며, 의미는 0x58 이 됩니다.
- 0x000000 부터 0x000003를 블록으로 생각하여 읽는 경우, 0x58 0x37 0x00 0x00 byte 의 나열이지만, 곧 4byte 의 자료라고도 할 수 있습니다.
위와 같이 다수의 Byte 로 이루어진 데이터를 어떻게 저장하고 읽을 것인가
에 대한 문제에 대한 해답은 Big Endian
과 Little Endian
입니다.
- 하나의 통일된 방식이 존재하면 좋겠지만, CPU 에 따라서 이를 처리하는 방법이 다를 수 있습니다.
우리가 흔하게 접할 수 있는 IA-32는 Little Endian 을 사용합니다.
Big Endian
Big Endian 은 상위 바이트의 값이 메모리 상 먼저 표시
되는 방법입니다.
위와 같이 0x58 0x37 0x00 0x00와 같은 byte 나열이 있다면, 0x58370000 으로 읽습니다.
- 2자리의 16진수는 1byte 에 대응합니다. 2^8 = 256bits , 16^2 = 256bits. 따라서 위와같이 붙여 읽을 수 있습니다.
이 방법은 읽기가 편하며, 앞 자리부터 표기되므로 크기 비교가 쉽습니다.
Little Endian
Little Endian 은 하위 바이트의 값이 메모리 상 먼저 표시
되는 방법입니다.
0x58 0x37 0x00 0x00와 같은 byte 나열이 있다면, 0x00003758 으로 읽습니다.
- 0x58 0x37 0x00 0x00를 반대로 읽는것이지, 0x58370000를 반대로 읽는것은 아닙니다. 따라서 0x00007385 가 아닙니다.
이 방법은 하위 바이트가 먼저 존재 하므로, 산술연산에 보다 편리합니다.
- 1의 자리에서 100의 자리 순으로 계산하는 것이 100의 자리에서 1의자리 순으로 계산하는 것 보다 쉽습니다.