C.W.K.
Stream
Lesson 03 of 05 · published

Apple Instruments 프로파일링

~14 min · instruments, metal, profiling, apple-silicon

Level 0Beginner
0 XP0/38 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete

Xcode Instruments + Metal System Trace — Apple의 Nsight equivalent

Apple Silicon에선 프로파일링 도구가 별도 다운로드 아니라 Xcode 일부. 관련 instrument:

  • Metal System Trace — command buffer, encoder activity, CPU/GPU sync의 timeline.
  • Metal GPU Counters — per-kernel 하드웨어 counter, Nsight metric의 equivalent.
  • GPU Performance Counters — 더 낮은 레벨 shader debug, 손코딩 커널에 유용.

M3 Ultra의 MPSMatrixMultiplication에서 캡처한 실제 숫자 (FP32, 4096³):

CounterBLAS (avg)BLAS (max)손코딩 Custom (max)
F32 Utilization0.67993.9%35.1%
ALU Utilization0.61363.3%44.2%
Last Level Cache Util0.46656.3%14.2%
GPU Bandwidth (GB/s)13.0978.5695.6
Total Occupancy1.51100%95.1%

나란히 읽기: BLAS가 비슷한 품질의 손코딩 커널 대비 F32 utilization 3.9× 높고, ALU utilization 2.7× 좋고, cache utilization 3.1× 좋음. 같은 하드웨어, 극적으로 다른 효율. 격차가 lesson 1의 다섯 기둥, 다시.

유용한 Apple-side 프로파일에 캡처할 거

  • 워크로드 두 번 돌리기 — command-buffer Trace 한 번, GPU Counter 한 번. 섞으려고 하지 마.
  • Frequency 핀: Activity Monitor → Window → GPU History로 캡처 동안 GPU가 boost clock으로 도는지 확인.
  • 여러 frame 캡처; 첫 frame은 항상 compile / first-load 비용.
  • 'avg'랑 'max' counter 값 비교 — 격차가 스케줄링 안정성 알려줌.

Code

Command-line Swift binary에서 프로파일 생성·bash
# Instruments가 symbolicate할 수 있게 debug info로 빌드
xcrun -sdk macosx swiftc gemm_bench.swift \
    -framework Metal -framework MetalPerformanceShaders -framework Foundation \
    -g -o build/gemm_bench

# Metal System Trace 템플릿으로 Instruments 아래 launch:
xcrun xctrace record --template 'Metal System Trace' \
    --launch -- ./build/gemm_bench

# 결과 .trace bundle을 Instruments에서 열기
open *.trace
Counter programmatic read — MTLCommandBuffer GPU time·swift
// 가벼운 '이 커널 진짜 얼마나 걸렸어?' timing용:
let cb = queue.makeCommandBuffer()!
cb.label = "gemm_4096"
// ... encoder.dispatchThreadgroups ...
cb.commit()
cb.waitUntilCompleted()

// GPU-side timing, 기본은 Instruments 필요 없음:
let elapsed = cb.gpuEndTime - cb.gpuStartTime
let flops = 2.0 * Double(m) * Double(n) * Double(k)
print("GPU time: \(elapsed * 1000) ms, \(flops / elapsed / 1e12) TFLOP/s")

External links

Exercise

Apple Silicon Mac 아무거나에서 Track 6의 tiled GEMM을 4096³로 프로파일. F32 Utilization, ALU Utilization, Last-Level-Cache Util 캡처. 위 표의 MPSMatrixMultiplication 숫자랑 비교. 각 metric의 3-4× 격차가 다시 lesson 1의 다섯-기둥 격차 — 이번엔 NVIDIA 대신 Apple 프로파일러가 풀어 씀.

Progress

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

댓글 0

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

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