호환성을 얻을수 없다
무언가를 얻기위해선
대등한 대가가 필요하다
그게 컴퓨터 업계의 레거시의 법칙
그시절 우리들은
그것이 세계의 진실이라고 믿고있었다.
- 강철의 코딩술사 中 -
본문읽기...
처음 컴퓨터를 만나던 당시에는 컴퓨터의 과거가 컴퓨터의 현재에 어떤 식으로 영향을 미치고 있는지 전혀 몰랐었다. 오랜 시간이 지난 지금, 이제야 알게된 과거로부터의 발목잡기에 대하여 몇가지 적어보고자 한다.
우선, 언어의 다양성에 관한 설명을 위해 커리큘럼 나열을 해보자.
(2000년 기준으로) 처음 대학에 입학해서 배우는 언어는 볼랜드사의 Turbo-C 이다. 1학년 2학기, 그 다음에 배운 언어는 HP-UX 환경의 gcc였다. 2학년 1학기의 언어는 Linux의 gcc와 MS Visual C와 MFC였다. 2학년 2학기는 SUN Java와 MATLAB과 생각에도 끔찍했던 -하지만 묘한 끌림이 있었다- MASM 6이었다.
3학년 1학기는 머릿속이 뒤집어지는 양자물리와 함께 동시에 머릿속이 뒤집어져야 했던 LISP와 Fortran, Pascal, 3학년 2학기는 MIPS 머신의 OS를 만드느라 컴퓨터 언어는 배운 것이 없다. (차라리 언어를 하나 더 배우는 것이 나았다.) 4학년 이후는 한 언어를 사용하지 않는다. 때에따라 어떤 부분은 이 언어로, 어떤 부분은 저 언어로 만들어 나중에 합치고 볶고 하게 된다. 일단은 대충 그정도이다. 일반적인 코스를 밟아 이 곳 컴퓨터 공학과를 졸업한 학생은 저런 코스를 밟아가며 초삽질유닛이 되어간다.
그 다음에는, 언어의 개수를 한 번 세어보자. 저급언어부터 세어보면,
MASM
Gcc, Turbo-C, MS Visual C
Fortran, Pascal, Java, MATLAB
LISP
가 된다. 이 목록을 보며 시간과 공간에 관한 두 가지 이야기를 할 수 있다.
*
MASM이야 CPU를 구워 만들어야 하는 3학년을 위하여 준비된 과정이니 논외로 치자. 지금 와서 컴파일러도 제대로 안나오는 Fortran이나 Pascal은 왜 배워야 하는 것일까? 대답은 의외로 간단하다. "지금도 그 언어가 쓰이고 있기 때문" 이다. 특히 물리학 분야에서는 더욱. (저 두 언어는 전산물리에서 데굴데굴 굴러가면서 배우게 된다.)
오래된 프로그램들은 Fortran이나 Pascal로 작성되어 있다. 그러한 프로그램들을 C로 고쳐주는 프로그램이 있으면 좋겠지만 불행히도 그러한 프로그램은 없다. 오래된 물리학자나 컴퓨터공학자들은 여전히 Fortran을 선호한다. 20년 전의 프로그램들을 이해하기 위해서 위의 두 언어는 전혀 필요가 없어 보이는데도 배워야 한다. 단지 에전의 프로그램들이 존재하고, 아직까지도 작동하기 때문이다.
이러한 문제가 위의 경우처럼 학문적인 경우에만 머물러 있으면 문제가 크지 않을텐데, 사실은 그렇지가 않다. 1990년대 말, 수많은 기업들은 Fortran과 Pascal을 할 줄 아는 프로그래머들을 찾아 온 세계를 헤매고 다녔다. Y2K 문제를 해결해야 하는데 소스코드를 이해할 수 있는 사람들이 별로 남아있지 않기 때문이다. 이러한 이유때문에, 컴퓨터를 공학이든 과학이든 사용하려는 사람들은 결국 컴퓨터계의 라틴어인 저 두 언어를 배우게 된다. EQUIVALENCE(A,AB,AC) 의 명령어는 세 변수가 같은 변수임을 의미한다. 왜 있을까? 프로그램 입력을 위한 천공카드에 구멍을 잘못 뚫는 경우에 다시 뚫기 힘드니까 존재한다.
NASA에서는 70년대 띄운 위성들의 데이터를 해석할 수가 없어 문제가 되었다. 당시의 데이터가 어떤 컴퓨터 구조에서 어떤 형식의 데이터로 저장되어 있는지 알 수 없기 때문이다. 게다가 이제는 테이프를 읽을 리더도 구하기가 힘들다. 만약 집에 8비트 애플 컴퓨터의 '벽돌깨기' 테이프가 있다면 어디에서 재생할 수 있을까? 5.25인치 드라이브도 이젠 찾기 힘들다. 테이프를 마지막으로 사용한 것이 90년이었으니 이제 15년밖에 되지 않았다. 5.25인치는? 최근에는 3.5인치 플로피디스크 드라이브도 찾아보기 힘들다. 표준 PC 사양에서 제외되었기 때문이다.
*
다음의 문제는 위의 경우처럼 빨리 변해가는 시간 때문에 발생하는 문제가 아니라 공간적인 영역, 실존하지는 않지만 기업간에 존재하는 영역의 차이로 발생한다. 'C라고 다같은 C인가?'
18개월동안 네가지의 C를 사용했다. 프로그래머들이 모두 그렇듯이 프로그램을 하나 작성하면서 많은 모듈들을 만들게 되었다. 그 중 유용한 모듈들은 당연히 다른 프로그램을 작성할 때에도 사용한다. 처음에는 별다른 문제가 없었다. C를 바탕으로 작성한 프로그램들이니 코드가 호환된다고 생각해 왔고, 대부분의 경우 그렇게 작동을 해 왔기 때문이다.
문제는 2학년 말부터 본격적으로 터지기 시작했다. 메모리를 직접 다루는 루틴이 많아지면 많아질수록 모듈들은 충돌했다. VC가 Unix의 gcc보다 메모리 부분에서의 에러를 컴파일러 단계에서 처리해 주는 경우가 많기 때문이다. 또한 메모리 참조의 경우, 메모리 참조를 하는 포인터가 가리키는 양이 차이나는 경우도 발생했다. 또한 라이브러리 문제도 있다. Itoa와 atoi는 대부분의 프로그래머들이 알지만, itoa는 VC에만 존재하는 명령어이다. (MSDN에 보면 itoa64라든지 하는 희한한 명령어들도 존재한다.) 이런 문제는 복잡한 문제이지만 정말 간단한 예들도 있다. 특정 경우에는 For문에서 쓰이는 명령어들 중 i++를 처리하는 방법이 C마다 다르다. 결국 하나의 C 프로그램이 작동하기 위해서는 ANSI C 규격을 지켰음에도 운영체제에서 원활하게 돌기 위해서는 수정을 해야 하는 것이다.
결국 이런 일을 하게 된다.<br /> UNIX계열용 따로, VC용 따로.
위의 예는 별 것이 아니다. 회사마다 컴파일러에서 오류 처리하는 법이 다를 수도 있고, 오류를 가지고 있을 수도 있기 때문이다. 그런데 하나의 언어에서 문제가 되는 경우도 있다. 2학년 말이었다. 말림비 소스(말림비는 텔넷 BBS 서버 프로그램이다)를 새 리눅스 머신에서 컴파일하는데 동작하지 않는 것이다. 왜냐? Gcc 버전이 올랐기 때문이다.
컴파일러도 결국에는 프로그램이다. 컴파일러가 오류를 가지고 있을 가능성도 있다. 그럼 오류가 발생하면 일반적으로는 gcc처럼 저렇게 컴파일러를 수정하면 되지 않을까? 해답은 바로 위에 있다. 오류를 수정하고 라이브러리를 개선하는데에는 레거시가 문제가 된다. 이에 대한 대처는 다양하다. '죽어도 레거시 버그라도 레거시'를 주장하는 쪽이 있는가 하면, '절대완벽'을 주장하는 쪽도 있다. 그리고 지금까지는 전자가 항상 후자를 이겨왔다. 컴퓨터를 사용하는 것은 사람이니까.
소프트웨어의 레거시를 이야기했는데, 하드웨어에 비하면 소프트웨어의 레거시는 양반이다. 지금의 개인용 컴퓨터 구조는 '이름도 거룩하사 IBM PC' 가 나온 이후로 커다란 변화를 겪은 적이 없다. 초창기의 기괴했던 보드 구조들 -예를 들자면, 마더보드가 따로 존재하지 않고 CPU조차 ISA 버스에 카드 형식으로 꽂히고 컨트롤러도 카드 형식으로 연결되는- 을 제외하면, AT 구조 이후로 하드웨어 구조의 레거시는 근 20년동안 그대로 유지되어 왔다.
예가 있다. 윈도우 95가 나와 Plug and play가 가능하게 되어도 실상 장치수는 15개의 IRQ (interrupt queue) 수로 제한되었다. 왜 15개인가? 8비트 시절의 버스 구조 컨트롤러의 레거시를 위해 당시의 8비트 컨트롤러를 그대로 유지해 왔기 때문이고, 결국 x86이 올라가면서 1비트를 희생해서 똑같은 8비트 컨트롤러를 직렬연결하는 방식으로 사용했기 때문이다. 결국 ACPI 가 나와서 다중 장치들을 하나의 IRQ에 할당하는 방식을 사용하기 시작했지만 윈도우 2000이 나오기 이전에는 제대로 지원하는 운영체제조차 없었고, 결국 2002년에 와서야 APIC가 나오게 된다. IDE는 구조의 불안정성과 속도의 문제에도 불구하고 LBA의 개념과 PIO, 디스크 컨트롤러에의 DMA의 도입을 거쳐 UDMA까지 '안 망하고' 이어져온다. 성능때문일까? 농담이겠지. 모두 레거시 때문이다. CPU 아키텍처 이야기는 입만 아프니 생략.
*
Sony사의 Play Station 2가 처음 세상에 나왔을 때 내세운 장점이 두 가지였다. 하나는 DVD video 재생 지원, 나머지 하나는 PS1에의 레거시 지원이었다. PS1의 레거시를 보장하기 위하여 소니는 무리수를 두었다. PS1의 CPU를 PS2에 내장하는 방식으로 (컨트롤러 칩으로 사용한다는 명목으로) 레거시를 보장한 것이다. 결과는 성공적이었다. 전자는 가전제품으로서의 보급을, 후자는 게임기로서의 보급을 가져왔다. MS는 Visual Studio.net을 출시하면서 예전의 이상한 처리 루틴들도 그대로 (혹은 어쩔수 없이) 가져왔다. 덕분에 PS2는 동시대의 기종중 최악의 입력장치를 -10년동안 변화가 없는- 가지게 되었고, MS는 엄청나게 복잡해서 가끔 에러를 에러라 말하지 못하는 컴파일러를 가지게 되었다.
한때의 신기술이 어느순간 족쇄로 변하는 모습은 역사상 언제나 존재해왔다. 단지 지금은 그 변화의 속도가 너무 빨라서 레거시를 유지하는 것이 엄청난 장점이 되기 때문에 유지될 뿐이다. 다행인 것은, 예전에는 발전의 속도가 느렸고 발전이 압도적이었기 때문에 우리는 옆에 촛대가 달린 전구를 쓰지 않아도 되고, 마구용품이 앞에 달린 자동차를 타지 않아도 된다는 점이다.
어제도 기숙사 공용 컴의 AGP와 PCI와 ISA의 IRQ 충돌을 해결하고 온 상황에선 촛대달린 전구는 충분히 있을법한 일로 여겨진다. =_= 안타깝지만.
이 글은 다음 글의 덧글로 작성되었습니다 : http://dorm2.postech.ac.kr/~ris81ryu/tt/index.php?pl=9