본문 바로가기

무언가 만들기 위한 지식/C,C++,Embedded C

[ALL] if문과 Switch문, 참조테이블에 대한 고찰


예전에 다니던 어떤 교육원에서 if문과 switch문 중에서 어떤 것이 임베디드에서 더 효율적인가에 대해 얼핏들은 기억이 있었다. 그래서 그 원인을 생각해본 적이 있었는데, 혼자서는 딱히 답이 나오지 않았다.
switch문도 어차피 내부적으로 연속된 if문이라고 생각한 적도 있었다. (물론 완전 오산) 그런 생각으로 시간이 흐르다가 요즘 보는 책에서 그 답을 찾을 수 있었다.


임베디드 프로그래밍 C코드 최적화
카테고리 컴퓨터/IT
지은이 김유진 (한빛미디어, 2008년)
상세보기


물론 일반 데스크탑이나, 좋은 환경에서
중첩된 if문과 switch문, 참조테이블은 속도면에서 별의미가 없겠지만, (그래도 개념상이나 실제로 빠른 순서가 있다.)
Embedded 환경에서는 이러한 것들이 민감하게 작용한다.

답을 먼저 제공하자면,
가장 빠른 것은 참조 테이블, Switch문, 중첩 IF문 순서이다.
이중 책에서 언급하는 내용중 Switch문의 경우 컴파일러에 따라 내부적으로 다른 방식으로 처리된다고 가정한다.
그 첫번째는, 처음 Switch문에서 한번의 연산 비교 수행후 바로 해당 Lable로 분기하는 경우
두번째는, 한번의 연산비교후, 해당 Lable이 아니면 다른 Lable에서 비교하여, 최악의 경우 가장 하단에 존재하는 default까지 가는 경우이다.

첫번째의 경우 Switch문은 참조테이블과 같이 가장 빠른 속도이고 두번째 경우는 if문보다는 빠르나 참조테이블보다는 느리다.

if문은 C언어의 기본적인 분기분이다. 중첩으로 if문을 사용하게 되면
if(condition){
//TODO
}
else if(condition){
//TODO
}
else if(condition){
//TODO
}
.
.
.

의 식으로 반복된다.
이를 디어셈블러하여 확인해보거나, 문법적으로 생각해보면,
각 경우마다 conditoion 조건 비교를 일일이 모두 하고, 분기가 여러 번 일어 난다.
분기가 여러번 일어나면 성능 즉 속도가 느려진다는 사실은 모두 알 것이다.

Switch문의 경우,
switch(temp){
case 0 :
//TODO
break;
case 1 :
//TODO
.
.
default :
//TODO
break;
}

로 이루어져 있다. 여기서 대부분의 컴파일러는 temp값과 case의 정수 값을 여러번 비교하고, 해당 루틴으로 한번 점프하는 구조가 된다. 즉 여러번의 비교와 한번의 분기 이다. (계속 언급했지만 컴파일러마다 다르다고 한다.)
이러한 CASE문은 embedded 쪽에서 고정적인 문제점이 있는데 이를 바로 부하불균형(load unbalancing)문제라고 한다.
예를 들면,
마우스 인식 드라이버가 있다. 소스내 switch문에는 들어온 값에 따라 해당 업체의 Driver가 있는 곳으로 분기하여 처리를 하는 루틴이 있다. 이경우 소스가 Switch문 내부의 상단에 있으면 빠른 처리가 되고, 가장 하단에 있으면 그 차이 많큼 시간이 더디게 늦게 인식되게 된다. 이러한 문제점은 은근히 제조사에 따라 큰 영향을 끼치게 되고, 이러한 문제점은 소프트웨어적으로 간단히 해결이 가능한데, 그것이 바로 참조테이블(lookUp Table)이다.

이러한 참조 테이블은 마치 자료구조중에서 해쉬코드나 Dictionary와 비슷하다. 배열을 이용해서 바로 해당 함수를 실행하는 것이다. 필자가 본 실제 디바이스가 정열된 배열이나, 기타 빠른속도로 여러 목록중에서 함수를 가져다 써야 할 경우 자주 쓰인다.
이 참조테이블은 한번의 비교(배열 인덱스 계산)와 한번의 분기(해당 인덱스 포인터값으로 이동)만이 이뤄지기 때문에 가장 빠르다. - 코드도 가장 간결해 메모리 사용에도 좋다.
(그런데 막상 사용할려면 가장 복잡한 개념이 된다. 확실히 알고 사용해야 한다.
필자는 예전 SystemCall 구현시 공부해서 사용했었다.)



뭐 그렇다고 모든 분기문을 참조테이블만을 사용할 수는 없는 노릇이고, 각자의 경우에 맞게 사용해야 한다.
(짧고 간단한 것은 if, 조밀도가 높은 경우들은 swtich, 속도가 중요하고 해당 경우수가 많은 경우는 참조테이블...=>이런식으로)

※ 나중에 알게 된것이지만, C코드 최적화 저 책이 내가 배운 교육원의 강사님에게 배운 사람이 쓴 글이었다.
    (여차여차 해서 문제가 많은데 일단 패스)