SW사관학교 정글7기 개발일지 (09/14)

c4fiber·2023년 9월 14일
0

SW사관학교 정글7기

목록 보기
25/49

malloc의 할당단위는 왜 8byte 일까?

1. primitive data type에 의해 8byte로 정해졌다.

32bit OS 기준 데이터 타입은 여러가지가 있지만 대표적으로 char, int, long, double 등이 있다.
여기서 long long, double은 8byte 크기를 가진다.

malloc으로 메모리를 할당받을경우 8byte를 하나의 alignment(할당 단위)로 반환함으로 써 모든 데이터 타입을 담기 위해 디자인 되었다는 답변이였다.

1word = 32bit로 가정하는 이유는 현존하는 대부분의 장치가 1word=32bit 혹은 64bit이라서 그중 하나를 고른 것입니다.
그리고 8byte alignment를 사용하는 이유는 (cs:app 교과서 p.309 기준으로) 각 데이터 타입별로 memory alignment 조건이 다른데, 달라봤자 전부 1byte, 2byte, 4byte, 8byte로 주어지므로 8byte alignment를 한 memory location을 반환함으로써 모든 데이터 타입을 담을 수 있도록 하기 위함입니다. 간단히 설명드리자면 8byte align된 주소를 반환하는 것은 모든 타입을 담기 위한 충분 조건이기 때문에 그렇게 디자인 한 것입니다.
말씀하신 long unsigned int 크기가 8byte이고, alignment 조건도 8byte의 배수가 되어야 하는데, malloc을 통해 반환한 메모리 주소값이 이미 8byte 정렬되어 있으면 long unsigned int를 담을 조건을 충족시킴을 확인할 수 있습니다.

큰 도움이 되었지만 나는 데이터 할당 단위가 2WORD (WORD는 OS에 따라 32bit, 64bit)라고 생각해서 64bit에서는 16byte가 되는게 아닌가? 라는 생각이 들었다.

나는 CPU 레지스터의 크기와 관련이 있다고 생각했는데 사실은 CPU 아키텍처와 메모리 시스템에 따라 결정된다. 그래서 다다른 결론에는 다음과 같다.

2. CPU 레지스터 크기와 관련이 있다 -> (X)

현재 사용하는 CPU의 레지스터 크기는 64bit, 8byte의 크기이다. 한번의 bitwise를 통해 64bit의 데이터 연산이 가능하고 이때문에 8byte를 사용하는것이 효율적이다 라고 생각했다

만약 CPU 레지스터 크기와 관련이 있다고 가정하면 32bit 레지스터 크기 -> 8byte 정렬, 64bit 레지스터 크기 -> 16byte 정렬을 사용하게 된다.

사실 이는 틀렸다. DOUBLE WORD(WORD = 32bit or 64bit)를 사용하는게 아니라 특수한 경우 해당될 수 있어서 혼동이 왔었다. 이에 관해 얻은 지식은 SIMD와 관련이 있다.

"SIMD(Single Intruction, Multibple Data)는 여러 데이터 요소를 동시에 처리할 수 있는 명령어 들이며 데이터를 16byte로 정렬된 벡터로 처리한다" 라고 되어있다.

즉 벡터 연산과 같은 대량의 데이터를 한번에 처리하기 위한 SIMD를 사용할 때 16byte 데이터 정렬을 요구할 수 있고 이는 매우 효율적으로 처리 된다는 뜻이다.

하지만 이러한 경우는 일반적이지 않고, 16byte 데이터 정렬도 필수적으로 쓰이는 것이 아니므로 내가 원하는 답은 아니였다.

3. CPU 아키텍처와 관련이 있다.

CPU 아키텍처와 CPU 레지스터 크기는 서로 다른 개념이다.

  • CPU Architecture

    • 컴퓨터 프로세서의 설계와 동작 방식을 정의한다.
    • 명렁어 집합, 레이스터 구성, 메모리 액세스 방식 등을 다룬다.
  • CPU Register size

    • CPU 내부의 레지스터의 크기를 나타낸다. 임시로 데이터를 저장하고, 연산을 수행하는데 사용된다.

CPU architecture vs CPU Register size

CPU 아키텍처는 CPU의 전체 동작 및 구성을 결정한다
vs
CPU 레지스터 크기는 레지스터의 데이터 저장 및 처리 능력을 정의하는데 사용된다.

CPU Architecture를 레지스터 크기에 맞춰서 설계하면 register의 효율을 최고로 끌어올릴 수 있지만, 그렇다고 데이터의 byte 정렬 크기가 register 크기에 따라가는 것이 아니다. 이는 CPU architecture의 영향을 받는다.

레지스터 크기가 64bit여도 아키텍처가 32bit로 작동한다면 데이터 연산 단위는 32bit가 되는 것이다 라고 이해했다.

chat GPT의 답변을 추가한다

기본적인 데이터에 대한 정렬 규칙은 대부분의 컴퓨터 아키텍처에서 데이터 유형의 크기와 주소에 관련이 있습니다. 주요 정렬 규칙은 다음과 같습니다:
1. 바이트 정렬 (Byte Alignment): 가장 작은 데이터 단위는 1바이트(8비트)입니다. 따라서 모든 데이터 유형은 최소 1바이트로 정렬되어야 합니다. 이는 모든 데이터가 메모리에서 바이트 단위로 액세스될 수 있도록 보장합니다.
2. 워드 정렬 (Word Alignment): 많은 아키텍처에서는 워드(보통 2바이트 또는 4바이트) 크기의 데이터가 워드 경계에 정렬되어야 합니다. 예를 들어, 4바이트 워드 데이터는 4의 배수 주소에 저장되어야 합니다. 이렇게 정렬된 데이터는 성능상 이점을 제공하며, 일부 아키텍처에서는 정렬되지 않은 데이터에 액세스할 때 추가 오버헤드를 발생시킵니다.
3. 더블 워드 또는 큰 데이터 정렬: 더 큰 데이터 유형(예: 8바이트 또는 16바이트)은 더블 워드 크기의 경계에 정렬되어야 합니다. 이렇게 정렬된 데이터는 주로 벡터 연산 또는 SIMD 명령을 사용하는 연산에서 중요합니다.
기본적인 데이터 정렬 규칙은 컴퓨터 아키텍처의 특성에 따라 다를 수 있으며, 이러한 규칙을 준수하지 않으면 성능 문제나 오류가 발생할 수 있습니다. 프로그래머는 주로 컴파일러와 컴퓨터 아키텍처의 요구사항을 준수하여 데이터를 정렬하도록 코드를 작성해야 합니다. 이러한 정렬 규칙은 저수준 프로그래밍 언어에서 중요합니다.

chat gpt 답변
https://chat.openai.com/share/6c26a611-f1d3-4390-b529-1b4a10397ab8

profile
amazing idiot

0개의 댓글