If 문은 필요악인가요? 그리고 어떻게 작동하는 걸까요?

구글에 how if works in c 치니깐 문법 밖에 안나오네요 ㅡ.ㅡ;;

갑자기 궁금해졌습니다.
1부터 100까지 순서대로 입력된 값중
2의 배수인지 출력하는 프로그램을 짜보겠습니다.

보통:
If number %2 !=0
2의배수입니다.
Else
2의배수 아님

갑자기 생각이 번뜩 지나갑니다
만약 2로 나오는걸 이렇게 판단 하지 않고

그렇다면 이걸 더 빠르게
받은 입렫된 값 % 2 를 같은 크기에 저장
그래서 그 숫자들중 나머지가 0 인 놈만 출력

여기서 더 진보된 방법
2의 배수는 2진수인 이상
맨 오른쪽 비트가 1이 아니면 무조껀 2의 배수가 되게 됩니다

그렇다면 비트 시프트 넘기고
출력

그런데 이래도 결국엔 컴퓨터가(정확힌 자기가 판단하는지도 모르겠지만) 판단을 해서 0이면 2의배수 1이면 배수아님 이렇게 출력하는 분기문이 작성되어야 합니다.

컴퓨터 구조론에서 교수님이 if문이 제일 나쁜놈이다(if문때문에 컴퓨터의 퍼포먼스가 상당히 저하된다.
그 이유는 분기에 따른 새명령어들이 로드되고 시행되어야 하기 때문에)라고 하시기도 하셨구요.

하지만 어셈블리어도 if문은 제가 알기론
If 뭐 하면 goto 몇번지 코드 이런식으로 되어있는걸로 알고 있습니다

그렇다면 그 if문에 만약 ~~라면 에서
그 조건이 일치하면 진행한다의 분기를 컴퓨터는 어떻게 아는거고, 어떻게 구현된 걸까요?
그리고 if문이 필요없는 프로그램은 과연 가능할까요?
예를들면 분기하는 과정에서
판단 하지않고 즉 컴퓨터가 판단하지 않고 자연스레 알아서 분리되는 그런 일은 일어나지 않으려나요?

제가 구글링을 잘 못해서 그러려나요
죄다 문법에 대한 설명밖엔 없네요 ㅠㅠ

1 Like

if 는 논리적인 과정입니다.

무슨말이냐면 그 조건문이 c언어의 문법상으로 참이면 실행하고 아니면 넘어가라는 뭐 그런 의미죠.

그런데 컴파일러가 그 구문을 컴파일할때는 최대한 효율적인 코드를 생성합니다.

생각하신 것 처럼말이죠, 뭐 암튼간에요.

어셈블리 레벨로 가시면 비교를 통해 플래그를 설정하고 그걸 통해 점프하는 어셈블리 코드를 볼 수 있습니다.

마찬가지로 if문은 논리적인 개념이라 없어도 가능합니다. :smiley: 대신 다른거 쓰겠죠.

1 Like
#include <stdio.h>

int main()
{
    int n;
    scanf("%d", &n);
    if (n % 2 == 0) {
        printf("짝수입니다.");
    }
    else {
        printf("홀수입니다.");
    }
}
main:                                   # @main
        push    rax
        lea     rsi, [rsp + 4]
        mov     edi, .L.str
        xor     eax, eax
        call    scanf
        test    byte ptr [rsp + 4], 1
        jne     .LBB0_2
        mov     edi, .L.str.1
        jmp     .LBB0_3
.LBB0_2:
        mov     edi, .L.str.2
.LBB0_3:
        xor     eax, eax
        call    printf
        xor     eax, eax
        pop     rcx
        ret

.L.str:
        .asciz  "%d"

.L.str.1:
        .asciz  "\354\247\235\354\210\230\354\236\205\353\213\210\353\213\244."

.L.str.2:
        .asciz  "\355\231\200\354\210\230\354\236\205\353\213\210\353\213\244."

==============================================================================

#include <stdio.h>

int main()
{
    int n;
    scanf("%d", &n);
    if (n & 1) {
        printf("홀수입니다.");
    }
    else {
        printf("짝수입니다.");
    }
}
main:                                   # @main
        push    rax
        lea     rsi, [rsp + 4]
        mov     edi, .L.str
        xor     eax, eax
        call    scanf
        test    byte ptr [rsp + 4], 1
        jne     .LBB0_1
        mov     edi, .L.str.2
        jmp     .LBB0_3
.LBB0_1:
        mov     edi, .L.str.1
.LBB0_3:
        xor     eax, eax
        call    printf
        xor     eax, eax
        pop     rcx
        ret

.L.str:
        .asciz  "%d"

.L.str.1:
        .asciz  "\355\231\200\354\210\230\354\236\205\353\213\210\353\213\244."

.L.str.2:
        .asciz  "\354\247\235\354\210\230\354\236\205\353\213\210\353\213\244."

똑같쥬?

2 Likes

네 맞습니다 !!
컴퓨터 구조론 배울때도 jne 조건분기문이라구 하면서 어셈블리어 맛(?) 봤었거든요.
저 jne가 물리적(?) 으로 어떻게 플래그를 설정하는지 였습니다.( 이걸 설명하려면 아마 전자공학 내용으루 넘어가려나요?)

어셈블리어 오랜만에 보니깐 느낌이 새롭네요 감사합니다! 플래그였었죠…ㄷㄷ

1 Like

이제 물리적인걸 배우시려면

컴퓨터 시스템 구조를 배우신다음…
x86 아키텍처 문서를 이제 보시면… 인텔의 크고 아름다운 문서를 이제 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

1 Like

짬프 짬프

인텔 문서가 있군요 ㄷㄷ 나중에 오기 생기면 한번 도전 해봐야 겠습니다
아니면 아무것도 모르는척 교수님에게 이거 모르겠어요 슬쩍…
교수님은 짱이잖아요 알려주세요 ㅎㅎ 해보겠읍니다
ㅋㅋㅋ

문서는 어렵지 않습니다. 분량이 엄청 길뿐이죠.

x86 아키텍처의 모든게 적혀있으니 ㅎㅎㅎ

1 Like

점프점프!!
Goto문도 어셈블리 말곤 정말 필요한곳 아니면 사용하지 말라고 하더라구요…
하긴 6개월 지나면 잘짠것도 읽는데 오래걸리는데
그게 고투로 도배된다???어우…

어 생각보다 해볼만 한가보네요?? 저는 또 이해하려면 전자공학이나 여러기타분야 + 두뇌 풀가동을 해야되는줄 알았습니다

Amd 가 바짝 따라오고 있기는 한데, amd 이슈나 잔고장 사례가 많은거에 비해 인텔은 잔고장 없는거 보면 정말 cpu 맛집인거 같아요 ㄷㄷ

if문이 제일 나쁘다는 교수님의 강의 저도 한 번 들어보고 싶네요.

if나 switch등 분기문에선 어차피 파이프라인이 안먹히지 않나요? 굳이 if 뿐만 아니더라도 함수 포인터 등을 쓰더라도 비슷할 거 같아요

그래서 현대의 cpu는 분기문 예측을 통해 파이프라이닝의 성능을 향상시킵니다.
즉 어디로 점프할지 맞추는거죠

1 Like

그리고 같은 논리라면 if문때문에 파이프라이닝 실패하는것보다 디스크 io가 훨씬 느리니
디스크가 만악의 근원입니다.

아니 cpu보다 느리면 뭐든 만악의 근원 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

1 Like

파이프 라인이 아무리 분기를 예측하더라도 결국 찍는 확률 높이는 찍신일 뿐 100%는 불가능…

그때는 cpu 아키텍쳐 관해서 파이프라이닝 얘기하고 있을때 말하신거니깐 아마 cpu에만 한정해서 보면 맞는 말인거 같아요 ㅋㅋㅋ
요즘은 하드디스크도 잘 안쓰는 추세더라구요
Ssd가 무지 저렴해졌습니다 ㄷㄷ