Performance Considerations
OSXDEV
퍼포먼스는 어떤 소프트웨어 시스템에서든 중요한 요소이다. 커널만큼 이것이 사실인 분야도 없다. 작은 성능 문제가 지속적인 실행에 의해 커지게 된다. 이러한 이유로, 여러분의 코드를 가능한 효율적으로 만드는 것이 매우 중요하다.
이 챕터는 낮은 인터럽트 지연(low interrupt latency)과 입자가 고운(fine-grained) locking(역자 주:lock 하는 영역이 최대한 작아서 효율적인)의 중요성을 검토하고, 더 효율적인 디자인으로부터 여러분의 코드의 어떤 부분이 가장 이득을 얻을 것인지 결정하는 방법을 배우도록 하겠다.
[편집] 인터럽트 지연(Latency)
Mac OS X에서, 인터럽트 컨텍스트에서 실행되는 코드를 작성할 일은 거의 없을 것이다. 대체로, 오직 마더보드 하드웨만이 이것을 필요로 한다. 그러나, 인터럽트 컨텍스트에서 코드를 써야하는 희박한 상황에서, 인터럽트 지연(latency)는 중요한 문제이다.
인터럽트 지연은 인터럽트가 발생되고 인터럽트 핸들러가 실제로 그 인터럽트를 서비스하기 시작하는 사이의 지연시간을 가르킨다. 실제로, 최악의 경우의 인터럽트 지연은 관리자(supervisor) 모드(커널 모드로 불리기도 함)에서 다른 인터럽트를 처리하는 동안에 인터럽트와 함께 소비된 시간에 달려있다. 낮은 인터럽트 지연은 전체적인 성능을 위해서 반드시 필요하며, 특별히 오디오와 비디오 작업에서 더욱 그러하다. 납득할 만한 실시간 성능(예를들어, 멀티미디어 응용프로그램의 성능)을 얻기 위해서, 모든 장치 드라이버에서 발생되는 인터럽트 지연은 반드시 작고, 제한되어야 한다.
Mac OS X는 내장된 드라이버들에 대해서 인터럽트 지연을 최소하하고 제한하기 위해서 대단히 신경을 썼다. 주로 인터럽트 서비스 쓰레드(I/O 서비스 쓰레드라고도 알려짐)의 사용을 통해 이것을 처리했다.
Mac OS X가 인터럽트를 받으면, 저수준의 trap 핸들러가 일반적인(generic) 인터럽트 처리 루틴을 호출하고, 일반적인 인터럽트 처리 루틴은 인터럽트 콘트롤러 안에 있는 인터럽트 지연(pending) bit를 지워버린 다음, 장치에 한정된 인터럽트 핸들러를 호출한다. 장치에 한정된 핸들러는 그 다음에, 인터럽트 서비스 쓰레드로 메세지를 보내서 인터럽트가 발생했다는 것을 알리고 리턴한다. 더이상 지연된 인터럽트가 없으면, 현재 실행중인 쓰레드로 제어가 넘어간다.
인터럽트 서비스 쓰레드가 스케쥴된 다음에, 인터럽트가 발생했는지 확인한다, 그런후에 인터럽트를 서비스한다. 이름에서 추측할 수 있듯이, 이것은 실제로 인터럽트 컨텍스트가 아니라 쓰레드 컨텍스트에서 일어난다. 이러한 디자인은 전통적인 운영체제 디자인과의 두가지 중요한 차이점을 초래한다.
- 인터럽트 컨텍스트안에 실행되는 코드가 아주 작기때문에, 인터럽트 지연이 거의 0에 가깝다.
- 인터럽트가 장치 드라이버가 실행중에 발생하는 것이 가능하다. 전통적인(쓰레드된) 장치 드라이버는 선점되는 것이 가능하다, 그러므로 반드시 locking 또는 다른 비슷한 방법을 사용하여 공유되는 데이터를 보호해야 한다 (멀티 프로세서 컴퓨터에서 작동하기 위해서라도 그러한 처리를 할필요가 있다).
이러한 모델은 Mac OS X의 성능에 결정적이다. 인터럽트 컨텍스트에서 많은 양의 작업을 하도록 하여 이러한 디자인을 피해가서는 안된다. 그렇게 하는 것은 시스템의 전체적인 성능에 큰 악영향을 끼친다.




