홍카나의 공부방

[Go, C] 구조체 메모리 정렬과 패딩 본문

Programming Language/Go

[Go, C] 구조체 메모리 정렬과 패딩

홍문관카페나무 2024. 9. 6. 15:50

 

package main

import (
	"fmt"
	"unsafe"
)

type User struct {
	Age		int32
	Score	float64
}

func main() {
	user := User {32, 64.8}
	fmt.Println(unsafe.Sizeof(user))
}

 

위 코드를 살펴보자. 구조체 User를 만들고 해당 타입의 객체인 user를 생성한다. 그리고 user 객체의 size를 출력하는 코드다. 언뜻봐서는 Int32는 Go언어에서 4바이트 크기를 가지고 있고, float64는 8바이트 크기를 가지고 있는 자료형인데 출력은 16바이트로 출력이 된다. 왜 12바이트가 아니라 16바이트의 크기를 가지게 되는것일까?

 

참고로 위 구조체에 Age2라는 int32(4바이트) 크기의 필드를 하나 더 만들어도 객체의 크기는 16바이트가 된다!

C언어 코드를 예시로 들면 아래 그림과 같다.

아래 padding 구조체의 크기가 24byte다!

 

바로 메모리 정렬(memory alignment)과 패딩(Padding)때문이다. 메모리 정렬은 컴퓨터가 데이터에 효과적으로 접근하기 위해 메모리를 일정한 크기 간격으로 정렬하는 것을 의미한다. 실제 연산에 사용되는 데이터는 레지스터(register)에 저장되는데, 레지스터 크기가 4바이트인 컴퓨터를 32비트 컴퓨터, 8바이트인 컴퓨터를 64비트 컴퓨터라고 한다.

 

데이터가 레지스터 크기와 똑같은 크기로 정렬되면 더욱 효율적으로 데이터를 읽어들일 수 있게 된다. 만약 컴퓨터가 64비트 아키텍쳐라 레지스터를 8바이트 크기로 가지게 된다면, 이는 데이터가 8바이트 단위로 정렬이 되었을 때 효율적으로 데이터를 읽어들일 수 있다는 이야기다.

 

 

메모리 용량이 충분한 데스크톱 어플리케이션이라면 패딩으로 인한 메모리 낭비를 크게 고려하지 않아도 되지만, 메모리 공간이 작은 임베디드 하드웨어에 올리는 프로그램이라면 패딩을 고려하여 코드를 설계하는 것이 필요하다. 불필요한 메모리 낭비를 줄이려면 작은 크기 필드값을 구조체 앞 부분에 배치하자.

 

 

 

 

 


 

Go 코드 참조 - <Tucker의 Go언어 프로그래밍 2판>

C 코드 출처 : https://unagi-zoso.tistory.com/7

https://bumukisbest.tistory.com/18

 

반응형