오늘 중요한 컴퓨터 개념에 대해 이야기해 보겠습니다. 대부분 들어본 적이 있지만 잘 파고들지 않은 것은 바로 바이트 순서 (Endianness)입니다.

1. 개념
바이트 순서는, 다중 바이트 데이터의 메모리 배열 순서를 의미합니다. 이 설명이 다소 추상적일 수 있으므로, 그림을 사용하여 설명하면 이해하기 쉽습니다.
메모리는 한 줄의 방과 같습니다. 각 바이트는 한 개의 방입니다. 각 방에는 문제 번호(메모리 주소)가 있으며, 0번부터 시작하여 1번, 2번... 순서대로 번호가 매겨집니다.

0번 바이트의 주소는 작으며 낮은 메모리라고 합니다. 3번 바이트의 주소는 크며 높은 메모리라고 합니다.
이제 어떤 값이 abcd 이 방들에 넣어야 하는데, 각 방에 하나씩 숫자를 넣는 방법이 있습니다. 두 가지 방법이 있습니다.
첫 번째 방법은, 첫 번째a는 낮은 주소(0번지)에 배치하고, 마지막 d는 높은 주소(3번지)에 배치합니다.

와 같은 배열 방식을 " 큰 엔디안 " (big-endian, 약칭 BE)라고 합니다. 이는 큰 부분이 앞에 있는 것을 의미하며, a가 abcd의 큰 부분(가장 중요한 숫자)이기 때문입니다.
두 번째 방법은, 첫 번째 a를 높은 주소(3번지)에 배치하고, 마지막 d를 낮은 주소(0번지)에 배치하는 것입니다.

이 배열 방식을 " 작은 엔디안 " (little-endian, 약칭 LE)라고 합니다. 이는 작은 부분이 앞에 있는 것을 의미합니다.d가 앞에 있습니다.
큰 엔디안과 작은 엔디안은 바이트 순서를 합친 말입니다. 이 두 이름은 18세기 영국 소설 《가리포트 여행》에서 유래했습니다. 어떤 나라는 두 파로 나뉘어, 한 파는 계란을 큰 머리부터 먹어야 한다고 생각하며 "큰 엔디안파"라고 불렸고, 다른 파는 계란을 작은 머리부터 먹어야 한다고 생각하며 "작은 엔디안파"라고 불렸습니다. 두 파는 서로 말을 걸어도 설득하지 못하자, 마침내 싸움까지 벌였습니다.

이, 읽기 쉬움
인간에게는 다른 바이트 순서의 읽기 쉬움은 다릅니다. 대부분의 나라는 왼쪽에서 오른쪽으로 읽는 습관을 가지고 있습니다.

큰 엔디안 순서에서는 최상위 비트가 왼쪽에 있고 최하위 비트가 오른쪽에 있어 읽기 쉬운 습관과 일치합니다. 따라서 이런 나라 사람들에게는 왼쪽에서 오른쪽으로 읽는 큰 엔디안 순서가 더 읽기 쉽습니다.
하지만 현실에서는 오른쪽에서 왼쪽으로 읽는 작은 엔디안은 읽기 쉽지 않지만 더 널리 사용되며, x86과 ARM이라는 두 가지 CPU 아키텍처 모두 작은 엔디안을 사용합니다. 그 이유는 무엇일까요?
또는 다른 질문의 방식으로, 두 가지 다른 바이트 순서가 공존하는 이유는 무엇인가? 하나의 규칙만 사용하도록 통일하는 것이 더 편리하지 않을까?
그 이유는 각자의 적용 시나리오가 있기 때문이다. 특정 시나리오에서는 빅 엔디안이 유리하고, 다른 시나리오에서는 리틀 엔디안이 유리하다. 이하 순서대로 분석한다.
3. 홀짝 검사
리틀 엔디안의 가장 명확한 장점 중 하나는 홀짝 검사이다. 즉, 일의 자리를 보고 특정 숫자가 홀수인지 짝수인지 결정하는 것이다.

예를 들어123456, 빅 엔디안은 왼쪽부터 오른쪽으로 배열되므로, 컴퓨터는 마지막 자리의 일의 자리를 계속 읽어야만 짝수임을 확인할 수 있다.6.
리틀 엔디안은 오른쪽부터 왼쪽으로 배열되며, 일의 자리가 첫 번째 자리에 있다. 따라서 첫 번째 자리를 읽기만 하면 짝수임을 확인할 수 있다.
4. 부호 검사
유사한 시나리오는 부호를 확인하여 정수가 양수인지 음수인지 결정하는 것입니다.

빅 엔디안에서의 부호 비트는 왼쪽 첫 번째 자리에 있고, 리틀 엔디안에서의 부호 비트는 오른쪽 마지막 자리에 있습니다. 따라서 빅 엔디안은 첫 번째 자리만 보고 음수인지 아닌지 알 수 있으므로 유리합니다.
5. 크기 비교
다음 연산은 크기 비교입니다. 현재 세 개의 숫자가 있으며, 크기를 비교해야 합니다: 43662576, 594, 2.

위 그림은 빅 엔디안 배열이며, 왼쪽에서 오른쪽으로 배열되므로 세 개의 숫자는 오른쪽 일의 자리에 정렬됩니다. 크기를 비교할 때 컴퓨터는 모든 비트를 읽어야 하며, 일의 자리까지 읽은 후 비교해야 합니다.
리틀 엔디안으로 변경하면 아래 배열 방식이 됩니다.

리틀 엔디안은 오른쪽에서 왼쪽으로이며, 세 개의 숫자는 첫 번째 자리에 정렬됩니다. 컴퓨터는 모든 비트를 읽을 필요가 없으며, 어떤 숫자가 다음 자리를 읽지 못하면 가장 작은 숫자입니다. 예를 들어,2 이 숫자는 두 번째 자리가 없으므로 두 번째 자리를 읽을 때, 그것이 가장 작은 숫자임을 알 수 있습니다.
따라서 크기를 비교할 때, 리틀 엔디안(Little-endian)이 우위에 있습니다.
여섯 번째, 곱셈
이제 곱셈 연산을 다시 살펴보겠습니다.
곱셈은 각 자리를 순차적으로 곱하고, 각 라운드에서는 자리 올림이 필요합니다.

위 그림은 대엔디안(Big-endian)의 24165를 3841로 곱한 것입니다. 대엔디안의 곱셈은 왼쪽으로 자리 올림을 하므로, 왼쪽으로 확장되어야 합니다. 각 라운드의 결과가 나올 때까지(예시에서는 네 라운드) 기다려야 하며, 그 후에 결과를 더하고 메모리에 통일적으로 쓰는 것입니다.
만약 리틀 엔디안의 곱셈으로 변경한다면, 다음 라운드의 결과를 기다릴 필요가 없습니다. 각 라운드는 메모리에 직접 쓸 수 있습니다.

위 그림은 리틀 엔디안의 24165를 3841로 곱한 것입니다. 리틀 엔디안의 곱셈은 오른쪽으로 자리 올림을 하므로, 오른쪽으로 확장되어야 합니다. 왼쪽 경계는 변하지 않습니다. 각 라운드의 결과를 메모리에 쓰고 나면, 이동할 필요가 없으며, 나중에 변경이 필요하다면 해당 비트만 수정하면 됩니다.
따라서 리틀 엔디안의 곱셈에는 명확한 이점이 있습니다.
7. 아리스틱 정수
이전 예제의 낮은 자리부터 계산하는 특성은 아리스틱 정수에 특히 유용합니다. 아리스틱 정수는 큰 정수라고도 하며, 아무리 큰 정수도 저장할 수 있습니다.
그 내부 구현은 정수를 더 작은 단위로 나누어서, 보통 uint32(부호 없는 32비트 정수) 또는 uint64(부호 없는 64비트 정수)로 구성되어 순서대로 결합됩니다.

대엔디안인 경우, 첫 번째 u64가 이 정수의 가장 큰 부분입니다. 계산할 때 이 숫자가 변경되면 이동이 필요하며, 그 이후 모든 비트가 이동하고 변경되어야 합니다. 리틀 엔디안에서 이동이 발생하면 모든 비트가 이동할 필요가 없습니다.
리틀 엔디안의 또 다른 장점은, 바이트 단위의 연산이 일의 자리부터 시작하는 경우(예: 곱셈과 덧셈) 왼쪽에서 오른쪽으로 순서대로 하나의 u64를 계산하고, 이전 것을 계산한 후 다음 것을 읽을 수 있다는 점입니다. 대엔디안은 이렇게 할 수 없으며, 전체 숫자를 읽은 후에 연산해야 합니다.
8. 타입 변경
마지막 예는 C 언어에 캐스팅 연산이 있는데, 이는 변수의 데이터 타입을 강제로 변경할 수 있습니다. 예를 들어 32비트 정수를 강제로 16비트 정수로 변경하는 것입니다.

위 그림에서 32비트 정수0x00000001를 16비트 정수0x0001로 변경했을 때, 빅 엔디안은 앞에서 두 바이트를 잘라냅니다. 이때 이 주소를 가리키는 포인터는 두 바이트 뒤로 이동해야 합니다.
작은 엔디안은 이런 문제가 없습니다. 뒤에서 두 바이트를 잘라내고, 첫 번째 바이트의 주소는 변하지 않으므로 포인터를 이동시키지 않아도 됩니다.
9. 요약
이상으로, 빅 엔디안과 작은 엔디안의 장점은 다음과 같습니다.
비트 단위 연산이나 일의 자리부터 연산해야 하는 경우 작은 엔디안이 유리합니다. 반대로 연산이 고위 자리에만 해당하거나 데이터의 가독성이 중요한 경우 빅 엔디안이 유리합니다.
10. 참고 링크
- 엔디안성에 관하여에서 카를 스테너루드
(끝)












