Media Log

  1. 황후순 at 2011.12.19 09:02 [edit/del]

    틀린 내용인거 같은데... double이 많을까요? Pointer가 많을까요?
    포인터가 32비트에서 4바이트고 64비트 8바이트라서 패킹을 각각 하고 있습니다. 구조체 크기랑은 별개의 이야기지요.메모리크기는 당연히 데이터 사이즈대로 나오겠죠. 패킹과 메모리사이즈는 별개의 얘기죠.
    단편화 생기는 과정을 만들어서 프로그램이 어떻게 죽는지 확인해보시기 바랍니다.
    필자는 ms vs compiler만 확인해보신 것이 아닌지... 메모리 패킹은 운영체제가 변경됨에 따라도 얼마든지 바뀔수 있으니 무조간 8바이트라고 단정하는건 문제가 됩니다.

    Reply
    • Favicon of https://benjaminlog.tistory.com BlogIcon 김재호 at 2011.12.19 10:10 신고 [edit/del]

      패킹이랑 메모리 사이즈는 별개의 이야기가 아닙니다. 그리고 패킹은 운영체제와는 상관없는 이야기이고요.
      무조건 8바이트라고 단정한 것이 아니라 왜 기본값을 8바이트로 정했는가에 대해서 말해본거에요.

      프로그램이 어떻게 죽는지 확인해보라는 말을 조금만 더 자세히 설명해 주실수 있을까요? 무슨 이야기를 하고 싶으신건지 궁금하네요^^

  2. kim at 2014.05.08 09:10 [edit/del]

    돌아다니다 여기까지왔네용.
    .
    글 잘봤습니다.

    제가 내린 결론은 운영체제가 몇비트 머신인지.. 그리고 컴파일러가 뭐인지에 따라
    패킹바이트가 달라진다는 결론을 얻었습니당...

    맞나요 ?!

    Reply
    • Favicon of https://sunyzero.tistory.com BlogIcon sunyzero at 2014.05.12 16:29 신고 [edit/del]

      패딩은 XDR 표준과 관련이 깊습니다. 단지 컴파일러가 CPU를 효율적으로 쓰기 위해서만은 아닙니다.

      이는 CPU의 효율면에서만 정한 것이 아니라 잠재적으로 다른 머신과의 통신(심지어 호스트 내부 통신이라고 할지라도...)에 정렬 오류를 없애기 위해서 제정되었습니다.

      과거에는 희귀한 64비트 머신인 크레이을 제외하였고, 64bit는 32bit 정렬을 포함하기 때문에 RFC에서는 4Byte 정렬을 기준으로 내세우고 있습니다. 따라서 double형을 쓰지 않는다면 대개 표준에서 지정한 4Byte정렬을 사용하고 있습니다.

      RFC문서를 보시면 좀더 빠르게 이해하실 수 있습니다. 원래는 RFC1014였다고 1832로 리바이스 되었습니다. (discussion부분을 보시면 왜 4B를 표준에 사용했는지 나오고 있습니다.)
      http://tools.ietf.org/html/rfc1832

submit
  1. Favicon of http://eslife.tistory.com BlogIcon esstory at 2011.05.30 12:58 [edit/del]

    이게 너무 오랫동안 습관이 ㅎㅎ
    처음에 null 로 초기화 안한 변수를 delete 해서 많이들 죽여 봐서.. 저렇게 하는 게 당연하다고 생각했는데 결국 '괜한 짓' 이군요 ㅎ

    Reply
  2. Favicon of http://sunyzero.tistory.com BlogIcon stevenkim at 2011.07.21 00:42 [edit/del]

    정말 사람의 습관이라는 것이 무서운게, 학생때 널체크로 배웠더니...

    나중에 초급시절을 벗어나 free(NULL)이 문제가 없는 것을 알았어도, 어느 순간 보면 기계적으로 널체크 코딩을 하고 있더군요.

    Reply
  3. gcd at 2012.02.22 06:43 [edit/del]

    여담이지만, 여기에 대고
    if (p != NULL) ...
    이라고까지 써놓은 걸 보면 정말 몸이 움찔(?)하더군요.

    Reply
  4. Favicon of http://blog.daum.net/knightofelf BlogIcon shint at 2013.10.26 21:34 [edit/del]

    이것은 중요합니다... ㅠㅠ...
    if(p != NULL)
    {
    free(p);
    p = NULL;
    }

    Reply

submit

Duff's Device

2011. 4. 7. 07:47 | Programming
Duff's Device는 Tom Duff라는 사람이 1983년도에 생각해낸 switch 문장을 사용한 loop unwinding 얍삽이이다.
위키피디아에는 다음 코드가 인용되어져 있다.
send(to, from, count)
register short *to, *from;
register count;
{
    register n = (count + 7) / 8;
    switch(count % 8) {
    case 0: do{ *to = *from++;
    case 7:     *to = *from++;
    case 6:     *to = *from++;
    case 5:     *to = *from++;
    case 4:     *to = *from++;
    case 3:     *to = *from++;
    case 2:     *to = *from++;
    case 1:     *to = *from++;
            } while(--n > 0);
    }
}
얼핏보면 switch 문장안에 do while 루프가 들어있는 것이 컴파일도 되지 않을 것처럼 보이지만 신기하게도 어느 컴파일러에서나 잘 컴파일된다.

이 코드가 컴파일 가능한 이유는 C언어의 switch 문법이
switch ( expression )
{
case constant-expression :
    statement-list
    break ;

case constant-expression :
    statement-list
    break ;

...

default :
    statement-list
    break ;
}
이 아니라 단지

switch ( expression )
    statement
이기 때문이다.

switch는 if문이나 for문 처럼 바로 뒤에 단일 문장이 올 수도 있고 블록으로된 문장들이 오는 것이 가능하다. 꼭 case 레이블이 바로 뒤따르지 않아도 된다는 뜻이다.
즉, 아래와 같은 코드도 적법하다.
switch(nn % 4)
{
for(; nn > 0; nn -= 4)
    {
case 0:    *destp++ = *srcp++;
case 3:    *destp++ = *srcp++;
case 2:    *destp++ = *srcp++;
case 1:    *destp++ = *srcp++;
    }
}

다시 처음에 나왔던 Duff's Device의 switch문을 보면, 그 코드는 마치 아래와 같이 동작할 것이다. 루프의 중간부분 부터 끼어들어갈 수 있다는 것이 중요하다.
switch(count & 7)
{
case 0 : goto lbl0;
case 1 : goto lbl1;
case 2 : goto lbl2;
case 3 : goto lbl3;
case 4 : goto lbl4;
case 5 : goto lbl5;
case 6 : goto lbl6;
case 7 : goto lbl7;
}

lbl0:
    while(count > 0)
    {
        handle_one();
        count--;
lbl1:
        handle_one();
        count--;
lbl2:
        handle_one();
        count--;
lbl3:
        handle_one();
        count--;
lbl4:
        handle_one();
        count--;
lbl5:
        handle_one();
        count--;
lbl6:
        handle_one();
        count--;
lbl7:
        handle_one();
        count--;
    }

이런 코드가 보통의 루프보다 빠른 이유는 불필요한 비교문을 줄여주기 때문이다.
do {                
    *a = *b++;
} while (--count > 0);
위 코드에서 몇번이나 count가 0과 비교 되겠는가. b의 포인터 증가 연산은 몇번 일어나겠는가. 쉽다. count 번이다.
Duff's device에서는 루프를 손으로 풀어서 씀으로써 count / 8 만큼으로 테스트 횟수를 줄일 수 있게 된다. (포인터 증가 연산은 줄일수 없고 비교연산만 줄일 수 있다)
꼭 8로 나눌 필요는 없으며, 이는 적절히 조정하면 된다. Duff는 캐시 사이즈를 고려해서 8 정도로 결정한 것 같다. 루프를 많이 풀어 쓸수록 더 많은 코드가 생성이되고 함수 크기가 커지게 될 것이다.

그런데 루프를 풀어서 쓰기 위해서 왜 꼭 switch 문을 사용한 것일까.
for(int i = 0; i < 100; i =+ 8)
{
    *a = *b++;
    *a = *b++;
    *a = *b++;
    *a = *b++;
    *a = *b++;
    *a = *b++;
    *a = *b++;
    *a = *b++;
}
위처럼 루프를 풀어내는 것도 물론 가능하다. 그런데 숫자가 딱 나누어 떨어지지 않으면(위 예에서는 100 / 8) 나머지 처리를 밑에서 한번 더 해주어야 한다. Duff의 코드에서는 n을 (count + 7) / 8 로 정하고 case 구문의 숫자 위치를 적절히 배열하여 나머지 처리를 안해도 되도록 한 것이 중요한 포인트이다. 이렇게 하면 한방에 깔끔하게 처리할 수 있고 따라서 텍스트의 크기도 약간 더 작아진다. 사실 이 포인트가 C언어의 문법으로 범용적인 loop unrolling을 구현가능하게 하는 것이며 Duff's Device라고 불리는 아이디어이다.

그런데 요즘 우리가 쓰는 거의 대부분의 컴파일러들은 최적화를 위해 loop unwinding을 지원하고 있으며, 손으로 루프를 풀어서 쓴 것보다 더 효율적으로 코드를 생성해준다. 오히려 그런 손으로 풀어쓴 루프가 컴파일러의 최적화를 방해해서 더 느린 코드가 생성될 수도 있다. 보기에 안좋은 것은 말할 필요도 없다.
이것은 이미 어딘가에 사용되고 있는 Duff's Device와 같은 코드들을 보통의 코드로 변경함으로서 오히려 더 빠른 성능을 얻을 수도 있다는 뜻이고 따라서 이런 루프 풀기를 적용하려고 할 때에는 정말 도움이 될지 미리 벤치마크를 잘 해봐야 한다. 만약 벤치마크 해보는 것이 귀찮다면 루프 풀기가 아닌 보통의 코드를 사용하는 쪽으로 베팅하는 것이 심신에도 좋고 동료들과의 관계에도 이로울 것이라 확신한다.

submit

_countof 매크로

2011. 3. 15. 06:48 | Programming

submit

FIELD_OFFSET 매크로

2011. 3. 1. 08:00 | Programming

블로그 이전했습니다.

https://jeho.page/programming/2011/03/01/FIELD_OFFSET-%EB%A7%A4%ED%81%AC%EB%A1%9C.html

 

FIELD_OFFSET 매크로

typedef struct tagST { CHAR a; CHAR b; INT* c; INT64 d; INT cbName; WCHAR name[1]; } ST;

jeho.page

 

'Programming' 카테고리의 다른 글

Duff's Device  (0) 2011.04.07
_countof 매크로  (0) 2011.03.15
FIELD_OFFSET 매크로  (1) 2011.03.01
PAGED_CODE 매크로  (6) 2011.02.27
디렉터리의 읽기 전용 속성  (4) 2011.02.20
알쏭달쏭한 typedef  (9) 2011.01.04
  1. 오곡 at 2013.08.07 18:14 [edit/del]

    잘배우고 갑니다~!

    Reply

submit
  1. Favicon of http://eslife.tistory.com BlogIcon eslife at 2010.01.14 23:28 [edit/del]

    재호님 글 잘 봤습니다.
    저도 가끔씩 이용하는 방식인데.. 재호님처럼 매크로와 얍샵이 방법까지 활용할 생각은 못해 봤습니다. 좋은 방법 배우고 갑니다 ^^

    Reply
  2. Favicon of http://www.voiceportal.co.kr BlogIcon 김태정 at 2010.01.21 00:43 [edit/del]

    오호~ 오랜만에 글?? ㅎㅎ

    Reply

submit