1. 바이트 정렬이란?
데이터가 메모리에 배치될 때 해당 데이터 구조의 바이트 경계에 맞추어 정렬되는 것을 의미한다.
2. 바이트 정렬을 사용하는 이유는?
현재 MyStruct라는 구조체에 있는 데이터가 메모리에 배치된다면
어떤 과정으로 메모리에 배치되는지 확인해보자.
기본적으로 데이터가 배치될 메모리의 크기는 구조체에 있는
가장 큰 바이트의 크기로 설정된다. ->현재 long타입의 8바이트 크기가
가장 크기 때문에 8바이트 메모리가 설정된다.
1. byte(1바이트) 부분에 8바이트 메모리가 부여된다.
-> 나머지 공간은 1바이트가 채워진 7바이트
2. 이전 8바이트 메모리의 공간은 7바이트 밖에 남지 않았기 때문에
다시 long부분에 8바이트 메모리를 부여한다.
-> 나머지 공간은 모두 채워졌기에 0바이트
3. 이전 8바이트 메모리의 나머지 공간이 없기 때문에
short(2바이트) 부분에 8바이트 메모리를 부여한다.
-> 나머지 공간은 2바이트가 채워진 6바이트
4. 이전 8바이트 메모리의 나머지 공간은 6바이트가 있지만
8바이트인 long을 넣을 수 없기 때문에 다시 8바이트의 메모리를 부여한다.
그럼 최종적으로 이 구조체의 크기는 8바이트가 4번 부여된 32바이트가 된다.
그럼 1번과 3번에서 7바이트와 6바이트의 공간이 쓰레기 값이 되버린다.
그래서 구조체의 순서를 알맞게 정렬해보면
1. 8바이트 메모리 부여 - long 8바이트 적용, 나머지 공간 0
2. 8바이트 메모리 부여 - long 8바이트 적용, 나머지 공간 0
3. 8바이트 메모리 부여 - byte 1바이트 적용, 나머지 공간 7
4. 나머지 공간 7바이트 사용 - short 2바이트 적용, 나머지 공간 5
그럼 이전에는 32바이트의 공간이 사용됐지만
지금은 총 24바이트의 공간이 사용된 것을 확인할 수 있다.
이처럼 바이트가 정렬이 돼있다면 메모리 컨트롤러가 정렬된 값을 읽을 때 곧바로
레지스터에 저장할 수 있다.
하지만 정렬이 돼있지 않다면 메모리 컨트롤러가 쓰레기 값을 읽거나 프로그램이 강제종료되는
상황이 발생될 수 있다. 이로 인해 원하던 기능이 실행되지 않고 오류가 발생할 수 있는 문제점이 생긴다.
3. C#에서의 바이트 정렬 사용
C# 에서는 StructLayout이라는 바이트 정렬 기능을 제공한다.
StructLayout을 사용해 메모리 바이트를 1로 정렬하게 설정했다.
그럼 1 씩 메모리에 데이터를 저장하기 때문에 8 + 8 + 1 + 2인 19의 크기가 나온다.
그럼 여기서 무조건 메모리 바이트르 1로 설정하여 정렬하면 메모리의 낭비없이
정렬할 수 있는 것이 아닌지 의문이 생긴다.
하지만 구조체의 크기가 매우 크다면 메모리의 낭비는 없지만 작업 시간이
그만큼 매우 증가하여 오히려 비효율적인 방법이 될 수 있다.
반대로 메모리 바이트를 일정 크기 이상으로 정렬한다면 더 빠른 작업 시간의 장점을
얻을 수 있지만 메모리가 낭비된다는 단점을 얻게된다.
이처럼 상황에 알맞게 바이트를 정렬하여 사용하는 것이 올바른 바이트 정렬의 사용법이다.
'간단한 IT 지식' 카테고리의 다른 글
[오늘의 지식] 컴퓨터의 실수 표현 (0) | 2024.03.04 |
---|---|
[오늘의 지식] OOP (Object-Oriented Programming) (0) | 2024.02.29 |
[오늘의 지식] 전략 패턴 (1) | 2024.02.27 |
[오늘의 지식] IPC (Inter Process Communication) (0) | 2024.02.26 |
[오늘의 지식] Unity에서 Enum형을 받을 때 주의점 (0) | 2024.02.23 |