성능 프로파일러에서 CPU 프로파일링을 사용하여 성능 분석(C#, Visual Basic, C++, F#)

앱의 성능 문제를 조사하기 위한 좋은 방법은 CPU 프로파일러를 사용하여 CPU 사용량을 이해하는 것입니다. CPU 사용량 성능 도구는 C++, C#/Visual Basic에서 코드 실행에 소요된 CPU 시간 및 백분율을 보여줍니다.

CPU 사용량 도구를 사용하면 다음을 수행할 수 있습니다.

  • 팀의 코드베이스에서 속도 저하 또는 프로세스 중단을 진단합니다. 이 도구는 팀의 프로덕션 코드에서 문제를 진단하는 데 도움이 될 수 있습니다. 이 도구는 성능 문제를 분석하고 진단할 수 있도록 데이터의 자동 인사이트와 다양한 보기를 제공합니다.

  • 고객이 성수기 동안 일부 요청 또는 주문이 소매 웹 사이트로 전송되지 않는다고 보고하는 경우와 같은 DevOps 시나리오에서 성능 문제를 식별합니다. 프로덕션 환경에서는 종종 문제가 있으며 해당 시점에서 디버그하기는 어렵지만 이 도구를 사용하면 문제의 충분한 정보와 증거를 캡처하는 데 도움이 될 수 있습니다. 추적 파일을 수집한 후 분석을 통해 잠재적인 원인을 빠르게 파악하고 코드 컨텍스트 내에서 제안 사항을 제공하여 다음 단계를 수행하여 문제를 해결할 수 있습니다.

  • API 요청에 대기 시간 문제가 없는 경우 높은 CPU 사용률 및 기타 CPU 사용량 도구와 관련된 문제를 확인할 수 있습니다. CPU 사용량 도구를 사용하면 병목 상태를 식별하여 최적화할 위치를 좁힐 수 있습니다.

CPU 사용량 도구는 로컬 추적 세션과 프로덕션 모두에 유용합니다. 또한 CPU 사용량 도구는 바로 가기 키 Alt+F2를 사용한 다음 CPU 사용량을 선택하거나 dotnet-trace 또는 dotnet-monitor와 같은 도구를 사용하여 이미 수집된 추적을 열어 시작할 수도 있습니다. (.NET 프로덕션 코드의 경우 이러한 방법으로 추적을 수집할 가능성이 가장 높습니다.)

CPU 사용량 도구는 열려 있는 Visual Studio 프로젝트, 설치된 Microsoft Store 앱에서 실행하거나 실행 중인 앱 또는 프로세스에 연결할 수 있습니다. 디버깅을 사용하거나 사용하지 않고 CPU 사용량 도구를 실행할 수 있습니다. 자세한 내용은 디버거를 사용하거나 사용하지 않고 프로파일링 도구 실행을 참조하세요.

다음 지침은 Visual Studio 성능 프로파일러를 사용하여 디버거 없이 CPU 사용량 도구를 사용하는 방법을 보여줍니다. 이 예제에서는 로컬 머신에서 릴리스 빌드를 사용합니다. 릴리스 빌드는 실제 앱 성능을 가장 잘 보여줍니다. CPU 사용량 도구를 사용하여 성능을 향상시키는 방법을 보여 주는 자습서는 코드 최적화에 대한 초보자 가이드를 참조하세요.

일반적으로 로컬 머신은 설치된 앱 실행을 가장 잘 복제합니다. 원격 디바이스에서 데이터를 수집하려면 원격 데스크톱 연결을 통하지 않고 디바이스에서 직접 앱을 실행합니다.

CPU 사용량 데이터 컬렉션

  1. Visual Studio 프로젝트에서 솔루션 구성을 릴리스로 설정하고 로컬 Windows 디버거(또는 로컬 머신)를 배포 대상으로 선택합니다.

    릴리스 및 로컬 컴퓨터 선택을 보여 주는 스크린샷.

    릴리스 및 로컬 컴퓨터 선택을 보여 주는 스크린샷.

  2. 디버그>성능 프로파일러를 선택합니다.

  3. 사용 가능한 도구에서 CPU 사용량을 선택한 다음, 시작을 선택합니다.

    CPU 사용량 선택을 보여 주는 스크린샷.

    CPU 사용량 선택을 보여 주는 스크린샷.

    프로파일러를 시작하기 전에 컬렉션 일시 중지로 시작 옵션을 사용하도록 설정하면 진단 세션 보기에서 레코드 단추를 선택할 때까지 데이터가 수집되지 않습니다.

    참고 항목

    도구를 보다 효율적으로 만드는 방법에 대한 자세한 내용은 프로파일러 설정 최적화를 참조하세요.

  4. 앱이 시작되면 진단 세션이 시작되고 CPU 사용량 데이터가 표시됩니다. 데이터 수집이 완료되면 컬렉션 중지를 선택합니다.

    CPU 사용량 데이터 수집 중지를 보여 주는 스크린샷.

    CPU 사용량 데이터 수집 중지를 보여 주는 스크린샷.

    CPU 사용량 도구에서 데이터를 분석하고 보고서를 표시합니다. 데이터를 수집하거나 표시하는 데 문제가 있는 경우 프로파일링 오류 문제 해결 및 문제 해결을 참조하세요.

    CPU 사용량 보고서를 보여 주는 스크린샷.

    CPU 사용량 보고서를 보여 주는 스크린샷.

    필터 드롭다운을 사용하여 표시할 스레드를 선택하거나 선택 취소하고, 검색 상자를 사용하여 특정 스레드 또는 노드를 검색합니다.

CPU 사용량 데이터 열

속성 설명
총 CPU [단위, %] 총 % 데이터 수식

선택한 시간 범위에서 함수 호출 및 함수가 호출한 함수에 의해 사용되는 밀리초 및 CPU 백분율입니다. 이 값은 시간 범위의 총 CPU 활동을 사용 가능한 총 CPU와 비교하는 CPU 사용률 타임라인 그래프와 다릅니다.
셀프 CPU [단위, %] 자체 % 수식

함수에 의해 호출되는 함수를 제외하고 선택한 시간 범위에서 함수를 호출하는 데 사용되는 밀리초 및 CPU 백분율입니다.
모듈 일부 뷰에서는 모듈 열이 표시되어 함수가 포함된 모듈의 이름을 보여줍니다.

CPU 인사이트 분석

상위 인사이트, 상위 함수 및 실행 부하 과다 경로를 분석하려면 CPU 인사이트를 참조하세요.

CPU 사용량 분석

CPU 사용량 보고서를 분석하려면 세부 정보 열기를 클릭하거나 상위 함수 중 하나를 클릭하여 함수 뷰를 엽니다.

이 보고서는 진단 데이터에 대한 다양한 보기를 제공합니다.

  • 호출자/호출 수신자
  • 호출 트리
  • 모듈
  • Functions
  • 플레임 그래프

보고서를 분석하려면 자세한 보고서 만들기를 클릭합니다.

이 보고서는 진단 데이터에 대한 다양한 보기를 제공합니다.

  • 호출자/호출 수신자
  • 호출 트리

호출자/호출 수신자를 제외한 모든 뷰에서 진단 보고서는 총 CPU를 기준으로 내림차순으로 정렬됩니다. 열 머리글을 선택하여 정렬 순서 또는 정렬 열을 변경합니다. 관심이 있는 함수를 두 번 클릭하면 함수의 원본 및 해당 함수에서 소요된 시간을 보여 주는 강조 표시가 표시됩니다. 이 표에는 호출된 함수(총 CPU)를 포함하여 함수에서 소요된 시간과 같은 데이터가 포함된 열과 호출된 함수(자체 CPU)를 제외한 함수에서 소요된 시간을 보여 주는 두 번째 열이 표시됩니다.

이 데이터를 사용하여 함수 자체에 성능 병목 현상이 있는지 여부를 평가할 수 있습니다. 메서드가 표시하는 데이터의 양을 결정하여 타사 코드 또는 런타임 라이브러리가 엔드포인트가 느리거나 리소스 사용량이 많은 이유인지 확인합니다.

플레임 그래프 사용에 대한 자세한 내용은 플레임 그래프를 사용하여 실행 부하 과다 경로 식별을 참조하세요.

CPU 사용량 호출 트리

호출 트리를 보려면 보고서에서 부모 노드를 선택합니다. 기본적으로 CPU 사용량 페이지는 호출자/호출 수신자 뷰에 열립니다. 현재 보기 드롭다운 목록에서 호출 트리를 선택합니다.

실행 부하 과다 경로 확장실행 부하 과다 경로 표시 단추를 클릭하여 호출 트리 뷰에서 CPU 사용률이 가장 높은 함수 호출을 볼 수 있습니다.

호출 트리 구조

호출 트리 구조를 보여 주는 스크린샷.

호출 트리 구조를 보여 주는 스크린샷.

이미지 설명
1단계 CPU 사용량 호출 트리의 최상위 노드는 의사 노드입니다.
2단계 대다수의 앱에서 외부 코드 표시 옵션을 사용하지 않도록 설정한 경우 두 번째 수준 노드가 [External Code] 노드입니다. 노드에는 앱 시작 및 중지, UI 그리기, 스레드 일정 제어 및 앱에 기타 낮은 수준 서비스를 제공하는 시스템과 프레임워크 코드가 포함되어 있습니다.
3단계 두 번째 수준 노드의 자식은 두 번째 수준 시스템과 프레임워크 코드가 호출하거나 만드는 사용자 코드 메서드 및 비동기 루틴입니다.
4단계 메서드의 자식 노드에는 부모 메서드 호출에 대한 데이터만 있습니다. 외부 코드 표시 가 사용하지 않도록 설정되어 있으면 앱 메서드에 [External Code] 노드를 포함할 수 있습니다.

외부 코드

코드로 실행되는 시스템과 프레임워크 함수를 외부 코드라고 합니다. 외부 코드 함수는 앱 시작 및 중지, UI 그리기, 스레딩 제어, 기타 낮은 수준 서비스를 앱에 제공합니다. 대부분의 경우 외부 코드에 관심이 없으므로 CPU 사용량 호출 트리에서 사용자 메서드의 외부 함수를 하나의 [External Code] 노드로 수집합니다.

외부 코드의 호출 경로를 보려면 현재 보기를 호출 트리 보기로 전환하거나 마우스 오른쪽 단추를 클릭하고 호출 트리에서 보기를 선택합니다.

호출 트리에 표시를 보여 주는 스크린샷.

외부 코드의 호출 경로를 보려면 기본 진단 보고서 페이지(오른쪽 창)의 필터 드롭다운에서 외부 코드 표시를 선택한 다음, 적용을 선택합니다. CPU 사용량 페이지의 호출 트리 보기와 외부 코드 호출을 확장합니다. (필터 드롭다운은 자세한 보기가 아닌 기본 진단 페이지에서 사용할 수 있습니다.)

외부 코드 표시를 보여 주는 스크린샷.

여러 외부 코드 호출 체인은 깊이 중첩되어 있으므로 체인 너비가 함수 이름 열의 표시 너비를 초과할 수 있습니다. 그러면 함수 이름이 다음 이미지와 같이 표시됩니다.

호출 트리에서 중첩된 외부 코드를 보여 주는 스크린샷.

여러 외부 코드 호출 체인은 깊이 중첩되어 있으므로 체인 너비가 함수 이름 열의 표시 너비를 초과할 수 있습니다. 그러면 함수 이름이 ... 로 나타납니다.

호출 트리에서 중첩된 외부 코드를 보여 주는 스크린샷.

찾고자 하는 함수 이름을 찾으려면 검색 상자를 사용합니다. 선택한 줄 위로 마우스를 가져가거나 가로 스크롤 막대를 사용하여 데이터를 봅니다.

중첩된 외부 코드 검색을 보여 주는 스크린샷.

중첩된 외부 코드 검색을 보여 주는 스크린샷.

CPU 사용량 호출 트리의 비동기 함수

컴파일러에서 비동기 메서드가 발생하면 메서드 실행을 제어하는 숨겨진 클래스를 만듭니다. 개념적으로 클래스는 상태 머신입니다. 클래스에 원래 메서드를 비동기식으로 호출하는 컴파일러 생성 함수와 이를 실행하는 데 필요한 콜백, 스케줄러 및 반복기가 있습니다. 부모 메서드가 원래 메서드를 호출하면 컴파일러는 부모의 실행 컨텍스트에서 메서드를 제거하고, 앱 실행을 제어하는 시스템과 프레임워크 코드의 컨텍스트에서 숨겨진 클래스 메서드를 실행합니다. 비동기 메서드는 일반적으로 하나 이상의 서로 다른 스레드에서 실행되지만 항상 그렇지는 않습니다. 이 코드는 트리의 상단 노드 바로 아래의 [External Code] 노드의 자식으로 CPU 사용량 호출 트리에 나타납니다.

다음 예제에서 [External Code] 아래에 있는 처음 두 노드는 상태 시스템 클래스의 컴파일러 생성 메서드입니다. 세 번째 노드는 원래 메서드에 대한 호출입니다.

비동기 노드를 보여주는 스크린샷.

생성된 메서드를 확장하면 진행 상황이 표시됩니다.

확장된 비동기 노드를 보여주는 스크린샷.

확장된 비동기 노드를 보여주는 스크린샷.

  • MainPage::GetMaxNumberAsyncButton_Click은 작업 값 목록을 관리하고, 결과의 최댓값을 계산하고, 출력을 표시합니다.

  • MainPage+<GetMaxNumberAsyncButton_Click>d__3::MoveNextGetNumberAsync에 대한 호출을 래핑하는 48개 작업을 예약 및 시작하는 데 필요한 활동을 보여 줍니다.

  • MainPage::<GetNumberAsync>b__bGetNumber를 호출하는 작업의 활동을 보여줍니다.

호출 수 수집(.NET)

함수 보기에서 호출 수를 보려면 프로파일러를 시작하기 전에 설정을 사용하도록 설정할 수 있습니다. 이 설정은 .NET 프로젝트 형식에 대해 지원되며 프로파일러에서 프로세스를 시작해야 합니다. 연결 시나리오는 지원되지 않습니다.

  1. 성능 프로파일러에서 CPU 사용량에 대한 설정 아이콘을 선택합니다.

    CPU 사용량에 대한 설정 아이콘을 보여 주는 스크린샷.

  2. 호출 수 수집(.NET에만 해당) 옵션을 사용하도록 설정합니다.

    CPU 사용량에 대한 설정을 보여 주는 스크린샷.

  3. CPU 사용량 데이터를 수집합니다.

  4. 함수 보기를 연 다음 호출 개수 열이 표시되도록 설정되어 있는지 확인합니다.

    열이 표시되지 않으면 열 머리글을 마우스 오른쪽 단추로 클릭하여 표시되는 열을 선택합니다.

    호출 수 데이터를 보여 주는 스크린샷.