부록 A. 개발자를 위한 팁
- 쓰레드의 사용.
- 불필요한 CPU 깨우기를 야기하며, 깨어난 CPU를 효율적으로 활용하지 못하는 것. 만약 CPU를 깨워야만 한다면, 해야할 일 전체를 깨어난 CPU에서 한꺼번에 가능한 한 빨리 수행하십시오(race to idle, 역주: CPU 절전기능이 뛰어나기 때문에 CPU가 깨어있을 때는 최대한 빠른 속도로 필요한 작업을 수행하고, 유휴상태로 남는 시간을 최대한 늘려야 전력 소모를 최소화할 수 있다는 것).
[f]sync()
를 불필요하게 사용하는 것.- 불필요한 액티브 폴링 또는, 짧게 주기적으로 타임아웃을 사용하는 것. (대신 이벤트에 반응하도록 수정하십시오).
- 깨어난 CPU를 효율적으로 사용하지 않는 것.
- 비효율적인 디스크 액세스. 잦은 디스크 액세스를 방지하기 위해 커다란 버퍼를 사용하십시오. 한번에 커다란 블럭을 쓰도록 하십시오.
- 비효율적인 타이머 사용. 가능한 한 어플리케이션 사이에(가능한 한 시스템 전반에 걸쳐서도) 타이머를 그룹화하도록 하십시오.
- 과도학 I/O, 전력 소모, 또는 메모리 사용(메모리 누수 포함)
- 불필요한 계산 수행.
A.1. 쓰레드의 사용
Python은 전역 잠금 인터프리터(Global Lock Interpreter)[1]를 사용하며, 이에 따라 쓰레드를 사용하는 것은 오직 커다란 I/O 연산에서만 이득이 있습니다. Unladen-swallow[2]가 코드를 최적화하는 데 사용할 수 있는 더 빠른 파이썬 구현입니다.
펄 쓰레드는 원래 fork를 하지 않는 시스템(32비트 Windows 운영체제 등)에서 동작하는 프로그램을 위해 만들어졌습니다. 펄 쓰레드에서 데이터는 모든 개별 쓰레드에 복사됩니다(쓰기시 복사,Copy On Write). 사용자들이 데이터 공유의 수준을 결정할 수 있기 때문에, 데이터는 기본적으로 공유되지 않습니다. 데이터를 공유하기 위해서는 threads::shared 모듈을 포함시켜야 합니다. 하지만, 그렇게 할 경우 데이터가 (쓰기시 복사에 의해) 복사될 뿐아니라, 공유 모듈에 의해서 해당 데이터와 연계된 변수도 만들어집니다. 이 작업은 더 시간이 걸리고 더 느립니다.[3]
C 쓰레드는 메모리를 공유하고, 개별 쓰레드마다 자신만의 스택이 있습니다. 또한 커널은 쓰레드에 대해 새로운 파일 디스크립터를 할당하거나 새로운 메모리 공간을 할당할 필요가 없습니다. C는 실제로 더 많은 쓰레드에 대해 더 많은 CPU지원을 활용할 수 있습니다. 따라서 쓰레드의 성능을 최고로 끌어올리기 위해, C나 C++과 같은 저수준 언어를 사용하십시오. 만약 스크립트 언어를 사용한다면, C 바인딩(binding)을 작성하는 것을 고려해 보십시오. 프로파일러(profiler)를 사용해 코드에서 성능이 낮은 부분을 판별하십시오.[4]