/proc/stat 횟수가 초당 100회를 초과하는 이유는 무엇입니까?

/proc/stat 횟수가 초당 100회를 초과하는 이유는 무엇입니까?

/proc/stat개발자가 일관되지 않게 보고된 CPU 사용량 에 대해 불만을 토로했습니다 .

내 이해는 /proc/stat틱 수를 계산하는 것입니다. 커널 2.6부터 틱 수는 100/s로 고정되었습니다.

이제 CPU1을 관찰해 보니 /proc/stat초당 100틱이 넘는 틱이 계산되는 것 같습니다. 이는 불가능합니다.

이 스크립트는 내가 계산한 방법을 보여줍니다.

cat /proc/uptime
b=`awk /cpu1/'{print $2+$3+$4+$5+$6+$7+$8+$9+$10+$11}' /proc/stat`
sleep 1
a=`awk /cpu1/'{print $2+$3+$4+$5+$6+$7+$8+$9+$10+$11}' /proc/stat`
cat /proc/uptime
expr $a - $b

출력 예

32.80 19.06
33.86 19.51
CPU1 jiffies/s 137

의 필드를 합산하고 /proc/stat잠시 기다렸다가 다시 수행합니다. 그러면 때로는 약 140의 합계 차이가 발생합니다. 꽤 안정적입니다. 어쩌면 몇 카운트 위아래로 움직일 수도 있습니다.

커널의 경우 CONFIG_HZ는 100입니다. 250이나 1000으로 컴파일하면 변화는 작지만 여전히 남아 있습니다.

사용자 공간과 여유 필드가 대부분의 시간을 차지하는 것 같습니다. 한 예에서 나는 102개의 사용자 공간 jiffies를 계산했는데, 이는 추가로 20밀리초 동안 잠을 자면 설명될 수 있습니다. 따라서 사용자 공간은 항상 점유됩니다. 그러나 완전히 예약된 CPU에서 실행되는 유휴 틱은 33개입니다.

Linux kernel 4.14.34RT 선점 패치를 실행하는 듀얼 코어 ARMv7 프로세서가 있습니다 . 동시에 실시간 제어 애플리케이션을 실행하고 있습니다.

내 문제는 /proc/stat숫자가 일치하지 않는다는 것입니다. 하지만 이것을 이해하기 위해, 나는 왜 /proc/stat100을 넘어 셀 수 있는지 알고 싶습니다 .

편집: 스크립트에 cat /proc/uptime을 추가했습니다.

답변1

사용하는 스크립트가 주요 문제입니다. 컨텍스트 전환은 대기 시간 측면에서 매우 비용이 많이 듭니다. sleep 1스크립트를 잠자기 상태로 두십시오. 타이머가 완료되면 프로세스가 다시 실행 가능해지며 CPU의 다른 코어에 다시 할당될 수 있습니다(마이그레이션). 따라서 기본적으로 /proc/stat게시물에서 말한 것처럼 정확히 1000ms마다 폴링하는 것은 아닙니다 .

그건 그렇고, 이것은 RT 코어를 평가하는 좋은 방법이 아닙니다.

sysjitterSolarflare의 예제를 사용해 보시기 바랍니다.시스템 지터오픈로드이를 통해 커널이 어떻게 작동하는지 더 잘 알 수 있습니다.

주요 개념은 코어의 타임스탬프 카운터(TSC) 레지스터를 집계하고 다음 두 값을 비교하여 코어가 실행될 때마다 어떤 일이 발생했는지 확인하는 코어(코어당 실행 스레드 1개)에 무한 루프를 고정하는 것입니다. 실행 중인 프로세스의 선점 차이(100hz로 가정)

이렇게 하면 서버의 시스템 지터를 더 잘 이해하고 이를 더 조정하기로 결정할 수 있습니다.

또한 사용 사례에 이러한 개선이 필요한 경우 CPU 격리, 애플리케이션 전용 코어 및 동적 티킹 커널 구성도 고려해야 합니다.

awk편집: 모든 요구 사항에 대해 다음과 같은 작은 스크립트를 사용하는 것이 좋습니다 .

#!/usr/bin/awk 

BEGIN { 
    sum1=0;
    sum2=0;
    result=0;
    file="/proc/stat";



while (( getline < file ) > 0 ) {
    if ($1=="cpu1"){ sum1=$2+$3+$4+$5+$6+$7+$8+$9+$10+$11 }; 
    } 
    close(file) ;
    print  "firt time " sum1;
    system("sleep 10");

while (( getline < file ) > 0 ) {
        if ($1=="cpu1") { sum2=$2+$3+$4+$5+$6+$7+$8+$9+$10+$11 }
    }
    close (file)
    print "secont time " sum2;
    result=sum2-sum1;
    print "sum is " result/10;
}

샘플링 시간은 10초 이상이며 결과를 10으로 나누어 1초 슬라이스의 평균 시간을 구합니다.

관련 정보