네이버 블로그 2006/09/26 작성내용 옮김. http://blog.naver.com/pinocc/120029339528
Alignment error 는 Bus Error signal 에 대한 반응으로 발생한다. bus error 신호는 multi-byte 데이터가 적절한 메모리 boundary 에서 접근되지 않을 때 발생한다. 이런 플랫폼에서 integer / long 타입의 데이터들은 cpu 가 데이터를 가져오는 방식과, 해당 플랫폼의 cpu instruction set 에서 어떻게 최적화를 하냐에 따라서 특정 byte boundary 에 정렬되어야 한다. 예를 들면 4byte long 데이터는 4의 배수에 정렬된 주소에 접근해야 하고, 2byte 는 2의 배수 주소에서 접근해야 한다.
인텔 cpu 의 경우에 특별히 정렬하지 않아도 내부적으로 이러한 일을 해준다고 한다. 대신 속도는 줄어들 것이다. sparc 의 경우에는 정렬하지 않은 경우 여지없이 bus error 를 발생시킨다.
GNU 에서는 malloc의 경우에 리턴되는 주소값이 항상 8byte align 된 값이다.(즉 8의 배수이고, 64bit 의 경우에는 16의 배수라고 한다) 이는 해당 값이 8byte/4byte 중 어떤 타입으로 캐스팅 되더라도, alignment 조건을 만족시키기 때문이다.
이런 이유에서인지 구조체도 align을 하게되는데, 컴파일러가 알아서 align에 맞도록 packing 을 해주는 것으로 생각된다.
아래와 같이 선언된 구조체의 크기는 각각 얼마인지 생각해보자
1)
struct a {
char aa;
int8 bb;
}
2)
struct a {
char aa;
int16 bb;
}
3)
struct a {
char aa;
int64 bb;
}1)의 경우 2byte, 2)의 경우 4byte, 3)의 경우는 16byte 가 된다.(편의상 int8/int16/int64 라는 타입을 썼음)
사실 structure member 의 alignment 를 어떤식으로 하는지에 따라 달라질 수도 있겠지만, 일반적으로 리눅스에서는 위와 같은 크기를 가질 것이다.
즉 변수 aa 와 bb 사이에 생기는 공간은 bb 변수의 타입에 따라 달라진 다는 말이다.
어떤 컴파일러는 정확하게 해당 구조체의 크기로 결정해주는 것도 있지만, 이런 경우 그 구조체가 디스크에 기록되는 구조체일 경우에 호환여부를 잘 따져봐야 한다.
struct a {
char aa;
char bb[256];
}
위와 같은 구조체가 있는데 컴파일러가 bb 의 크기가 짝수이기 때문에 aa 사이에 빈 byte 를 하나 padding 하여 구조체 크기를 258로 나타낸다고 하자. 즉 aa 와 bb 사이에 1byte 의 공백이 있다는 소리가 된다. 이 구조체가 디스크에 기록된다면 비어있는 공간에 gabage 가 기록될 것이다. 하지만 동일한 구조체를 257 의 크기로 인식할 수 있는 컴파일러로 컴파일을 한다면, 이전에 디스크에 기록된 내용을 읽어올 때 문제가 발생할 수 있다. 이런 경우에는 컴파일러에 alignment 를 변경시켜주는 옵션이 있는지를 찾아보고, 없다면 아래와 같이 명시적으로 Padding 구조체를 넣어주어해결 하는 것이 좋다.
struct a {
char aa;
char padding;
char bb[256];
}
참고) http://kldp.org/node/61942
http://www.goingware.com/tips/getting-started/alignment.html
메모리 관리 -
http://www-128.ibm.com/developerworks/kr/library/l-memory/
A Comparison of Memory Allocators in Multiprocessors -
http://developers.sun.com/solaris/articles/multiproc/multiproc.html
'IT 기술 > 개발환경_유틸 관련 팁' 카테고리의 다른 글
[git] git checkout 에서 '--' 의 의미 (0) | 2012.11.06 |
---|---|
git rebase 시 conflict 발생 (0) | 2012.01.19 |
screen multi-user mode error: Must run suid root for multiuser support (0) | 2011.05.12 |
awk 로 substr 뽑아내기 (0) | 2011.02.09 |
patch 명령 tip (0) | 2010.10.11 |