while(1)이랑 while(2)중 어 느게 더 빠르나요?

발생하는 문제 및 실행환경

면접에서 while(1)이랑 while(2)중 어느 게 더 빠를 것 같냐고 물어봐서 저는 (1)이던 (2)던 똑같이 true니까 둘이 같은 속도일 것 같다고 대답했는데 while(1)이 더 빠르다고 합니다. 왜죠?

소스코드

while(1) {
    //어떤 코드
}
or

while(2) {
    //어떤 코드
}

1답변

  • 좋아요

    0

    싫어요
    채택취소하기

    두 개의 코드가 실제로 어떻게 실행되는지 보려면, 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)등은 컴파일하면 전부 같은 어셈블리 코드가 되기 때문에 수행 속도에 차이가 없습니다.

ᕕ( ᐛ )ᕗ
로그인이 필요합니다

작성한 답변에 다른 개발자들이 댓글을 작성하거나 댓글에 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.