jacobhan.me

기술의 역사

궁핍이 벼려낸 코드 — 제약의 시대가 만든 프로그래밍 전설들

쓸 만한 도구도, 참고할 튜토리얼도 거의 없던 시절. 핵심 기능을 처음부터 직접 짜야 했던 그 열악함이 오히려 한 세대의 프로그래머를 벼려냈다. 오늘까지 회자되는 몇몇 걸작 코드의 뿌리에는 넉넉함이 아니라 결핍이 있었다.


레전드 프로그래머는 어떻게 탄생하는가. 역설적이게도, 가혹한 제약과 열악한 환경이 개발자의 실력을 달구는 용광로가 되어 준 경우가 적지 않다. 손쉽게 가져다 쓸 도구가 없고 핵심 기능마저 직접 구현해야 했기에, 그 시절 프로그래머들은 비범한 기지와 창의성을 발휘할 수밖에 없었다. 그 결과 기계어 수준까지 최적화된 코드들이 남았고, 그중 일부는 수십 년이 지난 지금도 하나의 사건으로 언급된다.

01이른바 '침실 코더'의 시대

1980년대와 1990년대 초의 풍경을 떠올려 보자. 기본적인 컴퓨터 한 대와 열의만 있으면 누구나 시작할 수 있었던, 이른바 '침실 코더(bedroom coder)'의 시대였다. 다만 진입 장벽이 낮았을 뿐, 기술 그 자체는 만만치 않은 벽이었다.

하드웨어 제약은 혹독했다. RAM(주기억장치, Random Access Memory)은 수 킬로바이트에서 많아야 수 메가바이트 단위였고, 그마저도 넉넉하게 확보하기 어려웠다. '나중에 최적화하자'는 여유는 사치였다. 즉시 최적화하지 않으면 컴퓨터가 그대로 멈춰 버렸기 때문이다. 메모리와 싸우고 처리 속도와 싸워야 했으며, 코드 한 줄 한 줄이 결과를 갈랐다.

추상화와 지원 도구도 심각하게 부족했다. 패키지 관리자도, 화면 구성용 라이브러리도, 자동화 수단도 없었다. 필요한 라이브러리는 대개 직접 만들어야 했다. 디버깅은 16진수로 찍힌 메모리 덤프를 노려보며 원인을 짚어 나가는 길고 고된 과정이었다. 튜토리얼이 사실상 없었다는 점도 컸다. 도서관에서 프로그래밍 책 한 권이라도 찾으면 운이 좋은 편이었고, 참고할 자료라고는 읽기 까다로운 매뉴얼이 전부일 때가 많았다. 프로그래머가 대화할 상대는 사실상 컴파일러뿐이었다.

이런 결핍은 오늘날 상상하기 어려운 수준의 창의성을 강요했다. 몇 바이트가 아쉬우면 화면 출력용 메모리인 VRAM(영상 메모리, Video RAM)을 데이터 저장소처럼 쓰는 편법도 흔했다. CPU(중앙처리장치, Central Processing Unit)가 한 번에 처리하는 연산 하나하나를, 가계부를 쓰듯 아꼈다. 그 제약이 개발자를 날카롭게 벼렸고, 오늘 우리가 당연하게 쓰는 여러 기본 개념을 그들이 직접 만들어 냈다.

02어셈블리어, 기계에 가장 가까운 언어

원시적인 기계에서 빠릿한 게임을 구현하려면, BASIC 같은 고수준 해석형 언어로는 대개 역부족이었다. 프로그래머는 결국 기계어, 혹은 그 바로 위 단계인 어셈블리어로 내려가야 했다.

어셈블리어는 사람이 읽기 편하다고는 말하기 어려운 저수준 언어다. 어셈블리로 코드를 쓴다는 것은 메모리 주소를 지정해 '데이터를 어디로 옮길지'를 컴퓨터에 직접 지시하는 일이다. CPU와 그 안의 임시 저장 공간인 레지스터까지 손으로 세밀하게 제어해야 한다. 사람이 비교적 읽기 쉬운 C 언어 한 줄을 어셈블리로 옮기면, 필요한 수작업 단계 때문에 네다섯 줄로 불어나는 것이 보통이다.

프로그래밍 언어의 추상화 계층 고수준 언어 · Python, C 사람의 언어에 가깝다 어셈블리어 · Z80, x86 명령과 메모리 주소를 하나하나 손으로 지정 기계어 · 0과 1 CPU가 곧바로 실행하는 코드 하드웨어 CPU · 레지스터 · 메모리 위로 갈수록 사람이 읽기 쉽고, 아래로 갈수록 기계를 정밀하게 제어한다.

언어의 계층 구조. 어셈블리어는 사람과 기계의 중간에서 하드웨어를 직접 다룬다.

비유로 이해하기

고수준 언어로 프로그래밍하는 것은 택시 기사에게 "공항으로 가 주세요"라고 목적지만 말하는 것과 같다. 세부 경로는 기사가 알아서 처리한다. 반면 어셈블리로 프로그래밍하는 것은 교차로마다 "여기서 좌회전, 3단 기어로, 2차선 유지"처럼 모든 조작을 일일이 지시하는 것과 같다. 훨씬 번거롭지만, 그만큼 경로의 모든 순간을 내 뜻대로 통제할 수 있다.

바로 이 통제력이 어셈블리의 강점이었다. 데이터를 수동으로 옮기고 제어할 수 있기에, 같은 시기 다른 언어로는 도달하기 어려운 성능을 끌어낼 수 있었다. 이 저수준 성능이 절실했던 대표적 사례가 스코틀랜드 출신 개발자 크리스 소여(Chris Sawyer)다.

03크리스 소여와 롤러코스터 타이쿤

소여는 1983년, 생소한 8비트 컴퓨터로 개발 여정을 시작했다. 인기 기종인 BBC 마이크로를 살 형편이 못 되어 대신 구입한 것이 캠퓨터스 링스(Camputers Lynx)였고, 그는 이 기계 위에서 기계어를 한 바이트씩 손으로 짜 넣으며 감을 익혔다. 이후 옮겨 간 메모텍 MTX(Memotech MTX)는 Z80 프로세서용 어셈블러를 내장하고 있어 기계어 작성이 한결 수월했다. 그는 1984~85년 무렵 이 기종용으로 열한 편가량의 게임을 만들었는데, 상당수가 당대 아케이드 게임을 본뜬 클론이었다.

1988년부터 1993년까지 그는 아미가(Amiga) 등 다른 기종의 게임을 MS-DOS(마이크로소프트 디스크 운영체제, Microsoft Disk Operating System) 기반 PC(개인용 컴퓨터, Personal Computer)로 옮기는 이식 작업으로 실력을 갈고닦았다. 우주 시뮬레이션 게임 Frontier: Elite II를 비롯한 여러 작품이 그의 손을 거쳤고, 이 방대한 이식 경험이 저수준 코드에 대한 숙련도를 끌어올렸다.

1994년 발표한 트랜스포트 타이쿤(Transport Tycoon)의 상업적 성공은 그에게 시간과 여유를 안겨 주었다. 이 수익 일부로 유럽과 미국을 여행하며 여러 놀이공원의 롤러코스터를 타 본 것이 다음 작품의 씨앗이 되었다. 원래 롤러코스터를 그리 좋아하지 않았다던 그는, 이 여행을 계기로 코스터 마니아가 되어 지금까지 700종이 넘는 코스터를 탔다고 한다.

제약의 시대가 만든 이정표 1983 Camputers Lynx 기계어 입문 1984–85 Memotech MTX 게임 11종 (Z80) 1991 토르발스, 386 PC로 리눅스 커널 착수 1994 Transport Tycoon 출시 1999 RollerCoaster Tycoon PC 판매 1위 · 99% 어셈블리

주황색은 소여의 이정표, 초록색은 토르발스의 리눅스 착수 시점.

그리고 롤러코스터 타이쿤(RollerCoaster Tycoon)에서 그의 전문성은 정점에 달했다. 1990년대 후반이면 프로그래밍 세계는 이미 대체로 C++로 옮겨 간 상태였다. 그러나 소여는 이 게임의 약 99%를 x86 어셈블리로 작성했고, 윈도우 및 그래픽 처리 규격과 맞물리는 1% 정도만 C로 처리했다. 이미 구식으로 취급되던 언어를 1990년대 말에 고수한 셈이니, 대담한 선택이었다.

왜 그랬을까. 소여 본인은 성능 때문이라고 설명한다. 당대 PC에서 고수준 언어를 썼다면 게임이 지나치게 느려지거나, 속도를 지키려고 시뮬레이션의 복잡도를 크게 줄여야 했다는 것이다. 넓고 세밀한 놀이공원 화면, 높은 프레임 속도, 수백 명에 이르는 이용객과 여러 놀이기구를 동시에 돌리는 밀도. 이 모든 것을 포기하지 않으려면 손으로 다듬은 기계어가 사실상 유일한 답이었다.

대가는 컸다. 어셈블리에는 C 같은 언어의 편의 기능도, 뜻이 담긴 변수 이름도 넉넉하지 않았기에, 소여는 게임의 전체 구조와 모든 시스템, 물리 연산, 수백 명 이용객의 렌더링까지 상당 부분을 머릿속에 그려 가며 개발해야 했다. 그러나 그 노고는 거대한 성과로 돌아왔다. 롤러코스터 타이쿤은 복잡한 관리 시스템과 자체 물리 엔진을 갖추고도, 그 시대의 빈약한 컴퓨터에서 눈에 띄는 지연 없이 매끄럽게 돌아갔다.

그래픽 담당자 한 명과 작곡가 한 명의 도움을 받았을 뿐, 사실상 한 사람이 만든 게임이었다. 그리고 이 작품은 1999년 PC 게임 판매 1위에 올랐다.

미국에서만 그해 약 72만 장이 팔렸고, 소여가 로열티로 벌어들인 금액은 3천만 달러 안팎으로 알려져 있다. 대형 팀이 투입되던 동시대 경쟁작들과 견주면, 1인 개발에 가까운 이 결과는 전례를 찾기 어려웠다. 한정된 하드웨어에서 저수준 코드의 숙련도가 커져 가는 산업 규모를 뛰어넘을 수 있음을 그는 몸소 보여 주었다.

흥미로운 후일담이 있다. 훗날 이 게임을 모바일용으로 다시 내놓기로 하면서, 개발진은 전체를 C++로 새로 써야 했다. 그런데 이 재작성에는 여러 해와 소규모 팀이 필요했고, 결과적으로 20여 년 전 소여가 혼자 기계어로 원본을 완성하는 데 걸린 시간보다 더 오래 걸렸다. 손으로 눌러 담은 그 코드에 얼마나 많은 것이 압축돼 있었는지를 보여 주는 대목이다.

04리누스 토르발스, 결핍에서 태어난 리눅스

같은 흐름을 조금 다른 결로 보여 주는 인물이 리누스 토르발스(Linus Torvalds)다. 그의 이야기에서 결정적이었던 것은 어셈블리 자체라기보다, 무엇 하나 마음껏 갖추기 어려웠던 결핍의 환경이었다.

그는 부유한 유닉스(Unix) 워크스테이션을 다루며 자란 것이 아니라, 대학 시절 겨우 마련한 386 PC 한 대와 교재 몇 권에 의지해 시스템 프로그래밍을 파고들기 시작했다. 요즘처럼 동영상 강의나 코드 예제가 쏟아지던 시절이 아니었고, 인터넷은 느렸으며 정보는 한정적이었다. 상용 유닉스는 라이선스 비용이 비싸 학생 신분으로는 직접 써 보기조차 어려웠다. 그가 실습용으로 제대로 만져 볼 수 있었던 것은 교육용 OS(운영체제, Operating System)인 미닉스(MINIX)가 거의 전부였다.

그런데 미닉스조차 라이선스와 기능 면에서 제약이 많아, 마음껏 고치고 발전시키기에는 답답한 환경이었다. 게다가 미닉스의 16비트 설계는 당시 값이 내려가며 보급되던 386 계열의 32비트 성능을 제대로 살리지 못했다. 이 답답함이 오히려 그를 달궜다. "그렇다면 내가 직접 만들어 보자"는 마음으로, 그는 취미 삼아 386의 작업 전환 기능과 터미널 드라이버 같은 밑바닥 조각부터 짜기 시작했고, 이것이 점차 하나의 커널로 자라났다.

좋은 통합 개발 도구도, 자동 완성도, 친절한 디버거도 지금 같지 않던 시절이었다. 시스템 호출 하나, 스케줄러 한 줄을 직접 짜고 직접 깨지면서 배워야 했다. 유닉스의 시스템 호출 방식은 대학 서버의 매뉴얼과 미닉스 교재를 뒤져 가며 익혔다. 전 세계 개발자들과의 협업도 메일링 리스트와 패치 파일이라는 원시적인 수단으로 하나씩 익혀 나갔다.

1991년 8월, 그는 한 뉴스그룹에 "취미로 (무료) 운영체제를 만들고 있다, 크고 대단하진 않을 것"이라는 유명한 글을 올렸다. 그해 9월 공개된 최초 버전은 코드가 약 1만 줄에 불과했다. 이듬해 그는 이 커널을 GPL(일반 공중 사용 허가서, General Public License)로 공개했고, 이 결정이 이후의 폭발적 성장을 가능케 했다. 열악한 도구와 제한된 하드웨어, 불편한 협업 환경 속에서도 꾸준히 실력을 다진 끝에, 사람들은 그를 '리눅스의 아버지'라 부르게 되었다.

한 가지 짚고 넘어가기

소여가 성능을 위해 어셈블리를 끝까지 붙든 것과 달리, 리눅스 커널의 대부분은 C로 작성되었다(밑바닥의 극히 일부만 어셈블리다). 두 사람을 잇는 공통점은 '어셈블리'라는 도구가 아니라, 살 수 없거나 고칠 수 없는 환경이 이들을 '직접 만들기'로 떠밀었다는 사실이다. 결핍이 곧 출발점이었다.

05제약이 남긴 것, 그리고 남기지 못한 것

소여와 토르발스 같은 이들은 온갖 제약과 열악한 환경을 견뎌 낸 생존자였다. 단순히 타고난 재능만으로 빛난 사람들이 아니다. 도구가 부족했고 CPU가 처리하는 연산 하나하나를 세며 최대 효율의 코드를 짜야 한다는 요구가, 오늘날 보기 드문 창의성과 최적화를 끌어냈다. 그들의 재능은 가혹한 환경을 하나의 설계적 성취로 바꿔 놓았다.

다만 이 이야기를 '제약은 언제나 이롭다'로 읽는 것은 성급하다. 여기에는 살아남은 자만 눈에 띄는 편향이 섞여 있다. 같은 결핍 속에서 수많은 프로젝트가 조용히 사라졌고, 모두가 전설이 된 것도 아니다. 반대로 오늘의 풍요로운 환경—성숙한 컴파일러, 방대한 라이브러리, 실시간으로 연결된 개발자 공동체—은 과거와는 비교할 수 없는 규모의 소프트웨어를 가능하게 했다. 소여 자신도 이제는 자기 같은 1인 어셈블리 개발자가 설 자리가 거의 없다고 인정한다.

그래서 남는 교훈은 단순한 예찬이 아니다. 필연적인 궁핍과 저수준에 대한 깊은 이해가 맞물렸을 때, 특정한 종류의 탁월함이 태어난다는 것. 롤러코스터 타이쿤이 '거의 전부를 어셈블리로 작성한 마지막 대형 상업 게임'으로 평가받는다는 사실은, 한 시대가 닫히는 지점을 정확히 가리킨다. 궁핍이 코드를 벼려내던 시대는 그렇게 저물었고, 그 시대가 남긴 몇 줄의 전설은 지금도 회자된다.