"스케줄러는 네 일이 얼마나 중요한지 안 물어봐. 네가 뭘 선언했는지 물어봐."
클러스터 둘, 그다음 이름 셋
M4 세대까지 모든 애플 실리콘 칩엔 두 종류의 CPU 코어가 있어. 앞 레슨의 넓은 코어인 성능 코어, 그리고 더 작고 더 느리고 돌리는 값은 훨씬 싼 효율 코어. macOS는 이걸 두 성능 레벨로 보고해. hw.perflevel0(M3 Ultra에선 성능 코어 24개)과 hw.perflevel1(효율 코어 8개). M5 세대는 사다리 이름을 바꿨어. 애플의 M5 Pro/Max 발표문은 "가장 높은 성능의 코어 설계 여섯 개, 이제 슈퍼 코어라 부른다"와 그 옆의 "전력 효율적인 멀티스레드 워크로드에 최적화된 완전히 새로운 성능 코어 12개"를 설명하고, Pro, Max, Ultra엔 효율 코어를 목록에 안 올려. 함대의 M5 노트북이 셸에서 그 이름을 확인해 줘. hw.perflevel0.name은 Super(6), hw.perflevel1.name은 Performance(12), 세 번째 레벨은 없어. 기본 M5는 효율 코어를 유지하고, 프로 칩들은 이 증거로 보면 빠른 티어 하나와 효율적 멀티스레드 티어 하나, 그 아래는 없어.
일이 코어를 찾아가는 방법
아무도 손으로 코어를 안 골라. 스레드는 서비스 품질 등급을 들고 있어. 사용자 인터랙티브, 사용자 개시, 기본, 유틸리티, 백그라운드. 만든 코드가 선언하거나 바깥에서 프로세스 전체에 씌우는 거야. 스케줄러는 이 등급으로 어느 클러스터를 선호할지, 클럭을 얼마나 올릴지, 다이가 붐빌 때 누가 이길지를 정해. 사용자 인터랙티브와 사용자 개시 작업은 성능 클러스터 쪽으로 세게 기울고, 백그라운드 작업은 효율 클러스터에 놓이고, 중요한 건, 싸게 유지되도록 억제된 클럭으로 돌아. 부하가 바뀌면 스레드는 클러스터 사이를 옮겨 다녀. 등급은 선호와 예산이지 고정이 아니야.
그 예산을 셸에서 볼 수 있어. taskpolicy -c background는 프로세스를 백그라운드 등급에 묶어. 코드 블록은 office에서 같은 Python 루프를 각 클램프 아래서 돌려.
| 클램프 | 2천만 회 루프 | 비율 | 증거 |
|---|---|---|---|
| default | 1.31 s | 1.0x | 실측, office, 2026-09-15 |
| utility | 1.26 s | 1.0x | 실측 |
| maintenance | 7.75 s | 5.9배 느림 | 실측 |
| background | 8.81 s | 6.7배 느림 | 실측 |
백그라운드 루프는 단순히 느린 코어에 있는 게 아니야. 6.7배는 효율 코어와 성능 코어 사이 격차보다 커. 느린 코어 그리고 억제된 클럭 그리고 다이에 대한 낮은 권리. 예산의 세 부분 전부야. 절대 눈에 띄면 안 되는 작업한테 딱 원하는 게 그거지.
함대가 이 위에서 돌아가는 이유
이 집의 맥들은 수십 개의 오래 사는 서비스를 돌려. 엔진들, 동기화 작업, 미디어 워커, 트랜스코딩 파이프라인. 누군가 실제로 쓰고 있는 포그라운드 앱 옆에서. 다이 하나 위에서 공존하는 건 그 서비스들이 자기를 선언하기 때문이야. ProcessType을 Background로 둔 launchd 작업은 표의 백그라운드 줄처럼 스케줄되고, 컨트롤 플레인한테서 작업을 임대받는 워커는 무거운 루프를 일부러 유틸리티나 백그라운드 등급으로 돌려. 결과는 두 번째 기계 없이 서버이자 책상인 기계야. 규칙도 함정도 같은 문장이야. 스케줄러는 네가 뜻한 게 아니라 네가 선언한 걸 존중해. 자기 선언을 잊은 백그라운드 작업은 사용자의 편집기랑 풀 클럭으로 경쟁하고, 백그라운드 등급으로 일을 띄운 포그라운드 앱은 진행 막대가 왜 기어가는지 의아해해.
클러스터가 사주는 것 하나 더. 추론에 중요해. 모델이 GPU에서 디코드하는 동안 그걸 먹여 살리는 CPU 쪽 루프(샘플링, 토큰화, Python 드라이버)는 성능 코어 하나 위의 사용자 개시 등급 스레드 하나고, 기계의 나머지 전부는 성능 클러스터의 나머지(office에선 스물세 개, 성능 코어 여덟 개짜리 Max에선 일곱 개)와 효율 클러스터 전체에서 살 수 있어. GPU랑 CPU는 메모리 풀을 공유하지 스케줄러를 공유하진 않아.