ARM Thumb 모드

ARM(Advanced RISC machines) 프로세서의 Thumb 모드에 대한 글을 써야겠다고 마음 먹고 있다가 시간을 내어 글을 쓰게 되었습니다.

ARM 프로세서는 일반적인 32비트 인스트럭션 셋을 제공하는 ARM 모드와, 16비트 인스트럭션 셋을 제공하는 Thumb 모드가 있습니다. 모든ARM 프로세서가 Thumb 모드를 지원하진 않고 ARM7TDMI처럼 프로세서 이름에 T가 들어있는 제품군이 Thumb 모드를 지원합니다.

이 이야기는 하나의 프로세서가 두 가지 인스트럭션을 제공한다는 뜻인데, 그 이유가 무엇일까요?

RISC 머신은 복잡한 CISC 머신에 비해서, 칩 설계가 간단해지므로 보통 한 CPU 사이클에 하나의 인스트럭션을 수행할 수 있다는 장점이 있습니다. 부족한 부분은 컴파일러 최적화를 활용해서 성능을 개선하는 것이죠. 반대로 CISC처럼 복잡한 인스트럭션이 없다 보니 같은 기능을 구현하기 위해 드는 인스트럭션의 길이가 길어지는 문제점도 있습니다.

ARM이 주로 조그마한 임베디드 시스템에 사용되는 프로세서임을 생각해 본다면 그런 기계들은 메모리도 무척 귀중한 자원임을 알수 있습니다. 하지만 ARM은 RISC 머신이기 때문에 바이너리 크기가 같은 기능을 하는 CISC 프로세서용 바이너리보다 커지는 것이죠.

이 문제를 해결하기 위해서 도입한 것이 Thumb 모드입니다. ARM 인스트럭션 중에 자주 쓰이는 수치 연산, 브랜치, load/store 등의 일부 명령을 16 비트로 표시할 수 있는모드를 만든 것이죠. ARM은 CSPR(Current Program Status Register)라는 현재 상태를 나타내는 레지스터가 있는데 여기 플래그를 하나 두고 현재 ARM 모드인지 Thumb모드인지 구분하게 됩니다.

하지만 하나의 CPU가 두 개의 인스트럭션 셋을 가진다는 것은 그만큼 프로세서가 복잡해진다는 것을 뜻합니다. 이러면 RISC의 기본 정신에 어긋나게 되겠죠. 실제로 Thumb 모드는 별도의 프로세서가 아닌 보조 하드웨어를 거쳐서 ARM 인스트럭션으로 변환되게 됩니다. 이 변환은 하드웨어에서 이루어지기 때문에 별도의 속도 저하가 일어나지 않는 것이죠.

물론 원래 32비트였던 인스트럭션을 16비트로 줄였기 때문에 몇 가지 제약 사항이 생깁니다. 원래 ARM 사용자모드에서는 16+1개 레지스터가 보이는데, 레지스터 어드레싱하는 비트를 줄이기 위해 이를 8+1개로 바꾸었습니다. 대신에 원래 ARM 모드에는 원래 PUSH, POP 명령은 암묵적으로 R13번을 사용하는 식으로 레지스터 어드레싱을 합니다.

ARM과 Thumb 모드는 하나의 바이너리 내에서도 자유롭게 변환이 가능합니다. 즉 C 프로그램을 컴파일한다고 하면 일부 함수는 ARM 모드로, 일부 함수는Thumb 모드로 컴파일이 가능한 것이죠. 물론 디바이스 드라이버나 예외 처리(exception handling) 같이 모든 레지스터와 인스트럭션에 대한 접근이 필요한 경우는 ARM 모드로 해야 하고요. 이런 변환은 보통 BX(Branch, Exchange)나 BLX(Branch, Link and Exchange) 같은 명령으로 이루어지는데 브랜치 할 때 목적 주소(destination address)의 LSB가 0인지 1인지에 따라 결정을 하게 됩니다.

Thumb 모드로 하면 한 가지 부수적인 장점은 데이터 버스를 16비트로 줄일 수 있다는 겁니다. 이 경우 Thumb 모드 인스트럭션은 16 비트로 버스로 보내고, 32비트 ARM 인스트럭션은 16비트 버스로2번 패치(fetch)해서 처리할 수 있죠. 실제데이터 버스는 16비트이지만 32비트로 RISC 머신을 쓸 수 있다는 장점이 있습니다. 대신에 비용을 낮추는 것이지요.

참고 문서
[1] Introduction to ARM thumb By Joe Lemieux, Courtesy of Embedded Systems Design

GLSL

지금까지 프로그래밍 언어(programming language)에 관심을 가졌으면서도 범용적인 언어만 공부하다 보니 특수 목적(special-purpose) 언어에 대한 관심을 깊이 못 가져본 것 같다. 이번에 한 회사 면접 준비를 하면서 GLSL(OpenGL Shader Language)를 조금 살펴봤는데, 범용 언어가 아니더라도 언어/컴파일러 기술이 활용될 수 있는 곳은 여전히 많이 있는 게 아닐까 하는 생각이 들었다.

흔히들 국내에서 프로그래밍 언어/컴파일러 쪽 전공하면 밥 먹고 살기 힘들다는 이야기를 많이 하는데, 이게 참 웃기다. 마이크로소프트나 썬 마이크로시스템즈의 예만 봐도 알 수 있듯이 소프트웨어에서 정말 기반이 되는 기술은 사실 언어와 런타임을 포함한 소프트웨어 플랫폼이기 때문이다. 즉 이걸 안 하면서 IT 강국을 키우겠다는 건, 모든 제품을 사다가 조립만 하는 조립 공장이 되겠다는 이야기와 크게 다르지 않다.

소프트웨어는 결국 하드웨어에 여러 겹 추상화 계층을 씌우는 작업이다 보니, translation은 거의 모든 소프트웨어의 필수적인 요소다. 3D 그래픽스 프로그래밍에 사용되는 Shading 언어도 결국은 그래픽스 칩 벤더가 제공하는 어셈블리 언어의 불편함을 줄이고, 범용적인 인터페이스를 제공하는 데 있다.

국내에 관련 업체가 별로 없다고는 하지만, 그렇게 밥 못 먹고 살만한 분야는 아닌 것 같은데…

UI 디자인

UI 디자인에 대한 잘못된 믿음 중에 하나는 UI 디자인은 프로그래머가 아닌 디자이너의 일이라는 생각이다. 물론 심미적인 부분도 중요하지만 실제로 UI 디자인에서 가장 중요한 것은 사용성이다. 애써 만든 프로그램이 사용하기 불편하고 어렵다면 그야말로 용두사미에 지나지 않는다.

좋은 UI는 사용자에게 필요한 정보만 줘야 한다. 예를 들어 일반적인 모니터 셋업 UI의 경우 사용자는 버튼을 눌러서 밝기, 명도, 색상 등 값을 1-100으로 조정할 수 있게 해준다. 반면에 어떤 모니터는 밝기 모드로 인터넷, 텍스트, 영화 등으로 몇 가지 직관적인 옵션을 제시하고 이 값에 따라 밝기, 명도, 색상을 적절한 값으로 조절해준다. 어느 쪽이 더 친절한 UI일까?

비슷한 예로 WinAmp 같은 mp3 감상 프로그램의 경우도 마찬가지다. 소리에 관한 세부적인 값을 조절할 수 있는 복잡한 컨트롤이 붙어있지만 이 값을 적절히 조절해 원하는 소리를 즐길 수 있는 전문가는 극소수에 지나지 않는다. 노래의 유형에 따라 재즈, 클래식, 팝, 가요 등으로 몇 가지 옵션을 주고 해당 장르에 적절한 셋팅 값을 주는 쪽이 대부분의 사용자에게는 훨씬 직관적이고 편리하다.

물론 좀 더 정교한 조작을 원하는 고급 사용자도 있기 마련이므로 이들 사용자를 위한 컨트롤은 남겨둘 수 있지만, 일반적으로 불필요한 기능을 과도하게 노출시키는 것은 사용하기 힘든 UI의 원천인 셈이다.