lilo.c 를 보면서, 잠깐 이야기 되었던 것중 하나입니다. 별로 중요하지 않은 내용인데, 괜히 올리는 것 같기도 하고 그렇지만, 노섭님께 올려보겠다라는 말을 했던터라, 그냥 올려 봅니다 ^^;;
int func() {
int t = 100;
return !!t; <---(1)
//return t; <---(2)
}
void main() {
int ret = func()
if(ret) <---(3)
printf("func()n");
}
코드에서 굳이 !!를 써줄 이유가 있을까가 원인이었는데, 성노섭님께서 "if대신 bit연산이 2사이클 정도 빠릅니다"라는 말이 이해가 가지 않아, 서로 이야기 해본 결과, 다른 부분에 초점을 맞추고 이야기를 했다는것을 알았습니다. 저같은 경우엔 "그렇다면 c코드 상에서 2번인 경우가 더 빠르지 않는가?" 라는 것이였고, 노섭님은 "return 할때, if문(?: 연산자)을 사용하지 않고, bit로 직접 0,1로 바꿔주기 때문에 2사이클 정도 빠르다는 이야기였습니다." 저는 3번 쪽의 if문에서는 똑같은데, 굳이 그렇게 쓴 것이 이해가 가지 않아서였는데, 결국엔,1,0으로 바꾸는 것은 lilo config 를 위해서 flag를 써주기 비교해주기 위해서 였습니다.
objdump를 해본 결과 (1)이 들어간 경우가 명령어 코드가 2개 더 늘어나 있었는데, 실제론 더 빠르게 되는건지는 잘 모르겠습니다.
(2) return t; | (1) return !!t; |
...상략... 00000000004004f4 <func>: 4004f4: 55 push rbp 4004f5: 48 89 e5 mov rbp,rsp 4004f8: c7 45 fc 64 00 00 00 mov DWORD PTR [rbp-0x4],0x64 4004ff: 8b 45 fc mov eax,DWORD PTR [rbp-0x4] 400502: c9 leave 400503: c3 ret 0000000000400504 <main>: 400504: 55 push rbp 400505: 48 89 e5 mov rbp,rsp 400508: b8 00 00 00 00 mov eax,0x0 40050d: e8 e2 ff ff ff call 4004f4 <func> 400512: 85 c0 test eax,eax 400514: 74 0a je 400520 <main+0x1c> 400516: bf 1c 06 40 00 mov edi,0x40061c 40051b: e8 d0 fe ff ff call 4003f0 <puts@plt> 400520: b8 00 00 00 00 mov eax,0x0 400525: c9 leave 400526: c3 ret <meta http-equiv="content-type" content="text/html; charset=utf-8"> ...하략... | ...상략... 00000000004004f4 <func>: 4004f4: 55 push rbp 4004f5: 48 89 e5 mov rbp,rsp 4004f8: c7 45 fc 64 00 00 00 mov DWORD PTR [rbp-0x4],0x64 4004ff: 83 7d fc 00 cmp DWORD PTR [rbp-0x4],0x0 400503: 0f 95 c0 setne al 400506: 0f b6 c0 movzx eax,al 400509: c9 leave 40050a: c3 ret 000000000040050b <main>: 40050b: 55 push rbp 40050c: 48 89 e5 mov rbp,rsp 40050f: b8 00 00 00 00 mov eax,0x0 400514: e8 db ff ff ff call 4004f4 <func> 400519: 85 c0 test eax,eax 40051b: 74 0a je 400527 <main+0x1c> 40051d: bf 1c 06 40 00 mov edi,0x40061c 400522: e8 c9 fe ff ff call 4003f0 <puts@plt> 400527: b8 00 00 00 00 mov eax,0x0 40052c: c9 leave 40052d: c3 ret ...하략... <meta http-equiv="content-type" content="text/html; charset=utf-8"> |
그리고, 박민규님이 말씀하신,lilo 컴파일 할때의 옵션인 -s 옵션으로 컴파일해서 해봤더니, 마치 inline함수처럼 심볼이 사라지고, 코드가 직접 들어가더군요.
<style type="text/css">::-webkit-scrollbar-track-piece:vertical {background-color:#eee;-webkit-border-radius: 0px;}::-webkit-scrollbar-track-piece:horizontal {background-color:#eee;-webkit-border-radius: 5px;}::-webkit-scrollbar {width: 9px;height: 9px;}::-webkit-scrollbar-thumb{ background-color:undefined; -webkit-border-radius:6px;}::-webkit-scrollbar-thumb:hover{background-color:undefined;!important -webkit-border-radius:6px;}</style>댓글 6
-
pororo
2011.07.26 00:05
-
오시리스
2011.07.26 00:18
네 맞습니다. 옵션 비교 때문이었군요. flag함수를 통해 얻어오는거라고 기억을 하고 있던터라, 저장하는 줄 알았네요.
-
성노섭
2011.07.27 12:20
1번째 비트연산이 더 빠르다고한거.
- 수업시간에 비트연산이랑 if연산비교해서 교수님이 설명해주시던게 얼핏기억나서 그런거 같다고 말씀드린거에요 ^^
그러니까 저의 말의 촛점은 main에서 return 값을 어떻게 처리하는지는 전 신경안쓰고 말씀드린거구요
call한 function을 수행할때
return !!t <---(1)
return if(t) 0; else 1; <---(2)
이렇게 작성하는 경우는 나누어서 설명한 것입니다.
왜냐하면 전 main함수에서 return값을 어떻게 받아서 뭘하고에 초점을 맞춘게아니라
프로그램을 작성하신분은 무슨 목적이었던 그 함수의 리턴값을 0 아니면 1이 되도록 하고싶었던 것이라고 생각했거든요
그래서 저는 (2)번 경우같이 if문을 써서 작성하는거보단 !!을 작성하는것이 효율적이니까 그런것 아닐까요 라고 말씀드린겁니다 ㅎ
올려주신 main 함수까지 보고나니까 저렇게 처리면 똑같을꺼같은데 (사실은 불필요하게 !! 연산을 한번 더해야하는것 같은데) 왜 해주는것인지 ㅎㅎ
-
박민규
2011.07.27 20:16
-
조정흠
2011.07.28 12:51
이 문제는 단순하게 생각해야 할 것 같은데요?
덤프까지 봐가며 최적화에 어떤 방식이 유리한가를 따지는 것까지 간다는 것은 너무 나간 것 같아요..
속도 최적화 측면에서 단발성의 이런 코드가 주는 영향은 거의 없다고 봐도 될 것 같거든요..
중요한 건 결과적으로 ! 연산을 두번 하고 난 이후에는 결과가 정수 1 아니면 정수 0 이라는 것이죠.
그러니까 !!0 은 그대로 0 이 되지만 !!(some non-zero value) 는 1 로 값의 변경이 일어나는 것!
이 이상의 어떤 의미도 없는 것 아닌가 ... 그냥 코딩 한 사람의 스타일일 뿐인 것 아닌가... 물론 그 스타일이 세련되었다면 배울 점일 수도 있겠고.. 나름 세련되 보이긴 하는데요?
-
오시리스
2011.07.28 13:23
이 글의 시작점은 !!의 쓰임이, 굳이 논리적으로 판단하기 위해 0,1로 명시적으로 바꾸는 것이라면, 암묵적인 방식대로 처리해도 되지 않은가? 였는데, 성노섭님이 말씀하신 이야기 -속도때문에 그랬을 것이다- 라는 것이 의아함을 자아냈고, 덤프 해본 거였습니다.(성노섭님의 말을 잘못 이해한 거였지만요)
덤프뜬 내용 때문에, 뭔가 복잡스럽게 얘기하는 것 같이 보이지만, 결국 !!의 필요성이나 코딩 스타일을 논하자 함은 아니고, 단지 이렇게 되서 그런것 같다. 를 적어보고자 한거죠. 게시글의 성격이 토론이라기 보다 애매한 정리에 가까워서 그런것 같습니다. ^^;;
.
저희가 본게 lilo.c 904라인의 cfg_get_flag(cfg.c:579) 맞나요?
초보라 맞는지 모르겠지만
lba32=cfg_get_flag(...)로 리턴후
if(lba32+geom+linear>1)
등의 옵션비교 때문에 그런게 아닐까 싶습니다. 그런데 이것도 main에서 처리해줄수 있을거 같네요.
다른 이유가 있을지도 모르겠습니다...