내 기본 가정은 프로세스의 제한 요소가 디스크와 CPU 인 경우 총 시스템 "iowait"+ CPU 사용량은 하나의 논리 CPU의 100 % 이상이어야한다는 것입니다. (다른 경우에는 유지되지 않습니다. 예를 들어를 사용하여 파일을 다운로드 할 때 wget네트워크가 종종 제한 요소입니다).
이 가정은 간단한 테스트로 위반됩니다. 이것이 예상됩니까? 이 예상되는 경우, 나는 일련의 조건이 해야 내 가정이 성립 기대는?
여기에 "iowait"에 대한 배경이 있습니다 : CPU는 IO 보류가 있는지 어떻게 알 수 있습니까? 여기에 대한 답변은 반 직관적 인 아이디어를 인용하며, 누적 된 iowait는 "특정 조건에서 감소 할 수 있습니다". 간단한 테스트가 문서화되지 않은 조건을 트리거 할 수 있는지 궁금합니다.
업데이트 : 답변으로 건너 뛰십시오 .
대답은 원래 사용했던 것보다 간단한 테스트를 거쳤습니다. 아래의 원래 질문을 유지했습니다. 원래 질문에는 몇 가지 추가 세부 사항이 표시 될 수 있습니다.
원래 질문
간단한 테스트 dd에서 커널에 임의 바이트를 생성하여 파일에 쓰도록 요청합니다. 커널 내에서 보낸 CPU 시간 수를 얻기 위해 ddinside 명령을 실행합니다 perf stat. 또한 내부 perf trace -s에서 보낸 시간을보고하기 위해 내부 에서 실행합니다 write(). 동시에, 나는 vmstat 5"iowait"시스템을보기 위해 다른 터미널에서 실행 합니다.
- 나는 적어도 하나의 전체 CPU를 "유휴 상태가 아닌"것으로 볼 것으로 예상했다. 즉, 100 %는 실행 중이거나 정지되었지만 IO ( "iowait"상태)를 기다리는 시간이다. 아니었다.
- (또한 "iowait"시간이 write ()에 소비 된 시간과 거의 일치 할 것으로 예상했지만 그렇게하지는 않았습니다.)
자세한 결과 및 테스트 환경은 다음과 같습니다. 또한 내 가정이 채택한 대체 테스트도 나와 있습니다. 참고 : 다른 방법이 아닌 perf stat내부 를 실행해야했습니다 perf trace. 이 여기에 자세히 설명되어 있습니다 합니까 "반환 한 통계"(그리고 "시간"!) "트레이스를 규칙적 -의"실행할 때 잘못된 결과를 보여?
"iowait"에 대한 배경 정보
다음은
sar맨 페이지 에서 가져온 정의입니다 .% iowait :
시스템에 미해결 디스크 I / O 요청이있는 동안 CPU가 유휴 상태 인 시간의 백분율입니다.
따라서 % iowait는 CPU 관점에서 실행할 수있는 작업이 없지만 하나 이상의 I / O가 진행 중임을 의미합니다. iowait는 예약 할 수없는 유휴 시간의 한 형태입니다. 이 값은 성능 문제를 나타내는 데 유용하거나 유용하지 않을 수 있지만 사용자에게 시스템이 유휴 상태이고 더 많은 작업을 수행 할 수 있음을 알려줍니다.
https://support.hpe.com/hpsc/doc/public/display?docId=c02783994
더 긴 기사 : I / O 대기 이해 (또는 0 % 유휴 상태가 양호한 이유)도 있습니다. 커널 코드에서 정의를 명확하게 볼 수있는 방법에 대해 설명합니다. 코드가 약간 변경되었지만 아이디어는 여전히 명확합니다.
/*
* Account for idle time.
* @cputime: the CPU time spent in idle wait
*/
void account_idle_time(u64 cputime)
{
u64 *cpustat = kcpustat_this_cpu->cpustat;
struct rq *rq = this_rq();
if (atomic_read(&rq->nr_iowait) > 0)
cpustat[CPUTIME_IOWAIT] += cputime;
else
cpustat[CPUTIME_IDLE] += cputime;
}
이 기사는 또한 단일 CPU 시스템에 대한 여러 관련 실험을 보여줍니다. 일부 실험 dd은 if=/dev/urandom ! 그러나 실험에는 내 테스트가 포함되어 있지 않습니다 dd if=/dev/urandom of=test.out . 만 사용합니다 dd if=/dev/urandom of=/dev/null .
"IO wait"는 멀티 CPU 시스템을 사용하기 때문에 지금 생각하기가 조금 까다 롭지 만 인용 코드를 기반으로 여전히 이해하고 있다고 생각합니다.
환경
4 개의 논리 CPU가 있습니다.
LVM과 ext4 파일 시스템을 사용합니다. 디스크 나 파일 시스템에서 암호화를 사용하지 않습니다. 네트워크 파일 시스템이 전혀 마운트되어 있지 않으므로 네트워크 파일 시스템을 읽거나 쓰지 않습니다.
아래 결과 4.20.15-200.fc29.x86_64는 noopIO 스케줄러를 사용하여 커널에서 얻은 것 입니다. cfqIO 스케줄러도 유사한 결과를 제공합니다.
(또한 비슷한 구성을 기반으로하지만 커널 버전 5.1에 더 가깝고을 사용하는 커널 빌드에서 비슷한 결과를 보았습니다 mq-deadline. 그래서 새 blk-mq코드를 사용했습니다 ).
테스트 및 결과
$ sudo perf trace -s \
perf stat \
dd if=/dev/urandom of=test.out bs=1M oflag=direct count=3000
3000+0 records in
3000+0 records out
3145728000 bytes (3.1 GB, 2.9 GiB) copied, 31.397 s, 100 MB/s
Performance counter stats for 'dd if=/dev/urandom of=test.out bs=1M oflag=direct count=3000':
18,014.26 msec task-clock # 0.574 CPUs utilized
3,199 context-switches # 0.178 K/sec
4 cpu-migrations # 0.000 K/sec
328 page-faults # 0.018 K/sec
45,232,163,658 cycles # 2.511 GHz
74,538,278,379 instructions # 1.65 insn per cycle
4,372,725,344 branches # 242.737 M/sec
4,650,429 branch-misses # 0.11% of all branches
31.398466725 seconds time elapsed
0.006966000 seconds user
17.910332000 seconds sys
Summary of events:
...
dd (4620), 12156 events, 12.0%
syscall calls total min avg max stddev
(msec) (msec) (msec) (msec) (%)
--------------- -------- --------- --------- --------- --------- ------
read 3007 17624.985 0.002 5.861 12.345 0.21%
write 3003 13722.837 0.004 4.570 179.928 2.63%
openat 12 0.371 0.002 0.031 0.267 70.36%
...
iowait의 wa열 에서 그림을 읽었습니다 vmstat. io열 을 보면 테스트가 언제 실행되는지 알 수 있습니다 ( bo= 1K 블록 출력).
$ vmstat 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 5126892 176512 1486060 0 0 1788 4072 321 414 4 4 83 9 0
1 0 0 5126632 176520 1485988 0 0 0 7 212 405 0 1 99 0 0
0 0 0 5126884 176520 1485988 0 0 0 0 130 283 0 0 99 0 0
0 0 0 5126948 176520 1485908 0 0 0 1 157 325 0 0 99 0 0
0 0 0 5126412 176520 1486412 0 0 115 0 141 284 0 0 99 0 0
0 2 0 5115724 176548 1487056 0 0 0 6019 18737 10733 3 6 89 2 0
1 0 0 5115708 176580 1487104 0 0 3 91840 1276 990 0 13 77 9 0
1 0 0 5115204 176600 1487128 0 0 2 91382 1382 1014 0 14 81 4 0
1 0 0 5115268 176636 1487084 0 0 4 88281 1257 901 0 14 83 3 0
0 1 0 5113504 177028 1487764 0 0 77 92596 1374 1111 0 15 83 2 0
1 0 0 5114008 177036 1487768 0 0 0 113282 1460 1060 0 16 81 2 0
1 0 0 5113472 177044 1487792 0 0 0 110821 1489 1118 0 16 74 10 0
0 0 0 5123852 177068 1487896 0 0 0 20537 631 714 1 3 94 2 0
0 0 0 5123852 177076 1487856 0 0 0 10 324 529 2 1 98 0 0
2 0 0 5123852 177084 1487872 0 0 0 70 150 299 0 0 99 0 0
VM 내부에서 보유한 테스트 결과
커널을 실행하고 (따라서 blk-mq)를 5.0.9-301.fc30.x86_64사용 하는 1 CPU의 VM에서 동일한 테스트를 시도했습니다 mq-deadline. 이 테스트에서는 예상대로 작동했습니다.
$ sudo perf trace -s \
perf stat \
dd if=/dev/urandom of=test.out bs=1M oflag=direct count=3000
[sudo] password for alan-sysop:
3000+0 records in
3000+0 records out
3145728000 bytes (3.1 GB, 2.9 GiB) copied, 46.8071 s, 67.2 MB/s
Performance counter stats for 'dd if=/dev/urandom of=test.out bs=1M oflag=direct count=3000':
18,734.89 msec task-clock # 0.400 CPUs utilized
16,690 context-switches # 0.891 K/sec
0 cpu-migrations # 0.000 K/sec
328 page-faults # 0.018 K/sec
<not supported> cycles
<not supported> instructions
<not supported> branches
<not supported> branch-misses
46.820355993 seconds time elapsed
0.011840000 seconds user
18.531449000 seconds sys
Summary of events:
...
dd (1492), 12156 events, 38.4%
syscall calls total min avg max stddev
(msec) (msec) (msec) (msec) (%)
--------------- -------- --------- --------- --------- --------- ------
write 3003 28269.070 0.019 9.414 5764.657 22.39%
read 3007 18371.469 0.013 6.110 14.848 0.53%
execve 6 10.399 0.012 1.733 10.328 99.18%
...
출력 vmstat 5:
$ vmstat 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 726176 52128 498508 0 0 2040 231 236 731 7 5 77 11 0
0 0 0 726176 52136 498508 0 0 0 10 25 46 0 0 99 1 0
0 0 0 726208 52136 498508 0 0 0 0 29 56 0 0 100 0 0
0 1 0 702280 55944 511780 0 0 2260 13109 4399 9049 3 17 55 25 0
0 1 0 701776 56040 511960 0 0 18 129582 1406 1458 0 73 0 27 0
0 2 0 701524 56156 512168 0 0 22 87060 960 991 0 50 0 50 0
3 1 0 701524 56228 512328 0 0 14 118170 1301 1322 0 68 0 32 0
1 1 0 701272 56260 512392 0 0 6 86426 994 982 0 53 0 46 0
0 2 0 701020 56292 512456 0 0 6 56115 683 660 0 37 0 63 0
3 2 0 700540 56316 512504 0 0 5 33450 446 457 0 26 0 74 0
0 2 0 700860 56332 512536 0 0 3 16998 311 240 0 19 0 81 0
1 2 0 700668 56368 512616 0 0 7 32563 443 428 0 24 0 76 0
1 0 0 700668 56392 512648 0 0 3 20338 245 272 0 12 0 88 0
0 1 0 707096 56408 512920 0 0 54 20913 312 530 0 12 79 8 0
0 0 0 707064 56432 512920 0 0 0 49 39 64 0 0 45 55 0
0 0 0 707064 56432 512920 0 0 0 0 24 46 0 0 100 0 0
0 0 0 707064 56432 512920 0 0 0 80 28 47 0 0 100 0 0
VM에 CPU를 추가하고 다시 테스트했습니다. 결과는 가변적입니다. 때로는 유휴 열에서 약 0 %를 보여 주었고 때로는 유휴 상태 (약 두 CPU 중 하나)에서 약 50 %를 보였습니다. 0 % "idle"의 경우 "iowait"는 매우 높았습니다 (예 : 하나 이상의 CPU 가치). 즉 내 기대 지점 2가 올바르지 않습니다. 다중 CPU 시스템에서 이러한 "iowait"의 명백한 한계를 확실하게 수용 할 수 있습니다. (나는 그것을 이해하지 못하지만. 누군가 그것을 정확하게 설명하고 싶다면, 그것은 좋을 것입니다). 그러나 "유휴"는 두 경우 모두 50 %를 넘지 않았으므로 이러한 테스트는 여전히 "iowait"에 대한 나의 첫 가정과 일치했습니다.
VM을 종료하고 4 개의 CPU로 시작했습니다. 마찬가지로, 종종 유휴 상태가 정확히 75 %이고 때로는 유휴 상태가 50 %에 불과하지만 유휴 상태가 75 %를 넘지 않았습니다 (예 : 4 개의 CPU 중 3 개 이상).
CPU가 4 개인 실제 시스템에서 위와 같이 80 % 이상의 유휴 결과를 여전히 재현 할 수 있습니다.
this_rq()->nr_iowait 사용중인 작업 수를 생각 io_schedule() 합니다 . 내가 잘못?
iowait
atop또는 을 실행 atopsar -c 5하면 CPU 별 사용량 수치가 표시됩니다. 여기에는 iowait가 포함되며 CPU 별 iowait 수치는 0이 아닌 다른 값을 표시 할 수 있습니다 :-). 또는 sar -P ALL 1사용하지 않는 경우 atop. 이것이 iowait다중 CPU 시스템을 위해 모델이 확장 된 방식입니다 ... 확실하지 않은 것은이 모델이 실제로 사용 가능한지 또는 CPU가 하나만있을 때 iowait 코드가 계속 작동하도록하는 것입니다. 온라인이지만 다른 방법으로는 신뢰할 수 없습니다.