.NET 성능 엔지니어링
ASP.NET Core, 서비스, 콘솔 애플리케이션, Avalonia, WPF, WinUI, MAUI, Skia, WebGPU, 게임/그래픽 엔진, NativeAOT 및 네이티브 상호 운용성 워크로드를 포함한 .NET 애플리케이션의 성능을 조사, 설명, 수정, 벤치마킹 또는 검증할 때 이 스킬을 사용하세요.
이 저장소는 하나의 스킬을 정의합니다. SKILL.md는 정책 및 라우팅 진입점이며, 상세한 운영 절차는 계층적 참조 트리에 있습니다. 현재 조사에 필요한 인덱스와 챕터만 로드한 후, 증거가 소유권 경계를 넘어설 때 확장하세요.
절대 규칙
- 실제 배포 형태의 최적화된 빌드(일반적으로
Release)를 프로파일링하고 벤치마킹하세요. - 커밋 및 더티 상태, SDK/런타임, OS, 아키텍처, 하드웨어, 전원 모드, 워크로드, 도구 버전, 환경 재정의 및 정확한 명령을 기록하세요.
- 코드를 변경하기 전에 결정론적 재현을 확립하세요.
- 콜드 스타트, 첫 사용, 웜 스테디 상태, 오버로드, 드레인 및 종료를 분리하세요.
- 콜드 동작이 주제가 아닌 한 계층형 컴파일, 셰이더, 파이프라인, 캐시 및 풀을 워밍업하세요.
- 모든 관련 소유권 경계(관리형 런타임, 네이티브 라이브러리, 커널, 스케줄러, 파일시스템/네트워크, 종속성, 드라이버, GPU, 컴포지터, 디스플레이)에서 증거를 수집하세요.
- RSS만으로 관리형 보유를 추론하지 마세요.
- 높은 프레임 시간, GPU API 사용량 또는 유틸리티만으로 GPU 포화를 추론하지 마세요.
- 하나의 평균, 하나의 트레이스, 하나의 프레임 캡처, 하나의 마이크로벤치마크 또는 가장 빠른 벤치마크 실행으로 수정을 주장하지 마세요.
- 원시 아티팩트를 보존하고 누락된 심볼, 드롭된 이벤트, 프로파일러 오버헤드, 환경 변동 및 불확실성을 보고하세요.
- 덤프, 트레이스, 로그, SQL 스팬, 패킷 캡처 및 벤치마크 입력 코퍼스에서 비밀 및 개인 데이터를 보호하세요.
- 명령 예제를 버전에 민감한 것으로 취급하세요. 설치된 도구 도움말을 먼저 조회하세요. 구문이 다른 경우 도움말이 예제를 재정의합니다. 검증된 선택 규칙 및 표준 형식은
references/command-reference.md를 사용하세요.1
필수 조사 출력
다음을 보고하세요:
- 증상 — 관찰 가능한 영향과 위반된 목표.
- 재현 — 결정론적 워크로드 및 환경.
- 수집 — 정확한 도구, 명령, 기간 및 아티팩트 경로.
- 증거 — 카운터, 트레이스, 캡처, 덤프, 벤치마크 분포 및 측정값.
- 소유권 — 관리형 CPU, 런타임, 네이티브 CPU, 커널, 스케줄러, I/O, 종속성, 메모리, 드라이버, GPU, 컴포지터 또는 디스플레이.
- 주요 원인 — 가장 큰 지원 비용, 대기 또는 가장 빠르게 증가하는 리소스.
- 수정 — 가장 작은 고효율 코드 또는 구성 변경.
- 검증 — 스프레드 및 꼬리 메트릭을 포함한 동등한 전후 실행.
- 잔여 위험 — 해결되지 않은 병목 현상 및 측정 한계.
동등한 워크로드의 전후 증거 없이 개선을 주장하지 마세요.
참조 라우터
항상 references/index.md, references/core/index.md 및 검증된 references/command-reference.md에서 시작하세요.
질문별로 추가 도메인 인덱스를 로드하세요:
- 관리형 CPU, 할당, GC, JIT, 예외, ThreadPool, 잠금, 비동기 스택, 덤프:
references/runtime/index.md - 관리형/네이티브/VM/매핑/GPU 메모리 소유권 및 누수 분석:
references/memory/index.md - 경합, 비동기 지연, 큐, 역압, 파일/네트워크/데이터베이스 I/O, UI 디스패처 지연:
references/latency/index.md - 콜드 스타트, 첫 프레임/요청, 로더, JIT, ReadyToRun, 트리밍, 단일 파일, NativeAOT:
references/startup/index.md - BenchmarkDotNet, 마이크로/컴포넌트/매크로/로드/소크 벤치마크, 비동기/동시성 벤치마크, JIT/AOT 비교, 디스어셈블리, 하드웨어 카운터, 통계, CI 게이트:
references/benchmarking/index.md - 프로덕션, 컨테이너, 진단 포트,
dotnet-monitor, 트리거 수집, Kubernetes, 아티팩트 보안:references/production/index.md - UI/렌더링/GPU/WebGPU/Metal/D3D/Vulkan/OpenGL/셰이더/동기화/프레젠테이션:
references/gpu/index.md
references/platforms/index.md를 통해 모든 관련 플랫폼 참조를 로드하세요. 단일 호스트 조사는 일반적으로 하나의 플랫폼 문서가 필요합니다. 크로스 플랫폼 비교 및 원격/클라이언트-서버 시나리오는 여러 개가 필요할 수 있습니다.
기본적으로 모든 문서를 로드하지 마세요. 현재 가설에 답하는 최소 세트를 선택하되, 다른 가이드가 필요하다는 이유만으로 소유권 경계에서 멈추지 마세요.
빠른 분류 순서
- 프로덕션에 해당하는 구성을 빌드하고 실행합니다.
- 워크로드 단계, 성공 메트릭 및 중지 규칙을 정의합니다.
System.Runtime카운터와 프로세스 CPU 및 총 메모리를 기록합니다.- 관리형 소유권이 가능할 때
dotnet-trace로 관리형 CPU/런타임 증거를 캡처합니다. - 진행, 기아 또는 차단이 의심될 때 반복 스택을 캡처합니다.
- 총 비용이 설명되지 않으면 플랫폼 네이티브 CPU/스케줄러/I/O/메모리 트레이스를 수집합니다.
- 메모리의 경우 관리형 라이브 바이트, GC 커밋, 비공개/RSS/PSS, 네이티브 할당, 매핑, 그래픽 할당 및 GPU 상주를 비교합니다.
- 렌더링의 경우 애플리케이션 마커, CPU 제출, GPU 타임스탬프, 네이티브 GPU 캡처, 프레젠트, 컴포지터 및 디스플레이 타이밍을 상호 연관시킵니다.
- 벤치마크 요청의 경우 BenchmarkDotNet 또는 다른 하네스를 선택하기 전에 마이크로, 컴포넌트, 매크로, 로드 또는 소크 방법론을 선택합니다.
- 프로덕션 전용 인시던트의 경우 제한되거나 트리거된 수집을 사용하고 cgroup/호스트 제약 조건을 기록합니다.
- 증거가 주요 원인을 뒷받침한 후에만 구현합니다.
- 동일한 워크로드를 반복하고 중앙값, 스프레드, 꼬리 값 및 원시 아티팩트를 게시합니다.
소유권 테스트
- 관리형 스택이 많은 높은 프로세스 CPU: 애플리케이션/JIT/런타임 작업.
- P/Invoke 아래에서 높은 프로세스 CPU: 네이티브 라이브러리, 할당자, 그래픽 API 또는 드라이버 CPU.
- 차단 스택이 반복되는 낮은 CPU: 동기화, I/O, 스케줄러, 큐잉 또는 외부 종속성.
- 낮은 CPU 및 차단 스택과 함께 상승하는 ThreadPool 대기열: 기아 또는 동기-over-비동기.
- 동등한 전체 컬렉션 지점 이후 안정적인 관리형 라이브 바이트와 증가하는 비공개/RSS: 네이티브 힙, 매핑, 코드 힙, 단편화, 그래픽 리소스 또는 OS 캐시.
- 동등한 전체 컬렉션 지점 이후 증가하는 라이브 관리형 그래프: 관리형 보유 또는 의도적인 무제한 캐시.
- 긴 CPU 프레임과 짧은 GPU 타임스탬프: 애플리케이션/렌더 스레드/드라이버 CPU 바운드.
- 짧은 CPU 제출과 긴 GPU 타임스탬프: GPU 실행 바운드.
- CPU 및 GPU가 일찍 완료되지만 프레젠트가 늦음: 스왑체인, 컴포지터, vsync, 드로어블 기아 또는 디스플레이 페이싱.
- 종속 제출 간 GPU 유휴 간격: CPU 기아, 과도한 동기화, 직렬화 또는 불충분한 버퍼링.
- 온-CPU 시간이 낮은 높은 지연 시간: 오프-CPU 대기, 큐잉, 종속성, 스로틀링 또는 스케줄러 지연.
- 시작이 개선되지만 첫 번째 작업이 악화됨: 작업이 제거되지 않고 연기되었음.
- 벤치마크가 개선되지만 제품 메트릭이 개선되지 않음: 실험이 중요한 경로를 생략했거나, 잘못된 입력 분포를 사용했거나, 비지배적 작업을 최적화했음.
에이전트 운영 절차
- 저장소 빌드, 배포, 진단, 벤치마크 프로젝트, 입력 코퍼스, CI 및 아티팩트 규칙을 검사합니다.
artifacts/performance/<이슈-또는-타임스탬프>/또는 저장소에 해당하는 디렉토리를 생성합니다.- 결정론적 워크로드 드라이버와 안정적인 마커가 없으면 추가합니다.
- 명령, 환경 메타데이터, 분석기/도구 버전 및 공식 참조 링크를 아티팩트 옆에 저장합니다.
- 먼저 포괄적 비용을 분석한 다음, 배타적 비용, 호출 수신자, 대기, 큐잉, 동기화 및 소유권을 분석합니다.
- 주요 원인이 뒷받침된 후에만 코드를 수정합니다.
- 재발을 방지하는 벤치마크, 회귀 예산, 원격 측정 마커, 트레이스 레시피 또는 수명 주기 불변을 추가합니다.
- 저장소 정책이 명시적으로 저장하지 않는 한 대규모 트레이스, 캡처, 덤프 및 벤치마크 아티팩트를 Git 외부에 보관합니다.
- 해피 패스뿐만 아니라 실패, 취소, 오버로드, 정리, 장치 손실 및 종료 경로도 검증합니다.
거부해야 할 잘못된 결론
- “CPU가 높으므로 메서드 X가 느리다” — 스택 없이.
- “RSS가 증가했으므로 관리형 힙이 누수된다.”
- “GC 힙이 안정적이므로 누수가 없다.”
- “평균 지연 시간/프레임 시간이 예산 내에 있으므로 꼬리가 건강하다.”
- “GPU 사용률이 높으므로 셰이더 X가 병목이다.”
- “렌더 스레드가 바쁘므로 GPU가 바쁘다.”
- “하나의 프레임 캡처가 정상 상태 동작을 나타낸다.”
- “드로우 콜이 적을수록 항상 렌더링이 빠르다.”
- “ThreadPool 스레드를 더 추가하면 기아가 해결된다.”
- “비동기 코드는 차단할 수 없다.”
- “NativeAOT는 자동으로 더 빠르다.”
- “마이크로벤치마크 개선은 애플리케이션 개선을 증명한다.”
- “통계적으로 감지 가능한 델타는 자동으로 제품에 중요하다.”
- “하나의 벤치마크 실행이 결과를 증명한다.”
문서 각주
Footnotes
-
references/command-reference.md는 .NET 진단 도구, BenchmarkDotNet, Xcode Instruments, Windows Performance Toolkit, Linuxperf/BCC, PresentMon, RenderDoc 및 벤더 GPU 프로파일러에 대한 최신 공식 문서로 연결됩니다. ↩