커널의 공통 CPU 성능 카드 포인트 인벤토리

당사의 애플리케이션은 다양한 언어, 운영 체제 커널 및 CPU와 같은 하드웨어의 런타임에서 실행됩니다. 우리는 일반적으로 개발을 위해 Go, Java 및 기타 언어를 사용합니다. 그러나 이러한 언어는 런타임, 커널 및 하드웨어와 같은 여러 계층에서 지원됩니다.

프로그램이 실행 중일 때 성능 카드가 반드시 자체 애플리케이션 코드로 인해 발생하는 것은 아닐 수 있습니다. 기본 소프트웨어의 상태가 좋지 않아 발생할 수도 있습니다. 성능 카드 포인트가 하드웨어에 나타날 수 있습니다. 우리는 프로그램 성능에 영향을 미치는 CPU 하드웨어의 주요 지표, 즉 명령당 평균 클록 사이클 수, CPI 및 캐시 적중률에 대해 배웠습니다. 성능 카드 포인트는 커널 소프트웨어에도 나타날 수 있습니다. 오늘 우리는 프로그램의 성능에 영향을 미칠 수 있는 커널에 존재하는 몇 가지 주요 지표를 살펴보겠습니다.

실제로 커널 개발자는 커널 실행 중에 상대적으로 높은 오버헤드가 무엇인지도 알고 있습니다. 그래서 우리는 오랫동안 소프트웨어 성능 이벤트라는 지원을 제공했습니다. 애플리케이션 개발자가 이러한 이벤트의 발생 횟수와 발생 시 트리거되는 함수 호출 체인을 관찰하는 것이 편리합니다.

 

1. 소프트웨어 성능 이벤트 목록

perf의 list 하위 명령을 통해 현재 시스템이 지원하는 소프트웨어 성능 이벤트를 볼 수 있습니다.

# perf list sw
List of pre-defined events (to be used in -e):
  alignment-faults                                   [Software event]
  context-switches OR cs                             [Software event]
  cpu-migrations OR migrations                       [Software event]
  emulation-faults                                   [Software event]
  major-faults                                       [Software event]
  minor-faults                                       [Software event]
  page-faults OR faults                              [Software event]
  task-clock                                         [Software event]

그 중 위 명령어에서 sw는 software의 약자로 실제로는 커널을 가리킨다. 다음 목록에는 성능에 영향을 미치는 몇 가지 이벤트가 나열되어 있으며 하나씩 설명하겠습니다.

정렬 오류

이는 정렬 예외를 나타냅니다. 간단히 말해서, CPU가 메모리 주소에 액세스할 때 액세스된 주소가 잘못 정렬된 것으로 확인되면 커널이 메모리에서 데이터를 요청할 때 하나의 IO가 충분하지 않을 수 있으며 다른 IO를 트리거하여 데이터를 다시 읽어야 합니다. . 정렬 예외는 불필요한 메모리 IO를 증가시켜 필연적으로 프로그램의 성능을 저하시킵니다.

그래도 이해가 안 되시면 아래 그림을 보시면 됩니다. 아래 그림에서 주소 0-63 및 64-127의 데이터는 하나의 메모리 IO로 완료될 수 있습니다. 그러나 응용 프로그램이 40 위치에서 64 데이터 길이로 시작해야 하는 경우. 그것은 정렬 불량입니다.

컨텍스트 스위치

프로세스 컨텍스트 전환. 평균적으로 각 스위치는 3-5us가 걸립니다. 이것은 빠르게 실행되는 운영 체제의 경우 이미 매우 긴 시간이며 더 중요한 것은 사용자 프로그램의 경우 이 시간이 완전히 낭비된다는 것입니다. 빈번한 컨텍스트 전환은 CPU 캐시 적중률을 저하시키고 CPI를 증가시킵니다.

CPU 마이그레이션

프로세스가 예약될 때마다 동일한 CPU 코어에서 실행될 수 있다면 이 코어의 L1, L2, L3 및 기타 캐시에 저장된 데이터를 계속 사용할 가능성이 높습니다. 데이터에 대한 액세스를 피하십시오. 너무 느린 메모리에 침투하십시오. 따라서 커널은 스케줄러 구현에서 가능한 한 마지막으로 사용된 코어를 스케줄링에 사용하도록 하기 위해 wake_affine 메커니즘을 개발했습니다.

그러나 프로세스가 스케줄러가 깨어날 때 마지막으로 사용된 코어가 다른 프로세스에 의해 점유된 것을 발견하면 어떻게 됩니까? 이 프로세스가 깨어나는 것을 막고 마지막으로 사용된 CPU 코어를 기다리는 것은 불가능합니다. 프로세스가 적시에 CPU를 얻을 수 있도록 다른 코어를 할당하는 것이 더 나을 수 있습니다. 하지만 이때 실행 중에 프로세스가 CPU 사이를 건너뛰게 되는데, 이러한 현상을 작업 마이그레이션이라고 합니다.

분명히 작업 마이그레이션은 CPU 캐시에 그다지 우호적이지 않습니다. 마이그레이션이 너무 많으면 필연적으로 프로세스 성능이 저하됩니다.

에뮬레이션 오류

에뮬레이션 오류는 QEMU 가상 머신에서 x86 애플리케이션을 실행할 때 발생하는 오류 유형입니다. x86 프로그램은 x86 아키텍처 컴퓨터에서 실행되어야 하며 컴퓨터의 하드웨어 아키텍처 및 명령어 집합에 따라 달라집니다. 에뮬레이터로서 QEMU는 x86 하드웨어 아키텍처 및 명령어 세트를 에뮬레이션할 수 있지만 에뮬레이터와 실제 하드웨어 간의 차이로 인해 x86 응용 프로그램을 실행할 때 에뮬레이션 오류가 발생할 수 있습니다.

페이지 오류

이것은 우리가 종종 페이지 폴트라고 부르는 것입니다. 사용자 프로세스에서 메모리를 신청할 때 실제로 적용되는 것은 주소 범위인 vm_area_struct뿐이다. 물리적 메모리는 즉시 할당되지 않으며 특정 할당은 실제 액세스까지 대기합니다. 프로세스가 실행 중에 스택에 변수를 할당하고 액세스하기 시작할 때 물리적 페이지가 할당되지 않은 경우 페이지 폴트 인터럽트가 트리거됩니다. 실제 메모리는 페이지 폴트 인터럽트에서 실제로 할당됩니다.

페이지 폴트에는 메이저 폴트와 마이너 폴트의 두 가지 유형이 있습니다. 이 두 가지 유형의 오류의 차이점은 주요 오류로 인해 디스크 IO가 발생하므로 프로그램 실행에 더 큰 영향을 미친다는 것입니다.

2. 소프트웨어 성능 이벤트 통계 집계

프로그램의 성능에 영향을 줄 수 있는 커널의 여러 이벤트를 이해한 후에 우리가 필요로 하는 것 중 하나는 이러한 이벤트가 시스템에서 실제로 몇 번 발생하는지 확인하는 것입니다. 이는 perf stat 하위 명령을 사용하여 수행할 수 있습니다.

# perf stat -e alignment-faults,context-switches,cpu-migrations,emulation-faults,page-faults,major-faults,minor-faults sleep 5
 Performance counter stats for 'sleep 5':
     0      alignment-faults:u
     0      context-switches:u
     0      cpu-migrations:u
     0      emulation-faults:u
    56      page-faults:u
     0      major-faults:u
    56      minor-faults:u

위의 명령어를 개발용 머신에서 직접 실행해보니 0인 지표가 많았고, 심각하지 않은 마이너 폴트만 56건 발생했다. 이 명령은 전체 시스템의 통계입니다.

지정된 프로그램이나 프로세스만 보려면 프로그램 이름을 따르거나 -p로 프로세스 pid를 지정하십시오.

# perf stat <可执行程序>   // 统计指定程序
# perf stat -p <pid>     // 统计指定进程

 기차를 통한 정보: Linux 커널 소스 코드 기술 학습 경로 + 비디오 튜토리얼 커널 소스 코드

학습을 통한 학습: Linux 커널 소스 코드 메모리 튜닝 파일 시스템 프로세스 관리 장치 드라이버/네트워크 프로토콜 스택

3. 소프트웨어 성능 이벤트의 함수 스택 추적

시스템에 지표가 너무 많다는 사실을 알게 되더라도 어떤 함수 호출 체인이 원인인지 확인하고 싶을 가능성이 큽니다. 이때 perf record 명령은 스택을 샘플링하는 데 도움이 될 수 있습니다.

예를 들어 컨텍스트 스위치가 작동하는 방식을 보려면 샘플을 가져옵니다.

# perf record -a -g -e context-switches sleep 30

위 명령에서 -a는 사용자 스택과 커널 스택을 포함한 모든 스택을 보는 것을 의미합니다. -g는 샘플링 시 현재 실행 중인 함수의 이름을 기록할 뿐만 아니라 전체 호출 체인을 기록한다는 의미입니다. -e는 컨텍스트 스위치 이벤트만 샘플링하는 것을 의미합니다. sleep은 30초 동안의 획득을 의미합니다. 명령이 실행된 후 perf.data 파일이 현재 디렉터리에 출력됩니다.

기본적으로 perf stat는 초당 4000회 수집합니다. 이로 인해 수집된 perf.data 파일이 너무 커지고 프로그램 성능에도 영향을 미칩니다. -F 매개변수를 사용하여 수집 빈도를 제어할 수 있습니다.

# perf record -F 100 ...

perf.data 파일의 내용을 보려면 perf 스크립트를 사용하십시오.

# perf script

간단한 통계를 위해 perf 보고서 명령을 사용할 수도 있습니다.

# perf report

가장 좋은 방법은 Brendan Gregg의 FlameGraph 프로젝트를 사용하여 샘플링된 perf.data를 매우 직관적인 불꽃 그래프로 렌더링하는 것입니다.

생성 방법은 매우 간단하여 FlameGraph 프로젝트를 다운로드한 다음 stackcollapse-perf.pl 및 flamegraph.pl 스크립트를 사용하여 처리하기만 하면 됩니다.

# git clone https://github.com/brendangregg/FlameGraph.git
# perf script | ./FlameGraph/stackcollapse-perf.pl | ./FlameGraph/flamegraph.pl > out.svg

stackcollapse-perf.pl 스크립트의 기능은 호출 스택을 한 줄로 처리하는 것입니다. 줄의 앞부분은 호출 스택을 나타내고 줄 뒤의 출력은 함수가 실행되도록 샘플링된 횟수입니다. 예를 들어, 다음 처리 결과는 샘플링 동안 main;funcA;funcD;funcE;caculate 함수 호출 링크가 554118432회 실행되고, main;funcB;caculate 함수 호출 링크가 338716787회 실행됨을 나타냅니다.

main;funcA;funcD;funcE;caculate 554118432
main;funcB;caculate 338716787

flamegraph.pl 스크립트는 stackcollapse-perf.pl을 svg 이미지로 그리는 방식으로 작동합니다.

Flame 그래프를 사용하여 컨텍스트 전환 커널 소프트웨어 이벤트 샘플링 결과 perf.data를 렌더링한 후 컨텍스트 전환이 가장 자주 발생하는 링크를 명확하게 확인할 수 있습니다.

플레임 그래프를 관찰하면 프로세스 컨텍스트 스위칭 오버헤드가 가장 많이 발생하는 원인을 분석하고 찾을 수 있습니다. 페이지 오류 중단 및 CPU 마이그레이션과 같은 다른 커널 소프트웨어 이벤트의 분석 원칙도 동일합니다.

 

Supongo que te gusta

Origin blog.csdn.net/youzhangjing_/article/details/131381446
Recomendado
Clasificación