
계산기 버튼 하나 뒤에 숨은 이야기
공학용 계산기에서 tan 버튼을 누르면 결과가 바로 나오잖아요. 너무 당연해서 그 안에서 무슨 일이 일어나는지 생각해 볼 일이 거의 없는데요. 1980년에 나온 인텔 8087은 PC에 붙이던 부동소수점 코프로세서예요. 코프로세서가 뭐냐면, 메인 CPU(8086/8088) 옆에 붙어서 실수 계산만 전담해 주는 보조 칩이에요. 당시 CPU는 소수점 계산을 소프트웨어로 한땀한땀 처리해야 해서 엄청 느렸거든요. 8087을 꽂으면 과학 계산이나 CAD 프로그램이 수십 배 빨라졌어요.
이번 글은 칩 역공학으로 유명한 righto.com 블로그에서 8087 다이 사진과 마이크로코드를 분석해서, 탄젠트 명령어(FPTAN)가 실제로 어떤 알고리즘으로 돌아가는지 파헤친 내용이에요. 제목에 붙은 'CORDIC 그 이상'이 핵심 포인트예요.
CORDIC이 뭐냐면
CORDIC은 곱셈기 없이 덧셈과 비트 시프트(2로 나누기)만으로 삼각함수를 계산하는 알고리즘이에요. 비유하자면 이런 느낌이에요. 어떤 각도만큼 벡터를 돌리고 싶은데 큰 각도를 한 번에 돌릴 수 없으니까, 45도, 26.57도, 14.04도처럼 점점 작아지는 '정해진 각도 조각'들을 더하거나 빼면서 목표 각도에 조금씩 다가가는 거예요. 이 조각 각도들이 tan 값이 1, 1/2, 1/4, 1/8처럼 2의 거듭제곱이 되도록 골라져 있어서, 회전할 때 필요한 곱셈이 전부 비트 시프트로 바뀌어요. 하드웨어 입장에서는 곱셈기가 필요 없으니 트랜지스터가 크게 줄어들죠. 그래서 옛날 계산기부터 지금의 FPGA, 저전력 임베디드 칩까지 오래 쓰여 왔어요.
8087은 순수 CORDIC만 쓰지 않았다
분석 결과에 따르면 8087의 탄젠트 계산은 교과서적인 CORDIC 한 방으로 끝나지 않아요. 크게 보면 몇 단계로 나뉘는데요.
- 인자 축소: 입력 각도를 작은 범위로 좁혀요. 실제로 8087의 FPTAN은 입력 범위에 제약이 있었고, 큰 각도는 먼저 줄여줘야 했어요.
- CORDIC 스타일의 반복 단계: 칩 안 ROM에 저장된 아크탄젠트 상수 테이블을 써서 각도를 조각조각 소화해요.
- 마무리 보정 단계: 반복이 끝나고 남은 아주 작은 잔여 각도는 반복을 더 돌리는 대신 다른 근사 방식으로 처리해요. 각도가 충분히 작으면 tan x가 x와 거의 같아지는 성질을 이용할 수 있거든요.
요약하면, 반복 횟수를 줄여서 속도를 얻고, 마지막을 똑똑하게 보정해서 정밀도를 지킨 하이브리드 설계라는 게 이번 분석의 핵심이에요.
업계 맥락: 지금은 어떻게 계산할까
오늘날 x86 CPU에도 FPTAN 같은 x87 명령어가 호환성 때문에 남아 있지만, 실제 C 라이브러리(glibc 등)의 tan()은 대부분 SSE/AVX 레지스터 위에서 다항식 근사와 테이블 조회를 조합한 소프트웨어로 구현돼요. 곱셈기가 싸고 빨라졌으니 굳이 CORDIC을 쓸 이유가 줄어든 거죠. 반면 곱셈기가 부담스러운 FPGA나 초저전력 MCU에서는 CORDIC이 여전히 현역이에요. 결국 '어떤 연산이 싸고 비싼가'에 따라 알고리즘 선택이 바뀐다는 교훈이 40년 넘게 그대로 유효한 셈이에요.
한국 개발자에게 주는 시사점
당장 실무에 8087을 쓸 일은 없겠지만, 이 이야기에서 얻을 게 꽤 있어요.
첫째, 수치 계산에서 공짜 점심은 없다는 감각이에요. Math.tan() 한 줄 뒤에는 범위 축소, 근사, 오차 관리가 전부 숨어 있어요. 게임 물리, 신호 처리, 금융 계산을 하다 보면 이런 오차가 쌓여서 버그처럼 보이는 경우가 생기는데, 그 원리를 알면 디버깅이 훨씬 쉬워져요.
둘째, 임베디드나 FPGA 쪽을 한다면 CORDIC은 지금도 직접 구현해 볼 가치가 충분한 알고리즘이에요. 파이썬으로 30줄 정도면 동작하는 버전을 만들어 볼 수 있어서 공부용으로도 좋아요.
셋째, 옛 하드웨어를 뜯어보는 역공학 글은 제약 조건 속에서 최적화하는 사고방식을 배우기에 정말 좋은 교재예요. 트랜지스터 몇 만 개로 IEEE 754 이전 시대의 정밀 연산을 해낸 엔지니어들의 트레이드오프를 따라가다 보면, 요즘 클라우드 비용이나 모델 추론 최적화 고민과도 묘하게 닮아 있다는 걸 느끼실 거예요.
마무리
한 줄 정리: 8087의 탄젠트는 CORDIC 반복과 똑똑한 마무리 보정을 섞은 하이브리드로, 속도와 정밀도 사이의 균형을 잡은 설계였어요.
여러분은 평소에 쓰는 수학 함수의 구현을 들여다본 적 있으신가요? 부동소수점 오차 때문에 고생했던 경험이 있다면 댓글로 공유해 주세요!
🔗 출처: Hacker News