구조체의 packing 은 위에 말씀 하신것 처럼 구조체를 구성하고 있는 요소중 가장 큰것의 사이즈로 정의하는 걸로 알고 있습니다.
하지만 실제 이렇게 하지는 않는 듯 하더군요.
제 경험상으로 gcc 에서의 경우
32비트 인텔 시퓨 리눅스에서는 4바이트 이고,
64비트 스팍 시퓨 솔라리스에서는 4바이트 또는 8바이트였습니다.
솔라리스에서는 구조체 구성 요소가 모두 4바이트 이하일 경우는 4바이트로 정렬하고, 4바이트가 초과된 것이 있으면 8바이트로 정렬하더군요.
그리고 gcc 의 malloc 의 경우는, 아마 gcc 는 어떤 효율을 위해 8바이트 단위가 최소라고 얼핏 접한듯하네요.
위에꺼 넘 믿지 마시고, 믿거나 말거나 정도로 참고만 하세요.
정확한건, 플랫폼 아키텍쳐에 의해 alignment 사이즈가 정해지고, 컴파일러가 효율을 위해 alignment 사이즈 변경 시킨다는 것이죠.
즉, 플랫폼과 컴파일러에 의존적이라는 것입니다.
GNU malloc()이 (64-bit system 제외) 8byte로 align되어 있는 값을 리턴하는 것은, 몇가지 이유가 있습니다.
첫째, 표준에 의해, malloc()이 리턴하는 주소는, 어떤 타입의 포인터로 캐스팅되었을때, 올바르게 align되어 쓸 수 있다는 것이 보장됩니다.
둘째, 어떤 system (대부분의 RISC 시스템)에서는, int의 주소는 4byte 배수로 align되어야 하며, 동시에 double은 8byte의 배수로 align되어야 합니다.
따라서, 8의 배수로 리턴하는 것이 가장 좋다는 판단이 나옵니다.
만약 제대로 align되어 있지 않는 주소를 잘못 쓸 경우 우리는 보통 "bus error"라는 치명적인? 오류를 받게 됩니다. (시스템에 따라서 segmentation fault가 날 수도 있음)
또한 하드웨어를 직접 다룬다거나 embedded system을 꾸미는 등의 상황에서, 정확히 특정 수치의 배수로 align되어 있는 메모리가 필요하다면,
posix_memalign(3)을 쓰는 것도 좋은 방법입니다. (이런 특정 상황에서도, 이 함수가 그리 자주 쓰이는 것을 보진 못했습니다. 대부분 커널 수준에서 처리하거나, mmap(2)을 쓰기 때문입니다)
구조체의 packing 은 위에 말씀 하신것 처럼 구조체를 구성하고 있는 요소중 가장 큰것의 사이즈로 정의하는 걸로 알고 있습니다.
하지만 실제 이렇게 하지는 않는 듯 하더군요.
제 경험상으로 gcc 에서의 경우
32비트 인텔 시퓨 리눅스에서는 4바이트 이고,
64비트 스팍 시퓨 솔라리스에서는 4바이트 또는 8바이트였습니다.
솔라리스에서는 구조체 구성 요소가 모두 4바이트 이하일 경우는 4바이트로 정렬하고, 4바이트가 초과된 것이 있으면 8바이트로 정렬하더군요.
그리고 gcc 의 malloc 의 경우는, 아마 gcc 는 어떤 효율을 위해 8바이트 단위가 최소라고 얼핏 접한듯하네요.
위에꺼 넘 믿지 마시고, 믿거나 말거나 정도로 참고만 하세요.
정확한건, 플랫폼 아키텍쳐에 의해 alignment 사이즈가 정해지고, 컴파일러가 효율을 위해 alignment 사이즈 변경 시킨다는 것이죠.
즉, 플랫폼과 컴파일러에 의존적이라는 것입니다.
저두 좀 보다 보니깐
struct packing하고 malloc의 memory align 하고
나눠서 생각해야 할 것 같네요.
리눅스 gcc 기준으로
struct packing은 4byte기준이고,
malloc의 memory align은 8byte 기준이네요.
그리고 제가 위에서
Quote:
인 구조체를 4byte로 align을 하면 'double a'를 참조할때
에러가 날테고, 아마 그래서 sizeof(double)=8에 align을 하는 것 같습니다. data type들의 sizeof의 최소 공배수라고
봐야 하지 않을까 싶은데요
라고 한 얘기는 틀린것 같습니다.
double이 들어가더라도 4byte에 align되면 괜찮은거 같네요.
malloc이 도대체 왜 8byte로 align을 하는지
위에 조언해주신대로 glib매뉴얼을 좀 찾아봐야할 듯 싶습니다.
아...헷갈린다..^^;;
네 구조체 packing 과 malloc 의 단위는 별도로 생각하셔야 합니다.
그리고 정확하게는 gcc 의 malloc 라기 보다는 그냥 현재 사용하고 있는 메모리 할당자가 그렇게 하고 있다고 보시면 됩니다.
(gcc 를 사용해서 현재 사용하고 있는 것이 아닌 다른 malloc 을 가져다 사용할 수도 있으니깐요.)
인텔 시퓨에서는 메모리 정렬에 어긋나게 접근해도, 에러나지 않습니다.
정렬 단위로 접근하지 않으면 속도가 느려질 뿐니다.
인텔 시퓨는 내부적으로 알아서 핸들링을 하거든요.
(이타니엄은 default 가 off 라고 하는 듯 하네요.)
하지만, 스팍 시퓨 같은 경우는 정렬되지 않은 상태의 데이터를 접근 하면 bus error 를 냅니다.
그리고 하드웨어 적으로 메모리 정렬 단위가 4바이트 단위라면 double 때문에 구조체 내의 다른 요소들을 double 에 맞추지 않아도 상관 없습니다.
glibc 를 참고 하시는건 glibc 를 사용하지 않는 플랫폼에서는 유효하지 않는 내용이 되므로, glibc 의 내용이 모든 곳에서 적용된다고는 생각하지 마세요.
(참고로 솔라리스에서는 glibc 최근버전은 사용 못합니다.)
msdn 에 memory alignment 따른 포퍼먼스 벤치마킹한 글이 있었는데 못 찾겠군요. 좋은 글이었는데...
혹시 이 글 주소 아시는 분 주소 올려주시면 감사하겠습니다.
저두 좀 보다 보니깐
struct packing하고 malloc의 memory align 하고
나눠서 생각해야 할 것 같네요.
리눅스 gcc 기준으로
struct packing은 4byte기준이고,
malloc의 memory align은 8byte 기준이네요.
그리고 제가 위에서
Quote:
인 구조체를 4byte로 align을 하면 'double a'를 참조할때
에러가 날테고, 아마 그래서 sizeof(double)=8에 align을 하는 것 같습니다. data type들의 sizeof의 최소 공배수라고
봐야 하지 않을까 싶은데요
라고 한 얘기는 틀린것 같습니다.
double이 들어가더라도 4byte에 align되면 괜찮은거 같네요.
malloc이 도대체 왜 8byte로 align을 하는지
위에 조언해주신대로 glib매뉴얼을 좀 찾아봐야할 듯 싶습니다.
아...헷갈린다..^^;;
네 구조체 packing 과 malloc 의 단위는 별도로 생각하셔야 합니다.
그리고 정확하게는 gcc 의 malloc 라기 보다는 그냥 현재 사용하고 있는 메모리 할당자가 그렇게 하고 있다고 보시면 됩니다.
(gcc 를 사용해서 현재 사용하고 있는 것이 아닌 다른 malloc 을 가져다 사용할 수도 있으니깐요.)
인텔 시퓨에서는 메모리 정렬에 어긋나게 접근해도, 에러나지 않습니다.
정렬 단위로 접근하지 않으면 속도가 느려질 뿐니다.
인텔 시퓨는 내부적으로 알아서 핸들링을 하거든요.
(이타니엄은 default 가 off 라고 하는 듯 하네요.)
하지만, 스팍 시퓨 같은 경우는 정렬되지 않은 상태의 데이터를 접근 하면 bus error 를 냅니다.
그리고 하드웨어 적으로 메모리 정렬 단위가 4바이트 단위라면 double 때문에 구조체 내의 다른 요소들을 double 에 맞추지 않아도 상관 없습니다.
glibc 를 참고 하시는건 glibc 를 사용하지 않는 플랫폼에서는 유효하지 않는 내용이 되므로, glibc 의 내용이 모든 곳에서 적용된다고는 생각하지 마세요.
(참고로 솔라리스에서는 glibc 최근버전은 사용 못합니다.)
msdn 에 memory alignment 따른 포퍼먼스 벤치마킹한 글이 있었는데 못 찾겠군요. 좋은 글이었는데...
혹시 이 글 주소 아시는 분 주소 올려주시면 감사하겠습니다.
Alignment: 2 * sizeof(size_t) (default)
(i.e., 8 byte alignment with 4byte size_t). This suffices for
nearly all current machines and C compilers. However, you can
define MALLOC_ALIGNMENT to be wider than this if necessary.
권위를 의심할 것,어긋남을 존경할 것,자리잡기를 거부할 것,항상 자신을 재창조할 것 - MIT 미디어랩 -
sizeof(void*) 아닐까요?
sizeof(void*) 아닐까요?
[quote="hyperhidrosis"]sizeof(void*) 아닐까
아...저두 확실히는 모르지만, 그건 아닌거 같습니다.
sizeof(void*) = 4 인데
보통 malloc align은 8byte 기준인듯 합니다.
가령
typedef struct {
double a;
int b;
long c;
} A;
인 구조체를 4byte로 align을 하면 'double a'를 참조할때
에러가 날테고, 아마 그래서 sizeof(double)=8에 align을 하는 것 같습니다. data type들의 sizeof의 최소 공배수라고
봐야 하지 않을까 싶은데요.
음 그러구 보니 비슷하게
sizeof(double)이 답일 수도 있겠네요.~~^^
권위를 의심할 것,어긋남을 존경할 것,자리잡기를 거부할 것,항상 자신을 재창조할 것 - MIT 미디어랩 -
보통 cpu기본 처리 데이터량이 int 아닌가요?sizeof(in
보통 cpu기본 처리 데이터량이 int 아닌가요?
sizeof(int) 에 한표
[quote="아싸가오리"]보통 cpu기본 처리 데이터량이 int 아닌가
sizeof(int)도 4인데
align은 8byte 기준으로 됩니당..
권위를 의심할 것,어긋남을 존경할 것,자리잡기를 거부할 것,항상 자신을 재창조할 것 - MIT 미디어랩 -
대부분의 32bit 시스템은 struct align 을 할때 4byte
대부분의 32bit 시스템은 struct align 을 할때 4byte align 을 합니다.
그리고, 예전(16bit 시절) 부터 32bit 시절 까지는
int 는 시스템에서 처리할 수 있는 제일 빠른(?) 데이타 타입이라는 규칙에 따라서
int==sizeof(void*) 이었지만
64bit 부터는 하위 호완성 이라는 미명아래 모든 규칙이 바뀌었습니다.
64bit 에서는 sizeof(void*)==8 이고, sizeof(int)==4 입니다. (대부분!)
그리고 32bit 시스템에서 struct packing 은 4byte 입니다.
(제가 아는 대부분의 시스템은)
구조체의 packing 은 위에 말씀 하신것 처럼 구조체를 구성하고 있는
구조체의 packing 은 위에 말씀 하신것 처럼 구조체를 구성하고 있는 요소중 가장 큰것의 사이즈로 정의하는 걸로 알고 있습니다.
하지만 실제 이렇게 하지는 않는 듯 하더군요.
제 경험상으로 gcc 에서의 경우
32비트 인텔 시퓨 리눅스에서는 4바이트 이고,
64비트 스팍 시퓨 솔라리스에서는 4바이트 또는 8바이트였습니다.
솔라리스에서는 구조체 구성 요소가 모두 4바이트 이하일 경우는 4바이트로 정렬하고, 4바이트가 초과된 것이 있으면 8바이트로 정렬하더군요.
그리고 gcc 의 malloc 의 경우는, 아마 gcc 는 어떤 효율을 위해 8바이트 단위가 최소라고 얼핏 접한듯하네요.
위에꺼 넘 믿지 마시고, 믿거나 말거나 정도로 참고만 하세요.
정확한건, 플랫폼 아키텍쳐에 의해 alignment 사이즈가 정해지고, 컴파일러가 효율을 위해 alignment 사이즈 변경 시킨다는 것이죠.
즉, 플랫폼과 컴파일러에 의존적이라는 것입니다.
다음은 "Writing Cross-Platform Software" 제목의 참고 자료입니다. :D
http://www.goingware.com/tips/getting-started/
http://www.goingware.com/tips/getting-started/alignment.html
glibc 매뉴얼을 참조하시기 바랍니다.디폴트가 8바이트로 되고
glibc 매뉴얼을 참조하시기 바랍니다.
디폴트가 8바이트로 되고 있는 걸로 알고 있습니다. 바꿀수도 있습니다.
Written By the Black Knight of Destruction
[code:1]#include <stdio.h>
vc 의 경우 옵션의 struct packing 을 어떻게 바꾸어도 결과값이 8, 4 가 나오는군요.. (이해가 안가는군요...)
gcc 의 경우는 어떤가요?
[quote="hyperhidrosis"]vc 의 경우 옵션의 struc
어떤 점이 이해가 안가시는지요? 패딩이 없다면 packing 옵션은 아무런 영향을
미치지 못합니다.
void main() 때문에 에러납니다. ^^;
올리신 코드를 표준에 따라 고쳐보면
저두 좀 보다 보니깐struct packing하고 malloc의 me
저두 좀 보다 보니깐
struct packing하고 malloc의 memory align 하고
나눠서 생각해야 할 것 같네요.
리눅스 gcc 기준으로
struct packing은 4byte기준이고,
malloc의 memory align은 8byte 기준이네요.
그리고 제가 위에서
라고 한 얘기는 틀린것 같습니다.
double이 들어가더라도 4byte에 align되면 괜찮은거 같네요.
malloc이 도대체 왜 8byte로 align을 하는지
위에 조언해주신대로 glib매뉴얼을 좀 찾아봐야할 듯 싶습니다.
아...헷갈린다..^^;;
권위를 의심할 것,어긋남을 존경할 것,자리잡기를 거부할 것,항상 자신을 재창조할 것 - MIT 미디어랩 -
먼저, alignment 값이 왜 필요한지 궁금합니다. 일반적으로, 이
먼저, alignment 값이 왜 필요한지 궁금합니다. 일반적으로, 이 값을 기준으로 코딩하는 것은 좋은 습관이 아닙니다.
첫째, 이런 alignment의 실제 값은 표준에서 다루지 않습니다.
둘째, GNU system에서 malloc이 리턴하는 주소는 8 byte로 align되어 있으며, 64 bit인 경우, 16 byte로 align됩니다.
세째, 일반적으로 alignment라고 하면, (malloc의 리턴 값이 아닌) structure의 alignment를 의미합니다. alignment를 얻기 위해서 다음 코드를 쓸 수 있습니다:
여기에서 DEFAULT_ALINGMENT와 DEFAULT_ROUNDING을 적절하게 쓰시면 됩니다. 자세한 것은, glibc의 obstack.[ch]의 코드를 참고하기 바랍니다.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://cinsk.github.io/cfaqs/
[quote="cinsk"]먼저, alignment 값이 왜 필요한지 궁
역시 CINSK님~~!! 감솨^^
malloc의 address align은
(align이라는 단어말고 쓸 방법이 없네요..^^;;)
어떤 연유에서 8byte를 하는지 아시면 알려주세용~^^
권위를 의심할 것,어긋남을 존경할 것,자리잡기를 거부할 것,항상 자신을 재창조할 것 - MIT 미디어랩 -
단순하게 pack단위를 알고 싶은것이라면 #pragma 사용하시면 됩니다.
#pragma pack(show)
#pragma pack(push,1)
#pragma pack(pop)
사용해보시면 될껍니다.
노력은 배반하지 않는다.
GNU malloc()이 (64-bit system 제외) 8byte로
GNU malloc()이 (64-bit system 제외) 8byte로 align되어 있는 값을 리턴하는 것은, 몇가지 이유가 있습니다.
첫째, 표준에 의해, malloc()이 리턴하는 주소는, 어떤 타입의 포인터로 캐스팅되었을때, 올바르게 align되어 쓸 수 있다는 것이 보장됩니다.
둘째, 어떤 system (대부분의 RISC 시스템)에서는, int의 주소는 4byte 배수로 align되어야 하며, 동시에 double은 8byte의 배수로 align되어야 합니다.
따라서, 8의 배수로 리턴하는 것이 가장 좋다는 판단이 나옵니다.
만약 제대로 align되어 있지 않는 주소를 잘못 쓸 경우 우리는 보통 "bus error"라는 치명적인? 오류를 받게 됩니다. (시스템에 따라서 segmentation fault가 날 수도 있음)
또한 하드웨어를 직접 다룬다거나 embedded system을 꾸미는 등의 상황에서, 정확히 특정 수치의 배수로 align되어 있는 메모리가 필요하다면,
posix_memalign(3)을 쓰는 것도 좋은 방법입니다. (이런 특정 상황에서도, 이 함수가 그리 자주 쓰이는 것을 보진 못했습니다. 대부분 커널 수준에서 처리하거나, mmap(2)을 쓰기 때문입니다)
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://cinsk.github.io/cfaqs/
[quote="cinsk"]둘째, 어떤 system (대부분의 RIS
저두 CINSK 님이 말씀하신 것처럼 생각을 해서
처음에 그런 의견을 제시 했었는데,
아래 소스 코드로 테스트를 해보니 괜찮아서
그게 또 아닌가 보다 싶어서
제 의견이 틀리다고 다시 답변을 달았거든요.
아래 소스 결과는 이렇게 나오구요.
sizeof = 12
12
죽거나 버스에러가 생기지 않습니다.
죽 ptS[1]은 8byte align이 되지 않았는데,
참조하는데 문제가 없네요.
저두 문제가 생겨야 할 것 같았는데 헷갈리네요.
이런 문제 같은경우 struct padding이랑
malloc의 addr align 문제랑
복합적인 문제라고 볼 수 있을텐데 함 봐주세요.~
권위를 의심할 것,어긋남을 존경할 것,자리잡기를 거부할 것,항상 자신을 재창조할 것 - MIT 미디어랩 -
Re: 단순하게 pack단위를 알고 싶은것이라면 #pragma 사용하시면 됩니다.
좋은 정보 감솨~~^^
C가 알면 알수록 모르는게 많이 나오네요. ^^
권위를 의심할 것,어긋남을 존경할 것,자리잡기를 거부할 것,항상 자신을 재창조할 것 - MIT 미디어랩 -
[quote="ssehoony"]구조체의 packing 은 위에 말씀 하
저도 해보니 리눅스는 4byte에 솔라리스,hp는
구조체 안의 가장 큰 sizeof를 가진 type을 기준으로
struct padding을 하네요.
위의 예제 프로그램이 리눅스에서는 12였는데
솔라리스,hp는 16입니다.
그럼 double 처리하는 구조가 OS 마다 어떻게 다른거 같네요.
리눅스에서 double의 size에 align이 안되어도
처리를 하는걸 보니...
후니님이 알려주신 사이트 읽어보니 약간 감이 오네요..^^
권위를 의심할 것,어긋남을 존경할 것,자리잡기를 거부할 것,항상 자신을 재창조할 것 - MIT 미디어랩 -
[quote="spacelee"]저두 좀 보다 보니깐struct pa
네 구조체 packing 과 malloc 의 단위는 별도로 생각하셔야 합니다.
그리고 정확하게는 gcc 의 malloc 라기 보다는 그냥 현재 사용하고 있는 메모리 할당자가 그렇게 하고 있다고 보시면 됩니다.
(gcc 를 사용해서 현재 사용하고 있는 것이 아닌 다른 malloc 을 가져다 사용할 수도 있으니깐요.)
인텔 시퓨에서는 메모리 정렬에 어긋나게 접근해도, 에러나지 않습니다.
정렬 단위로 접근하지 않으면 속도가 느려질 뿐니다.
인텔 시퓨는 내부적으로 알아서 핸들링을 하거든요.
(이타니엄은 default 가 off 라고 하는 듯 하네요.)
하지만, 스팍 시퓨 같은 경우는 정렬되지 않은 상태의 데이터를 접근 하면 bus error 를 냅니다.
그리고 하드웨어 적으로 메모리 정렬 단위가 4바이트 단위라면 double 때문에 구조체 내의 다른 요소들을 double 에 맞추지 않아도 상관 없습니다.
glibc 를 참고 하시는건 glibc 를 사용하지 않는 플랫폼에서는 유효하지 않는 내용이 되므로, glibc 의 내용이 모든 곳에서 적용된다고는 생각하지 마세요.
(참고로 솔라리스에서는 glibc 최근버전은 사용 못합니다.)
msdn 에 memory alignment 따른 포퍼먼스 벤치마킹한 글이 있었는데 못 찾겠군요. 좋은 글이었는데...
혹시 이 글 주소 아시는 분 주소 올려주시면 감사하겠습니다.
다른 참고할 만한 자료
메모리 관리 - 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
[quote="ssehoony"][quote="spacelee"]저두 좀
흐.. 좋은 정보 감사합니다.^^
권위를 의심할 것,어긋남을 존경할 것,자리잡기를 거부할 것,항상 자신을 재창조할 것 - MIT 미디어랩 -
glibc 소스의 malloc.c를 보다가 찾은 내용입니다. [c
glibc 소스의 malloc.c를 보다가 찾은 내용입니다.
권위를 의심할 것,어긋남을 존경할 것,자리잡기를 거부할 것,항상 자신을 재창조할 것 - MIT 미디어랩 -
Re: 단순하게 pack단위를 알고 싶은것이라면 #pragma 사용하시면 됩니다.
#pragma 를 믿지 마세요. Visual C++ 용일 겁니다. #pragma pack 은요.
표준 #pragma 는 #pragma STDC ... 뿐입니다. 이만 :oink:
Real programmers /* don't */ comment their code.
If it was hard to write, it should be /* hard to */ read.
댓글 달기