본문 바로가기
C.W.K.
Stream
Lesson 03 of 06 · published

효율, 성능, 슈퍼: macOS가 네 일을 어디에 놓는지

~15 min · cpu-soc, qos, scheduler, efficiency-cores, launchd, taskpolicy

Level 0스펙 시트 훑는 사람
0 XP0/91 lessons0/19 achievements
0/100 XP to next level100 XP to go0% complete
"스케줄러는 네 일이 얼마나 중요한지 안 물어봐. 네가 뭘 선언했는지 물어봐."

클러스터 둘, 그다음 이름 셋

M4 세대까지 모든 애플 실리콘 칩엔 두 종류의 CPU 코어가 있어. 앞 레슨의 넓은 코어인 성능 코어, 그리고 더 작고 더 느리고 돌리는 값은 훨씬 싼 효율 코어. macOS는 이걸 두 성능 레벨로 보고해. hw.perflevel0(M3 Ultra에선 성능 코어 24개)과 hw.perflevel1(효율 코어 8개). M5 세대는 사다리 이름을 바꿨어. 애플의 M5 Pro/Max 발표문은 "가장 높은 성능의 코어 설계 여섯 개, 이제 슈퍼 코어라 부른다"와 그 옆의 "전력 효율적인 멀티스레드 워크로드에 최적화된 완전히 새로운 성능 코어 12개"를 설명하고, Pro, Max, Ultra엔 효율 코어를 목록에 안 올려. 함대의 M5 노트북이 셸에서 그 이름을 확인해 줘. hw.perflevel0.nameSuper(6), hw.perflevel1.namePerformance(12), 세 번째 레벨은 없어. 기본 M5는 효율 코어를 유지하고, 프로 칩들은 이 증거로 보면 빠른 티어 하나와 효율적 멀티스레드 티어 하나, 그 아래는 없어.

일이 코어를 찾아가는 방법

아무도 손으로 코어를 안 골라. 스레드는 서비스 품질 등급을 들고 있어. 사용자 인터랙티브, 사용자 개시, 기본, 유틸리티, 백그라운드. 만든 코드가 선언하거나 바깥에서 프로세스 전체에 씌우는 거야. 스케줄러는 이 등급으로 어느 클러스터를 선호할지, 클럭을 얼마나 올릴지, 다이가 붐빌 때 누가 이길지를 정해. 사용자 인터랙티브와 사용자 개시 작업은 성능 클러스터 쪽으로 세게 기울고, 백그라운드 작업은 효율 클러스터에 놓이고, 중요한 건, 싸게 유지되도록 억제된 클럭으로 돌아. 부하가 바뀌면 스레드는 클러스터 사이를 옮겨 다녀. 등급은 선호와 예산이지 고정이 아니야.

그 예산을 셸에서 볼 수 있어. taskpolicy -c background는 프로세스를 백그라운드 등급에 묶어. 코드 블록은 office에서 같은 Python 루프를 각 클램프 아래서 돌려.

클램프2천만 회 루프비율증거
default1.31 s1.0x실측, office, 2026-09-15
utility1.26 s1.0x실측
maintenance7.75 s5.9배 느림실측
background8.81 s6.7배 느림실측

백그라운드 루프는 단순히 느린 코어에 있는 게 아니야. 6.7배는 효율 코어와 성능 코어 사이 격차보다 커. 느린 코어 그리고 억제된 클럭 그리고 다이에 대한 낮은 권리. 예산의 세 부분 전부야. 절대 눈에 띄면 안 되는 작업한테 딱 원하는 게 그거지.

함대가 이 위에서 돌아가는 이유

이 집의 맥들은 수십 개의 오래 사는 서비스를 돌려. 엔진들, 동기화 작업, 미디어 워커, 트랜스코딩 파이프라인. 누군가 실제로 쓰고 있는 포그라운드 앱 옆에서. 다이 하나 위에서 공존하는 건 그 서비스들이 자기를 선언하기 때문이야. ProcessTypeBackground로 둔 launchd 작업은 표의 백그라운드 줄처럼 스케줄되고, 컨트롤 플레인한테서 작업을 임대받는 워커는 무거운 루프를 일부러 유틸리티나 백그라운드 등급으로 돌려. 결과는 두 번째 기계 없이 서버이자 책상인 기계야. 규칙도 함정도 같은 문장이야. 스케줄러는 네가 뜻한 게 아니라 네가 선언한 걸 존중해. 자기 선언을 잊은 백그라운드 작업은 사용자의 편집기랑 풀 클럭으로 경쟁하고, 백그라운드 등급으로 일을 띄운 포그라운드 앱은 진행 막대가 왜 기어가는지 의아해해.

클러스터가 사주는 것 하나 더. 추론에 중요해. 모델이 GPU에서 디코드하는 동안 그걸 먹여 살리는 CPU 쪽 루프(샘플링, 토큰화, Python 드라이버)는 성능 코어 하나 위의 사용자 개시 등급 스레드 하나고, 기계의 나머지 전부는 성능 클러스터의 나머지(office에선 스물세 개, 성능 코어 여덟 개짜리 Max에선 일곱 개)와 효율 클러스터 전체에서 살 수 있어. GPU랑 CPU는 메모리 풀을 공유하지 스케줄러를 공유하진 않아.

Code

qos_clamp.sh — 같은 루프를 네 가지 서비스 품질 클램프 아래서·bash
#!/bin/zsh
# taskpolicy -c <class> clamps a process to a QoS class from outside; the
# scheduler places and clocks it accordingly. Run on any Apple silicon Mac.
cat > /tmp/loop.py <<'PY'
import time
t = time.perf_counter(); s = 0
for i in range(20_000_000):
    s += i * i
print(f"{time.perf_counter() - t:.2f}s")
PY

for clamp in default utility maintenance background; do
  printf "%-12s " "$clamp"
  if [[ $clamp == default ]]; then python3 /tmp/loop.py
  else taskpolicy -c $clamp python3 /tmp/loop.py; fi
done
# office, M3 Ultra, 2026-09-15:
# default      1.31s
# utility      1.26s
# maintenance  7.75s
# background   8.81s

sysctl hw.perflevel0.name hw.perflevel0.physicalcpu hw.perflevel1.name hw.perflevel1.physicalcpu
# M3 Ultra: Performance 24 / Efficiency 8
# M5 Max:   Super 6 / Performance 12   (no perflevel2 — no efficiency cores reported)
자기를 백그라운드로 선언하는 launchd 작업 (함대의 오래 사는 서비스들이 이렇게 해)·xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>            <string>com.example.nightly-index</string>
  <key>ProgramArguments</key> <array><string>/usr/bin/python3</string><string>/path/to/index.py</string></array>
  <key>ProcessType</key>      <string>Background</string>   <!-- efficiency cluster, restrained clock -->
  <key>LowPriorityIO</key>    <true/>
  <key>StartCalendarInterval</key> <dict><key>Hour</key><integer>3</integer></dict>
</dict>
</plist>
<!-- ProcessType: Background | Standard | Adaptive | Interactive. A 24/7 job
     that forgets this line runs at full clock beside the user's editor. -->

External links

Exercise

네 맥에서 qos_clamp.sh를 돌리고 네 시간을 카드에 추가해. 그다음 네가 손으로 띄우지 않은 오래 도는 프로세스 하나를 찾아봐. 동기화 클라이언트, 인덱서, 백업 같은 거. ps -o pid,pri,ni,command나 활성 상태 보기의 에너지 탭으로 그게 자기를 백그라운드로 선언했는지 판단해. 안 했다면 너한테 뭐가 달라질지 한 문장으로 써.
Hint
ps는 QoS를 직접 보여주지 않고 우선순위랑 nice를 보여줘. 백그라운드로 묶인 프로세스는 보통 낮은 우선순위를 보이고 활성 상태 보기의 CPU 기록에서 효율 클러스터에서 놀아. 네 후보가 하루 종일 풀 우선순위로 돌면, 그건 기계가 필요 이상으로 느린 거고, plist 키 하나면 고쳐져.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.