while(1)이랑 while(2)중 어 느게 더 빠르나요?
조회수 4198회
발생하는 문제 및 실행환경
면접에서 while(1)
이랑 while(2)
중 어느 게 더 빠를 것 같냐고 물어봐서
저는 (1)이던 (2)던 똑같이 true
니까
둘이 같은 속도일 것 같다고 대답했는데
while(1)
이 더 빠르다고 합니다. 왜죠?
소스코드
while(1) {
//어떤 코드
}
or
while(2) {
//어떤 코드
}
1 답변
-
두 개의 코드가 실제로 어떻게 실행되는지 보려면, gcc에서 두 코드의 어셈블리를 비교해야 합니다.
int main(void) { while(1) { } return 0; } int main(void) { while(2) { } return 0; }
제가 돌려 본 결과로는 최적화옵션(-O0)유무에 상관없이 두 코드의 어셈블리는 같습니다. 그래서 두 반복문 사이에는 속도차가 없어요.
어떤 최적화에서도 (
gcc main.c -S -masm=intel
+옵션) 둘은 항상 같은 결과가 나왔습니다.-O0에서:
.file "main.c" .intel_syntax noprefix .def __main; .scl 2; .type 32; .endef .text .globl main .def main; .scl 2; .type 32; .endef .seh_proc main main: push rbp .seh_pushreg rbp mov rbp, rsp .seh_setframe rbp, 0 sub rsp, 32 .seh_stackalloc 32 .seh_endprologue call __main .L2: jmp .L2 .seh_endproc .ident "GCC: (tdm64-2) 4.8.1"
-O1에서:
.file "main.c" .intel_syntax noprefix .def __main; .scl 2; .type 32; .endef .text .globl main .def main; .scl 2; .type 32; .endef .seh_proc main main: sub rsp, 40 .seh_stackalloc 40 .seh_endprologue call __main .L2: jmp .L2 .seh_endproc .ident "GCC: (tdm64-2) 4.8.1"
-O2/-O3에서:
.file "main.c" .intel_syntax noprefix .def __main; .scl 2; .type 32; .endef .section .text.startup,"x" .p2align 4,,15 .globl main .def main; .scl 2; .type 32; .endef .seh_proc main main: sub rsp, 40 .seh_stackalloc 40 .seh_endprologue call __main .L2: jmp .L2 .seh_endproc .ident "GCC: (tdm64-2) 4.8.1"
어떤 최적화 방식을 써도 반복문은 아래와 같은 형태인게 보이시나요?
.L2: jmp .L2 .seh_endproc .ident "GCC: (tdm64-2) 4.8.1"
중요한 건 여기에서,
.L2: jmp .L2
제가 어셈블리어를 잘 하지는 못하지만, 이건 unconditional loop로 비교하는 것 없이 무조건 L2로 점프하는 입니다. 이걸 c코드로 바꾸면
L2: goto L2;
입니다.
요약해서 말하면, 반복문이 어셈블리 언어로 컴파일될 때, 반복문에 상수값이 있다면 컴파일러가 이걸 미리 처리해 버립니다.
따라서
while(1)
,while(2)
,while(1==1)
,while(3==3 && 4==4)
,while(0.1+0.2)
등은 컴파일하면 전부 같은 어셈블리 코드가 되기 때문에 수행 속도에 차이가 없습니다.
댓글 입력