지저분한 최적화 비법 (Playdate용 C)

Dirty Optimization Secrets (C for Playdate)

devforum.play.date ▲ 71 댓글 12 ibobev

요약

Playdate에서 C 코드를 빠르게 하려면 연산보다 메모리와 캐시 배치를 먼저 따져야 합니다.

휴대용 게임기 Playdate에서 Game Boy 에뮬레이터를 원래 속도로 돌리려던 개발자 NaOH가 공식 개발자 포럼에 정리한 글입니다. 흔한 게임 최적화 요령이 아닙니다. 에뮬레이터, 대규모 시뮬레이션, 3D 렌더러처럼 성능을 끝까지 짜내야 하는 코드를 위한 기법이라고 밝혔습니다.

왜 중요한가

  • 이 기기의 병목은 CPU 연산이 아니라 캐시 밖 메모리 접근이라는 점을 실제 경험으로 보여 줍니다.
  • 코드 크기와 배치만 바꿔도 속도가 크게 달라집니다. 컴파일러 최적화 옵션만 믿어서는 안 된다는 뜻입니다.

핵심 내용

  • 명령어 캐시가 4KB(리비전 A 기준)로 작아서 -O3보다 -Os(크기 우선 최적화)가 더 빠를 수 있다고 했습니다.
  • 거대한 switch 표를 걷어내 에뮬레이터 핵심부를 20KB에서 2KB로 줄이자 눈에 띄게 빨라졌다고 합니다.
  • 스택이 놓인 DTCM(CPU에 바로 붙은 고속 메모리)에 자주 쓰는 데이터를 올려 두는 요령을 소개했습니다.
  • 빌드마다 속도가 최대 50%까지 달라지는 현상은 캐시 줄 정렬과 분기 예측 충돌 탓으로 보고, 링커 스크립트로 정렬하라고 권했습니다.
  • 함수를 ITCM(명령어용 고속 메모리)으로 옮기는 기법도 있지만, 잘못 다루면 프로그램이 쉽게 죽는다고 경고했습니다.

HN 반응

  • 한 이용자는 메모리 속도가 CPU를 따라잡았다는 RISC 옹호 논문의 전제를 이 글이 뒤집는다며, 코드 밀도는 여전히 중요하다고 짚었습니다.
  • 이에 다른 이용자는 최고 성능을 노린 8·16비트 시절 게임이 어셈블리로 쓰인 이유를 보여 주는 글로 읽힌다고 답했습니다.

댓글

12개 표시 · 전체 12개
  1. boricj HN

    플레이스테이션에서 복셀 스페이스(voxel space) 렌더링 데모를 만지작거리면서 썼던 요령 몇 가지가 떠오르네요.

    이런 작업에 그 콘솔은 특이한 점이 있습니다. 메인 RAM에서 읽을 때마다 CPU가 6사이클씩 멈추는 데다(사용 시점까지 기다렸다 멈추는 방식도 아닙니다), 데이터 캐시도 없습니다. 이 용도에는 아주 안 맞는 구조라서, 성능을 되찾으려고 온갖 꼼수를 즉흥적으로 짜내야 했습니다.

    • 핫 루프 전체를 함수 하나에 넣어서, 4 KiB 직접 매핑 명령어 캐시에 통째로 들어가게 했습니다(명령어 1024개 미만).

    • 함수 호출을 2 KiB 스크래치패드로 트램펄린(trampoline)해 주는 C++ 템플릿을 작성했습니다.

    • 스크래치패드의 나머지는 CLUT 테이블에 썼습니다. 읽을 때 멈추지 않거든요.

    • CPU가 N+1번째 높이 맵 데이터를 가져오느라 멈춰 있는 동안, GTE로 N번째 좌표 묶음을 변환했습니다.

    • 실제 3D 투영보다 단순한 공식을 쓸 수 있다는 점을 이용해, GTE를 이론상 한계보다 명령어당 더 많은 점을 변환하도록 구워삶는 방법을 찾아냈습니다.

    • 사각형 프리미티브는 디스플레이 리스트를 거치지 않고 GPU 레지스터에 바로 씁니다.

    플레이스테이션을 어찌나 혹사시키는지, PCSX-Redux와 DuckStation이 성능을 최대 두 배까지 다르게 보여 줍니다. 언젠가 마무리해서 실기에서는 어떻게 돌아가는지 보고 싶네요...

  2. omoikane HN

    이런 최적화가 Playdate 개발을 재미있게 만드는 이유 중 하나입니다. 사양이 더 높은 다른 플랫폼보다 Playdate에서 훨씬 보람이 크거든요.

    (물론 최적화를 재미있어하는 사람이라면 그렇다는 얘기예요. 코드 최적화에는 퍼즐을 푸는 맛이 있는데, 저는 그게 정말 좋습니다.)

  3. mococa HN

    이거 보니까 생각나네요 - https://graphics.stanford.edu/~seander/bithacks.html

  4. nxobject HN

    코드를 어떻게 배치하고 꼼꼼히 나누는지에 대한 팁이라니, 옛날 생각이 확 나네요!

  5. ahartmetz HN

    배치가 조금만 바뀌어도 성능이 예측 불가능해지는 문제를 줄이는 팁은 안타깝게도 지금도 그대로 통합니다.

  6. Joker_vD HN

    ...이거 읽다 보면 꼭 "복잡 명령어 집합 컴퓨터(CISC)를 옹호하는 논변" 같아요. 심지어 그 유명한 "RISC를 옹호하는 논변" 논문이 내세운 핵심 전제 중 첫 번째, 즉 메모리 속도가 마침내 CPU 속도를 따라잡았다는 주장을 아예 정면으로 박살내거든요. 아니요, 따라잡지 못했습니다. "코드 밀도" 논거도 마찬가지예요. 아니요, 코드 밀도는 아주 중요합니다.

    하긴 애초에 "RISC를 옹호하는 논변" 논문은 제목부터 잘못 붙은 셈이었죠. 실제로는 "CISC를 반대하는 논변"이에요. 패터슨과 디츨은 자기들이 옹호한다는 "RISC"가 정확히 무엇인지는 절대 말하지 않으려고 아주 조심하고, 실제로 RISC를 옹호하지도 않습니다. 대부분 당시의 ISA와 그 설계 방식 전반을 비판할 뿐이에요.

  7. throwawayk7h HN

    글쎄요, Playdate는 하드웨어가 썩 좋지 않잖아요. 모바일 기기나 노트북용으로 코딩한다면 이 조언은 해당되지 않을 수도 있어요.

  8. pjmlp HN

    저한테는 오히려, 최고 성능을 노리던 8비트·16비트 홈 컴퓨터 게임 대부분이 왜 전부 어셈블리로 짜였는지를 설명하는 글처럼 읽힙니다.

  9. maxlin HN

    누가 클론을 내놓아 줬으면 좋겠습니다. 그 "컴퓨터"는 5달러어치밖에 안 되거든요. 저는 20달러짜리 ESP32 개발 보드 등에 제 3D 게임 엔진을 포팅하며 프로그래밍하는 재미를 누려 왔고, 더 "미친" 플랫폼을 찾고 있습니다. 그런데 Playdate는 가격 정책 때문에 아예 손대고 싶지도 않아요. 우리 사무실 창고에 안 쓰는 게 하나 있는데도요.

  10. Wowfunhappy HN

    SoC 가격이 5달러라는 뜻인가요? Playdate는 화면, 버튼, 배터리, OS에다 (작은 편이긴 해도) 기본 수록 게임 24개까지 딸려 오잖아요.

    그게 전부 합쳐서 어떻게 계산되는지는 찾아보지 않았지만, Raspberry Pi 본체만 사는 경우와 케이스, 화면, 주변기기까지 붙여서 사는 경우의 가격 차이를 생각해 보면, 230달러쯤 되는 것도 이해가 가요.

    하다못해 Switch 2 Joy-Con 한 세트만 해도 100달러인걸요.

  11. maxlin HN

    계산이 10배쯤 틀리셨습니다. 제가 개발해 본 개발 보드는 말 그대로 20~30달러이고, 3.5인치 화면 형태든 스마트워치 형태든 케이스, 터치스크린, 버튼, 배터리, 실시간 OS, RTC, 와이파이, 수두룩한 GPIO까지 다 갖추고 있습니다. Playdate가 그 위에 더 가진 하드웨어는 살짝 더 나은 만듦새, 대부분의 게임이 쓰지 않는 크랭크(swivel), 10~20MB 더 많은 RAM 정도입니다. 흑백(그레이스케일) 화면을 택한 것도 비용을 아껴 주고요. 그 30달러짜리 개발 보드들은 흔한 풀컬러 화면을 쓰는데 말이죠.

    그러니 Playdate의 가격이 부품 원가와 전혀 맞지 않는다는 건 너무나 뻔합니다.

    1GB 이상 RAM을 갖춘 완전한 리눅스 머신까지 성능을 올려도, RG3588급처럼 그런 기기는 얼마든지 있습니다. 저도 하나 갖고 있는데, aarch64 리눅스에서 돌아가는 소프트웨어라면 뭐든 돌릴 수 있는 리눅스 박스로 잘 쓰고 있어요. 제 건 비교적 고급형이라 배송비까지 합쳐 ~100달러였지만, 좀 더 "기본" 사양이어도 하드웨어로는 Playdate를 훌쩍 뛰어넘는 걸 40달러 정도에 구할 수 있습니다.

    Playdate가 가진 건 폐쇄적인 생태계(walled garden)입니다. 저는 그런 건 싫습니다. 출시된 지 이렇게나 지났는데 아직도 그러니 더 싫고요.

    닌텐도 정품 Joy-Con 가격을 비교 대상으로 드셨는데, 폐쇄적 생태계가 얼마나 깊어질 수 있는지 잘 모르시는 것 같네요.

  12. Wowfunhappy HN

    대부분의 게임이 쓰지 않는 크랭크(swivel)

    제가 해 본 게임은 대부분 실제로 크랭크를 씁니다. 가끔은 쓰지 않았으면 싶을 때도 있고요. (많은 게임에서 크랭크가 정말 마음에 들지만, 버튼으로 충분한데 굳이 크랭크를 쓰게 만드는 게임도 있습니다.)

    흑백(그레이스케일) 화면을 택한 것도 비용을 아껴 주고요. 그 30달러짜리 개발 보드들은 흔한 풀컬러 화면을 쓰는데 말이죠.

    ...그런데 Playdate의 화면은 일반적인 LCD처럼 보이지 않습니다. e-ink에 훨씬 가까워 보여요. (e-ink가 더 낫긴 하지만, Playdate가 거기까지 한 60%쯤은 따라간 것 같아요.)

    구글로 아주 간단히 찾아봤는데, Playdate 크기와 해상도의 이런 화면은 30달러쯤 하는 것 같습니다[1]. SoC가 정말 5달러라면 이 두 부품만으로도 벌써 35달러예요. 조립 같은 건 아직 하지도 않았는데요.

    닌텐도 정품 조이콘 가격을 비교 대상으로 드셨는데, 폐쇄적 생태계가 얼마나 깊어질 수 있는지 잘 모르시는 것 같네요.

    그래도 닌텐도에는 패닉이 갖지 못한 규모의 경제가 있잖아요. 서드파티 Switch 컨트롤러도 써 봤는데 손맛이 그만 못했어요. 저는 품질에 돈을 내는 겁니다. (솔직히 Playdate 버튼 느낌도 썩 좋지는 않아요. 나쁘진 않지만 닌텐도 수준은 아니죠!)

    Playdate가 게임 콘솔이고, 게임 콘솔을 살 때는 잘 짜인 생태계에 돈을 내는 거라는 점에는 저도 동의합니다. PC 게이밍이 거의 모든 면에서 더 낫지만 손이 더 가죠. 많이 가는 건 아니고, 어디까지나 약간요.

    참고로 저도 제 Playdate에 완전히 만족하지는 않아요. 게임 라이브러리가 마음에 들지 않아서요. 그래도 귀엽고, 게임 자체가 아니라 소프트웨어는 정말 마음에 듭니다. 극단적일 정도로 다듬어진 UI에는 사족을 못 쓰거든요.

    1: https://www.digikey.com/en/products/detail/sharp-microelectronics/LS027B7DH01A/5054067

Hacker News에서 보기 ↗