/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.34
RT 선점 패치를 실행하는 듀얼 코어 ARMv7 프로세서가 있습니다 . 동시에 실시간 제어 애플리케이션을 실행하고 있습니다.
내 문제는 /proc/stat
숫자가 일치하지 않는다는 것입니다. 하지만 이것을 이해하기 위해, 나는 왜 /proc/stat
100을 넘어 셀 수 있는지 알고 싶습니다 .
편집: 스크립트에 cat /proc/uptime을 추가했습니다.
답변1
사용하는 스크립트가 주요 문제입니다. 컨텍스트 전환은 대기 시간 측면에서 매우 비용이 많이 듭니다.
sleep 1
스크립트를 잠자기 상태로 두십시오. 타이머가 완료되면 프로세스가 다시 실행 가능해지며 CPU의 다른 코어에 다시 할당될 수 있습니다(마이그레이션). 따라서 기본적으로 /proc/stat
게시물에서 말한 것처럼 정확히 1000ms마다 폴링하는 것은 아닙니다 .
그건 그렇고, 이것은 RT 코어를 평가하는 좋은 방법이 아닙니다.
sysjitter
Solarflare의 예제를 사용해 보시기 바랍니다.시스템 지터오픈로드이를 통해 커널이 어떻게 작동하는지 더 잘 알 수 있습니다.
주요 개념은 코어의 타임스탬프 카운터(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초 슬라이스의 평균 시간을 구합니다.