1. 1부
프로그래밍 기법들
1.2 템플릿 메타프로그래밍을 이용한 빠른 수학 연산
Page 59 ~ 77
NHN NEXT, NEXON 라태웅
2. 서론
C++ 프로그래머라면 템플릿이라는 말에서 STL, 범용 컨테이너 등을 떠올릴 것
템플릿은 속도와 크기 모두에서 대단히 최적화된 코드를 만들어 내는 하나의 가
상 컴파일러가 될 수 있음
Todd Veldhuidzen과 David Vandevoorde가 어떠한 알고리즘도 템플릿화 될 수 있
음을 보임
이 챕터에서는 몇 가지 예제로 템플릿의 새로운 활용 방법에 대해 알아볼 것
3. 피보나치 수열 - 정의
피보나치 수열 : 0, 1, 1, 2, 3, 5, 8, 13, … 형태의 수열
일반화된 공식 : Fib(n) = Fib(n-1) + Fib(n-2)
7. 피보나치 수열 – 주의할 점
템플릿 함수는 실제 함수가 아님. Val이라는 열거형 정수일 뿐
struct으로 정의한 것은 표기를 단수화하기 위한 것일 뿐
템플릿 인자 N은 함수의 입력을 지정하는 용도로 쓰임.
재귀 순환을 종료하기 위한 상태를 처리해야 함. (피보나치 수열의 경우 N이 0이
나 1일 때 종료됨)
14. 계승(Factorial) - 템플릿화
피보나치 예제와 마찬가지로 FactT(4)는 상수 24가 됨
즉, n에 비례하는 수행 시간이 런타임에서는 상수적인 수행 시간(O(1))으로 줄어
드는 것
15. 계승(Factorial) - 단점
가독성
FactT(n)과 같은 잘 정의된 매크로를 사용하면 해결
컴파일 시간
감수할 수 있음 (한 번만 컴파일하니까?)
피보나치 수열이나 계승이 필요한 게임은 많지 않음
필요로 하더라도 컴파일 시점에서 결정할 수 있는 경우는 드뭄
게임에서 거의 필수적으로 쓰이는 삼각함수를 템플릿화 해보자
16. 삼각함수
템플릿 기법이 실제로 쓸모 있는 것임을 보여주는 예가 될 것
많은 게임들이 sine 값 테이블이나 비슷한 방식을 이용해서 계산 속도를 높이는
기법을 사용함
만약 컴파일러가 sine(1.234) 같은 코드를 읽고 이로부터 단 하나의 move 명령을
생성해낼 수 있다면?
즉, sine(1.234)가 상수로 치환된다면? -> 수행 속도 매우 빨라질 것
17. 삼각함수
sine(x)은 으로 계산됨
위의 식에서 x는 라디안 값이고 0 <= x < 2pie 임
이를 재귀적으로 표현하면,
21. 삼각함수 – 템플릿화
!!?? 왜 안돼는거야!? 하고 찾아봤더니…
즉, float, double 같은 부동소수점은 사용할 수 없다!!
22. 삼각함수 – 템플릿화
하지만 이대로 포기할 수 없음
정수 계산을 하고 부동소수점으로 변환하도록 해보자.
23. 삼각함수 –
템플릿화
1.234의 경우 1234와 1000을 넣음
단점
매번 R/D를 수행해야함
개선
정수로 계산을 하고 return을
할 때만 D로 나눠주는 방식으로
개선할 수 있음
24. 결론
책에서는 템플릿 메타프로그래밍이 런타임에서 계산하는 것보다 느릴 때도 있
지만 결론은 짱짱맨
컴파일러마다 템플릿 처리 방식이 약간 다르고 재귀적인 호출 회수를 컴파일 중
에 제한하는 경우도 있음
아무튼 템플릿 짱짱맨
25. 발표자 결론
그러나 삼각함수의 예처럼 2000년도에는 되던 방법이 2014년에는 안되는 경우
가 많음…
분명 제대로 공부하고 알고 사용하면 유용할 것 같음
차라리 미리 계산해두고 상수 값으로 쓰면 컴파일 시간도 아끼고 런타임 시간도
아낄 수 있을텐데 굳이 템플릿 메타프로그래밍으로 해야할 필요가 있나?
26. 발표를 마치며…
템플릿 메타프로그래밍에 깊이가 없다보니 이게 현업에서 큰 도움이 될지는 잘
모르겠음
코드 가독성이 떨어지고 컴파일 시간이 늘어나고 상수 값만 넣을 수 있으니 동적
으로 무언가 계산할 수도 없고 불편한 점이 더 많아보임
정말 이걸 쓸 날이 올까..?
27. ‘ GPG를 공부하자’ 페이스북 페이지
https://www.facebook.com/gpgstudygogo