원문 캡처 · news.ycombinator.com
원문 캡처 · news.ycombinator.com

NeoBox 개발자는 iPhone 15 Pro에서 네오지오 에뮬레이터 Geolith를 프로파일링한 결과, 프레임 시간의 81%가 시그널 마스크(signal mask) 처리에 쓰였다고 밝혔다. 원인은 메모리 접근 전 오류를 확인하는 과정에서 프레임마다 약 2만 5,000회 호출되는 setjmp였으며, 수정 사항은 Geolith에 병합됐다.

NeoBox는 Mac, iPhone, iPad에서 실행되는 네오지오 에뮬레이터 프런트엔드다. 실제 에뮬레이션에는 루퍼트 카마이클(Rupert Carmichael)의 Geolith 라이브러리를 사용하고, 렌더링에는 Metal 기반 파이프라인을 쓴다.

NeoBox 개발자는 iPhone 15 Pro에서 앱을 시험하던 중 기기가 뜨거워지는 것을 발견해 프레임 처리 시간을 분석했다. 측정 결과 프레임 하나에 8.5밀리초가 걸렸고, 그중 81%가 sigprocmask와 sigalstack의 시그널 마스크 처리에 쓰였다. 개발자는 이 문제가 M1 Max 탑재 MacBook Pro에서는 두드러지지 않았지만 iPhone에서는 발열과 배터리 소모를 일으켰다고 설명했다.

개발자가 파악한 원인은 setjmp의 기본 동작이었다. CPU 에뮬레이션은 메모리에 접근하기 전에 오류를 가로채며, 이 보호 과정에서 setjmp를 사용했다. 하지만 setjmp는 시그널 마스크도 저장하고, 이 경우에는 그 저장이 필요하지 않았다. 시그널 마스크를 저장하지 않는 _setjmp를 사용하면 된다는 설명이다.

개발자가 iPhone에서 측정한 호출당 시간은 setjmp가 281나노초, _setjmp가 2.1나노초로, 약 130배 차이가 났다. 이 변경은 Geolith 저장소의 병합 요청을 통해 반영됐다. 따라서 NeoBox뿐 아니라 Geolith를 사용하는 다른 프로젝트도 해당 변경의 혜택을 받을 수 있다.