2016년 5월
2010년, 미국에 온 이후 영어 공부를 제대로 하고자 거의 모든 생활 및 생각을 영어로만 해왔습니다만, 이제는 학업도 마치고 영어 자체도 많이 향상되어서 다시 한글을 쓰면서 생활해도 된다고 느꼈습니다.

그 동안 많은 소프트웨어 개발과 공부를 해왔는데, 그 사이의 개인적인 생각 또는 그 동안 해왔던 공부와 어떻게 해왔는지에 대해서 적고 공유하는 것도 나쁘지 않을 것 같아서 이런 페이지를 만들었습니다.

제 소개를 드리자면, 제 한국 이름은 유인환이라고 하고, 건국대학교에서 수학과 학부 졸업, 그리고 미국의 퍼듀 대학교에서 컴퓨터 그래픽스로 석사와 박사 학위를 마무리 하였고 현재는 실리콘 밸리에 있는 엔비디아라는 그래픽 카드 개발 회사에서 오픈지엘 코어 팀에서 소프트웨어 엔지니어로 일하고 있습니다. 미국에 오기 전에는 네오플이라는 게임 회사에서 던전 앤 파이터라는 게임 개발에 참여하였으며, 연구소에서 최적화, 툴 개발, 안정성 향상등의 작업을 처리했었습니다. 미국에 온 이후에는 드림웍스 에니메이션과 엔비디아에서 인턴쉽을 했었고, 석사와 박사 학위 과정에서 약 6개의 연구 논문을 국제 학회지에 발표했습니다. 주요 연구 주제는 컴퓨터 에니메이션 (휴먼 모션 분석), Point Cloud 렌더링, 및 그 외 퍼듀의 생명 과학 대학의 교수님과의 공동 연구로 새의 눈에 대한 연구등이 있었습니다.

개인 소장 책 및 분류




분야별 연결 고리: Bi-directional Hierarchical Sankey View
전체적으로 보기: Sunburst View
중요도 맵: Treemap View

프로그래밍 언어

저는 2001년도부터 건국대학교의 자연 과학 대학의 프로그래밍 동아리인 DeBug에서 프로그래밍 공부를 시작했습니다. Turbo C 컴파일러를 이용하여 C/C++ 프로그래밍을 선배들로부터 배웠습니다. 배운지 2개월 후에 프로젝트로 테트리스를 만들었으며, 그 후에는 고전 게임으로 유명한 Snake를 만들었습니다. Snake를 만들면서 Linked List에 대해서 알게 되었고, 그로 인해서 자연스럽게 Data Structure에 관심을 가지게 되었습니다. 그 이후 게임 회사에 입사하고 8개월 후에 스스로 부족함을 느끼고 또 수학의 필요성을 절실히 느낀 이후에 복학하여 스스로 책을 사모으면서 프로그래밍을 공부했습니다.

제가 생각하는 최고의 C/C++ 프로그래밍 책은 "C++ 기초 플러스"입니다. 이 책은 가장 기본적인 것부터 거의 모든 가능한 문법들을 설명해주고 많은 예제를 줍니다. 이 책을 공부하는 방법은 읽고 이해하고 이해하지 못하면 이해할 때까지 다시 읽거나 다른 분들께 여쭤봅시다. 그리고 예제가 나오면 무조건 코딩하고 컴파일하고 또 다시 코드를 바꿔서 컴파일하고 실행해보는 작업을 거쳐야 합니다. 꽤나 두꺼운 이 책은 위와 같이 공부하면 거의 2-3 개월은 걸릴 것입니다 (하루 3시간은 읽는다고 하면). 하지만 마스터한 이후에는 C++ 언어에 대해서 굉장히 자세히 알고 이해할 수 있게 됩니다.

위 책을 공부한 이후에 "Effective C++"를 읽어보시면 부족했던 부분들을 보충할 수 있습니다 (연산자 오버로딩등등). 그 외에 궁극적으로는 "The C++ Programming Language", C++의 창시자인 비야네 스트라우스트럽의 책이 있습니다. 이 책을 다 완독한다면 완전한 C++ 레퍼런스를 얻을 수 있습니다만 바쁘시면 레퍼런스 용도로 쓰셔도 괜찮은 책입니다.

저 같은 경우는 공부를 하면 할 수록 더 Low Level 언어에 대한 호기심이 생기게 되었습니다. 컴퓨터의 가장 기초적인 부분을 다 이해하고 싶었던 것 같습니다. 그래서 어셈블리 언어도 역시나 공부했었는데, 책 2권을 소개드리면 "인텔 기반 컴퓨터를 위한 어셈블리 언어 제5판"은 기본적인 컴파일 환경 설정부터 어셈블리 언어 프로그래밍을 하나하나 자세히 설명해주고 있습니다. 어셈블리 언어를 이해하시면 C/C++ 환경에서 스택이 어떻게 구현되었는지, 그리고 왜 함수마다 콜 규약이 다른지 등을 이해할 수 있습니다. 두번째 책은 인텔의 Single Instruction Multiple Data (SIMD)에 관한 책입니다. SIMD는 인텔 CPU에서 지원해주고 있는 벡터와 행렬등의 연산을 한번에 처리할 수 있게 해주는 특별한 어셈블리 명령어 집합니다. "SIMD 병렬 프로그래밍: SSE, AVX를 이용한 고속 프로그래밍"을 공부하시면 특수한 경우 성능을 몇 배에서 몇 십배 향상시킬 수 있는 SIMD 명령어 집합에 대해서 이해할 수 있습니다.

그래픽 카드 안에는 요새는 한 1 Ghz짜리 작은 프로세서가 수천개가 들어가 있습니다. 비록 일반 CPU의 코어에 비해 하나하나의 성능은 떨어지지만 수천개의 작은 프로세스는 모조리 병렬로 동작이 가능합니다. 만약 어떤 알고리즘이나 코드가 Embarassingly Parallel (순수히 병렬 처리가 가능) 하다면, 해당 알고리즘을 CUDA로 옮기면 엄청난 성능의 향상을 얻을 수 있습니다. 제가 석사 학위 논문으로 썼던 스케치 기반 에니메이션 검색도 CUDA를 이용하여 약 500배 이상의 성능의 향상을 보았습니다 (그때 당시는 그래픽 카드에 코어 개수가 수천개까지는 아니었기에 500배 정도였습니다). CUDA를 공부하기 위해서 가장 좋은 책 중 하나는 "CUDA By Example"이라는 책입니다. 요새는 더 많은 책들이 있겠죠.

자료 구조 및 알고리즘

자료 구조와 알고리즘은 어떤 프로그래밍을 공부하던지 무조건 굉장히 잘 이해하고 있어야 하는 영역입니다. 특히 실리콘 밸리의 주요 회사들의 인터뷰에서는 자료 구조와 알고리즘만 거의 3 - 4 시간에 걸쳐서 인터뷰합니다. 기술 인터뷰의 경우는 거의 2 - 3 세션에 걸쳐서 하는데 많은 질문이 자료 구조와 알고리즘입니다. 우선 자료 구조의 경우 어떻게 데이터를 저장하고 검색하고 읽을 것인가에 대한 부분인데 알고리즘과 밀접하게 관련이 있어서 같이 다루는 경우가 꽤나 많습니다. 중요한 만큼 꽤나 많은 책들이 있는데, 이론적인 책들은 매우 다양하고 많은 좋은 책들이 있어서, 실용적으로는 Standard Template Library (STL)을 공부하시면 C++를 사용하면서 매우 쉽게 쓸 수 있습니다.

추천드리는 책으로는 "STL Tutorial and Reference Guide: C++ Programming with the Standard Template Library"이 있습니다. 이 책은 한글 번역판도 있으니, 번역판을 다 읽고 하나하나 따라 하시면 확실히 엄청나게 도움이 됩니다. 또한 좀 더 자세한 STL의 레퍼런스는 "The C++ Standard Library: A Tutorial and Reference"가 있습니다. 이 책은 레퍼런스 용도이니 다 읽기보다는 중간중간에 찾아가면서 쓸 수 있는 책입니다.

STL을 다 공부하신 이후에는 추가로 Boost를 공부하시면 아직 표준화되지 않았지만 가능성이 있고 또 유용한 Template Libraries를 공부할 수 있습니다. 추천드리는 책으로는 2권 짜리로 되어 있는 "Introduction to the Boost C++ Libraries", Volume I과 II가 있습니다.

알고리즘은 궁극의 책으로 Stanford 교수님이자 LaTex의 창시자인 Donald Knuth가 쓰신 "The Art of Computer Programming"이 있습니다. 이 책은 사실 완독이 정말정말 어려운 책인데, 마이크로 소프트의 빌게이츠는 이 책을 다 이해한 사람이 있으면 자신에게 이메일을 보내면 무조건 마이크로 소프트에서 채용을 하겠다고까지 했었죠.

그리고 좀 더 Low Level로 가면 "Write Great Code: Volume 1: Understanding the Machine"과 "Write Great Code, Volume 2: Thinking Low-Level, Writing High-Level"이라는 책을 공부하시면 낮은 수준의 코드를 더 잘 이해하고 또 중요한 로우 레벨 알고리즘을 알 수 있습니다.

게임 프로그래밍

개인적인 생각으로는 게임 프로그래밍은 일반적인 프로그래밍보다 더 많은 스킬들을 요구합니다. 게임을 위한 2D drawing, 3D rendering, 수학, 물리, 네트웍크등등이 필요로 합니다. 물론 시중의 잘 만들어진 게임 엔진을 사서 쓰는 경우에는 하위 수준의 게임 프로그래밍은 필요가 없을 수 있습니다만, 시대가 바뀌면 다시 엔진에 적응해야 하는 등의 귀찮은 일들이 있기에 저 같은 경우는 제일 기초적인 공부를 중요하게 생각했습니다.

제일 처음으로 추천드리고 싶은 책은 "Game Coding Complete"입니다. 이 책은 게임 프로그래밍에 가장 중요한 흐름들을 자세히 설명해주고 있습니다.

게임 프로그래머를 위한 수학에는 "Mathematics for 3D Game Programming and Computer Graphics, Third Edition" 책을 공부하시면 3D 프로그래밍에 필요한 수학을 공부할 수 있습니다. 하지만 이 책은 입문자용은 아니고, 중급 수준은 되는 책이니, 만약 어려우시면 이공계 고등학교 1, 2, 3학년 수학을 먼저 공부하신 후에 저 책을 보시면 조금 더 쉽게 읽으실 수 있습니다.

네트웍크 프로그래밍

"TCP/IP 소켓 프로그래밍 (윤성우)" 매우 좋은 책입니다. 저는 한 2번은 완독했습니다. 물론 서버 프로그래머가 되기 위해서는 아마 훨씬 더 자세한 네트웍 프로그래밍을 공부해야 겠지만, 저는 클라이언트 쪽이었기에 네트웍은 많은 공부를 하지 않았습니다.

Computer Graphics

그래픽스는 제가 석사와 박사 학위를 마무리한 영역인지라 꽤나 많은 책들을 추천드릴 수 있습니다. 그래픽스 API는 아직까지는 2개의 Major APIs가 있는데, 하나는 OpenGL이고 다른 하나는 DirectX입니다. 하지만 곧 이 부분은 Vulkan이 추가되어 3개의 주요 APIs가 중요해질 듯 하네요.

약간의 장점 및 단점을 설명드리자면, OpenGL는 말 그대로 Open Graphics Library입니다. 모든 스펙 및 기본 구현 방법은 Khronos 그룹을 통해서 공개되어 있습니다. 그러므로 모든 플랫폼을 지원합니다. Windows, Linux, Unix, Mac OS, IOS, Android등 다 지원되고 있습니다. 물론 모바일의 경우는 OpenGL ES를 통해서 부분적인 API들만 지원되고 있습니다. 그 외에도 웹브라우저에서도 WebGL을 통해서 렌더링이 가능합니다. 아직까지도 계속 API가 발전해가고 있고, 버전 4.5까지 나와 있는 상태입니다.

DirectX의 경우는 Microsoft에서 개발한 Windows 운영체제에서만 동작하는 API입니다. 그러기 때문에 Windows에서는 DirectX가 가장 빠르게 동작합니다 (DirectX가 가장 빠르게 만들기 위해서 OpenGL의 성능을 약간은 고의적으로 떨어트린다고 의심받고 있습니다). DirectX 12가 현재로서는 최신 API인데, Windows용 게임이라면 고려할만한 API입니다. 만약 다양한 플랫폼을 지원한다면, DirectX는 선택하면 안됩니다.

마지막으로 Vulkan은 OpenGL과 DirectX에서의 단점인 하드웨어와의 중간 커뮤니케이션 시간을 극단적으로 줄이고 멀티 코어에서 최상의 성능을 낼 수 있도록 API 수준에서 디자인된 Khornos 그룹을 통해서 스펙이 공개된 라이브러리입니다. OpenGL과 DirectX는 그동안 1990년대 초부터 개발된 그래픽스 API로 오래된 역사만큼이나 하위 시스템 지원등을 해야 합니다. 그로 인해서 사실 CPU단에서의 Task와 GPU단에서의 Task의 완전한 분리가 안되어 있습니다. 이 얘기는 사실 중간중간 CPU와 GPU 사이의 동기화를 반드시 해야 한다는 의미인데, 과거에는 이 동기화 시간이 중요하지 않았습니다. 왜냐하면 다른 것에 들어가는 계산이 훨씬 비쌌으니까요. 하지만 점점 그래픽 하드웨어 성능이 강해지면서 사실 동기화가 차지하는 시간이 오히려 렌더링등에 들어가는 시간보다 더 비싸지기 시작합니다. 그러면서 이 동기화에 들어가는 시간이 아예 없앨 수 있는가에 대해서 Khornos 그룹에서 논의가 되었고, 현재 Vulkan이라는 새로운 API가 나오게 되었습니다. Vulkan의 장점은 CPU와 GPU 사이의 동기화가 매 프레임 거의 단 1번 정도로 완전히 분리되어 사실상 CPU와 GPU가 각각 100퍼센트 성능을 발휘할 수 있다라는 장점이 있습니다. 또한 멀티 코어 지원이 확실해져서 기존의 렌더링 물리등등 다른 스레드를 활용해야 했던 것이 Vulkan에서는 몇개의 렌더링 스레드를 활용하던 동기화가 없으므로 성능에 영향을 주지 않습니다. 물론 단점은 그만큼 그래픽스 코딩에 더 신경을 써주어야 합니다. 기존처럼 DrawCall이 바로 렌더링으로 연결되는 것이 아니라 원하는 시점에 어떤 순서로 렌더링을 해야 하는지도 미리 알려주어야 하기에 렌더링 관련 코드에 좀 더 시간이 들어갈 것입니다. 주의할 사항은 만약 현재 그래픽스 코드가 CPU나 GPU의 동기화가 거의 영향을 주지 않으며, 멀티 코어 자체도 중요하지 않다면, Vulkan으로 이동한다고 해서 더 성능의 향상을 얻는 것은 어렵습니다.

기본 OpenGL 공부를 위해서는 "OpenGL Programming Guide: The Official Guide to Learning OpenGL, Version 4.3 (8th Edition)" (빨간책으로 불립니다), 그리고 좀 더 발전된 형태는 "OpenGL Superbible: Comprehensive Tutorial and Reference (7th Edition)"을 읽으시면 OpenGL 사용하는데에 많은 도움이 됩니다. 그리고 좀 더 자세히 쉐이더를 공부하기 위해서는 "OpenGL Shading Language"도 도움이 됩니다.

DirectX는 제가 너무 오래 전에 공부했었던지라 아마 추천드리는 곳은 웹사이트입니다. Game Institute에 가셔서 DirectX 관련 모듈 1, 2, 3와 수학 관련 모듈들은 굉장히 도움이 될 것입니다.

컴퓨터 그래픽스 관련 중요한 책은 "Fundamentals of Computer Graphics, Fourth Edition"이 있고, 또 "Computer Graphics with OpenGL (4th Edition)"도 좋은 책입니다. 둘 다 읽기에는 중복되는 내용이 꽤 있습니다. 매우 오래된 책인 "Principles of Digital Image Synthesis"는 고전이지만 그만큼 중요한 책입니다 (아마 구하기 쉽지는 않을 것 같습니다).

그래픽스에서 사용되는 중요한 자료 구조들을 설명한 책에는 "Geometric Data Structures for Computer Graphics"이 있습니다. 특히나 그래픽스는 특이한 자료구조들이 특별한 알고리즘들과 같이 사용되는데, Quad-Tree, Oct-Tree, kD-Tree, Binary Space Partitioning (BSP), Portal등등. 이런 자료구조를 공부하는데 도움이 되는 책입니다.

그래픽스에서는 미적분이 중요해집니다. 외부 곡면을 구한다거나, 곡률을 계산하고, 또 Volume을 계산해내는 등등 모두 미분과 적분이 사용되게 됩니다. 이 부분은 "Calculus for Computer Graphics"을 통해서 공부할 수 있습니다. "Geometric Algebra for Computer Graphics" 이 책은 그래픽스에서 사용되는 다양하고 기초적인 수학 공식을 모아놓은 책입니다. John Vince의 시리즈 책들은 매우 유용한 레퍼런스 책들입니다.

영화 수준의 이미지를 만들기 위해서는 실제 물리 기반 빛을 비슷하게 시뮬레이션을 해야 합니다. Disney, Pixar, DreamWorks등에서는 모두 빛을 시뮬레이션하는 Ray Tracing 기법을 이용해서 렌더링을 하고 있지요. 이 분야는 꽤나 오랜 시간 동안 그래픽스에서 가장 중요한 토픽이었는데요. 지금은 어느 정도 완성되어 특수한 효과등에 연구 논문이 집중되고 있습니다. 이 분야는 몇 가지 중요한 영역으로 나뉘게 되는데, Geometry (Spatial Partitioning), Material (BRDF, BTDF, & BSSRDF), Camera, Ray 관련 방법론들 (오래된 distributed부터, path tracing까지), Participating Media (공기, 안개등등), 그리고 마지막 photon의 양을 인간이 눈이 모니터등에 제대로 볼 수 있도록 조절하는 Tone Mapping등으로 나뉠 수 있습니다. 이 영역은 물리 기반 렌더링이라고 불리우는데, 공부를 위해서는 "Physically Based Rendering, Third Edition: From Theory To Implementation"이라는 책을 읽으시면 중요한 알고리즘과 그 구현에 대해서 알 수 있습니다. 좀 더 얇은 책을 원하신다면, "An Introduction to Ray Tracing (The Morgan Kaufmann Series in Computer Graphics)"도 매우 얇고 빠르게 Ray Tracing에 대해서 이해할 수 있습니다. 하지만 얇은 만큼 방대한 양을 다루지는 못합니다. "Realistic Ray Tracing, Second Edition"도 오래되었지만 좋은 책이며, "Monte Carlo Methods in Global Illumination: Photo-realistic Rendering with Randomization" 책은 인터넷에 공개된 버전이 있습니다. 또 다른 책은 "Advanced Global Illumination"이라는 책이 있습니다.

아카데미 수상에 빛나는 University of California, San Diego 교수님이신 Henrik Wann Jensen의 저서 "Realistic Image Synthesis Using Photon Mapping"는 기존의 Ray Tracing을 어떻게 하면 빠르면서도 실사에 가깝게 만들 수 있는지에 대해서 그의 박사 과정 논문을 기반으로 쓰여진 책입니다. 빠른 Ray Tracing을 위해서 kD-Tree에 Photon의 양을 저장해놓은 Photon Mapping이라는 방법을 1999년도 경에 Siggraph에 발표된 논문을 기반으로 합니다. 또다른 좋은 책으로는 "The Magic of Computer Graphics" 책도 두께도 적당하며, Ray Tracing의 각 방법들을 잘 설명해주고 있습니다.

Visualization으로는 Visualization Toolkit (VTK)라는 라이브러리가 있습니다. 이 라이브러리는 굉장한 양의 알고리즘들을 제공해주고 있습니다. 직접 알고리즘을 구현하는 것보다 빠르게 구현해서 데이터를 보고 싶다면 추천드리는 라이브러리입니다. 특히나 Volumetric Data (3D Volume Data)의 Visualization 알고리즘들을 잘 지원해주고 있습니다. VTK를 설명해주는 책으로는 "The Visualization Toolkit, Fourth Edition"과 "The VTK User's Guide"가 있습니다.

그 외 실무에 필요한 것들

실제 회사등에서 소프트웨어 엔지니어로 일을 하게 되면 꼭 연관되지는 않지만 반드시 알아야 하는 것들이 존재합니다. 그 중 하나는 버전 컨트롤 시스템인데요. 소프트웨어 개발을 위해서 거의 모든 회사에서 사용하고 있습니다. Git, Perforce, SVN등등이 존재합니다. 책으로는 "Version Control with Git", "Practical Perforce", "Version Control with Subversion" 중에서 회사에서 필요로 하는 것을 공부하시면 됩니다.

추가로 "GOF의 디자인 패턴"이나 "패턴 지향 소프트웨어 아키텍쳐"등의 책을 보시면 프로그램 설계에 대해서 설명해주고 있습니다. 하지만, 너무 디자인 패턴을 맹신하지 말고, 자연스럽게 코딩을 해나가다가 보면 점점 패턴에 비슷하게 설계가 바뀌게 될 것입니다.

회사 인터뷰를 준비 중이시라면 "조엘 온 소프트웨어"는 가볍게 읽어주시는 것이 좋습니다. 실리콘밸리의 회사 인터뷰를 준비하신다면 거의 모든 자료구조와 정렬, 검색 등의 모든 주요 알고리즘은 알고 계셔야 합니다. 단순히 외우는 것이 아니라 이해하고 있어야 인터뷰할 때 문제가 되지 않습니다 (자료구조에서 복잡성은 쉽게 얘기할 수 있어야 하는 것은 당연합니다).