Как вычисляется использование iostat?
iostat -x -d
может отображать много статистических данных ввода-вывода.
Для использования иостата объяснение:
Процентное время процессорного времени, в течение которого были отправлены запросы ввода-вывода (использование ширины полосы для устройства). Насыщенность устройства возникает, когда это значение близко к 100%
Я хочу знать, как вычислили утилиту?
Я делаю эксперимент (см. следующий код), запустите 40 потоков, чтобы случайно прочитать 40 файлов. Я полагаю, что диск должен быть очень высоким, но я ошибаюсь,
iostat является следующим, любой может дать почему? спасибо
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
sdb1 0.01 0.44 0.24 0.57 3.44 8.14 14.34 0.00 2.28 0.66 0.05
код:
#include <iostream>
#include <fstream>
#include <pthread.h>
using namespace std;
void* work(void* a)
{
int* id = (int*)a;
string file = "sys.partition";
char buf[100];
sprintf(buf, "%d", *id);
file.append(string(buf));
ifstream in(file.c_str());
in.seekg(0, ios_base::end);
size_t len = in.tellg();
cout << "open file : " << file << " , " << len << endl;
srand(time(NULL));
while(true)
{
size_t pos = rand() % len;
in.seekg(pos);
//cout << pos << endl;
in.read(buf, 10);
system("sync");
}
in.close();
}
int main(int argc, char** argv)
{
static const int num = 40;
pthread_t threads[num];
for (int i = 0; i < num; i++) {
pthread_create(&threads[i], NULL, work, &i);
}
for (int i = 0; i < num; i++) {
pthread_join(threads[i], NULL);
}
return 0;
}
Ответы
Ответ 1
%util
называется занятым в исходном коде iostat: https://code.google.com/p/tester-higkoo/source/browse/trunk/Tools/iostat/iostat.c#380
Занят подсчитывается как процентное соотношение от Ticks
до deltams
, ограниченное 100%
busy = 100.0 * blkio.ticks / deltams; /* percentage! */
if (busy > 100.0) busy = 100.0;
DeltaMS представляет собой сумму загрузки системы за период времени (пользовательское время + системное время + время простоя + iowait)/ncpu.
double deltams = 1000.0 *
((new_cpu.user + new_cpu.system +
new_cpu.idle + new_cpu.iowait) -
(old_cpu.user + old_cpu.system +
old_cpu.idle + old_cpu.iowait)) / ncpu / HZ;
Ticks - это Time of requests in queue
за период
blkio.ticks = new_blkio[p].ticks
- old_blkio[p].ticks;
В более текущей версии sysstat код немного отличается:
http://sources.debian.net/src/sysstat/10.2.0-1/iostat.c#L959
/* rrq/s wrq/s r/s w/s rsec wsec rqsz qusz await r_await w_await svctm %util */
printf(" %8.2f %8.2f %7.2f %7.2f %8.2f %8.2f %8.2f %8.2f %7.2f %7.2f %7.2f %6.2f %6.2f\n",
...
/*
* Again: Ticks in milliseconds.
* In the case of a device group (option -g), shi->used is the number of
* devices in the group. Else shi->used equals 1.
*/
shi->used ? xds.util / 10.0 / (double) shi->used
: xds.util / 10.0); /* shi->used should never be null here */
xds заполняется в compute_ext_disk_stats(&sdc, &sdp, itv, &xds);
http://sources.debian.net/src/sysstat/10.2.0-1/common.c?hl=679#L679
/*
* Macros used to display statistics values.
*
* HZ is 1024 on IA64 and % should be normalized to 100.
*/
#define S_VALUE(m,n,p) (((double) ((n) - (m))) / (p) * HZ)
xds->util = S_VALUE(sdp->tot_ticks, sdc->tot_ticks, itv);
И есть заполнение tot_ticks из iostat.c
* @ioi Current sample statistics.
* @ioj Previous sample statistics.
* @itv Interval of time.
...
sdc.tot_ticks = ioi->tot_ticks;
sdp.tot_ticks = ioj->tot_ticks;
tot_ticks
читаются из "sysfs stat для текущего блочного устройства или раздела" в read_sysfs_file_stat
(iostat.c: 487), и ioi
и ioj
являются текущими и предыдущими stat.
Ответ 2
iostat -x
(я использовал старый исходный код, чтобы записать это до его реализации) отображает информацию из /proc/diskstats
(документировано здесь) и /proc/stat
(для процессорных времен, см. man proc (5)) (и несколько других, но это не важно для понимания).
Вы можете увидеть соответствующие фрагменты кода в ответе osgx, но я не мог понять их изолированно, так что вот расширенное объяснение:
-
%util = blkio.ticks / deltams * 100%
-
deltams
- время, прошедшее с момента последнего моментального снимка в мс. Он использует статистику CPU от /proc/stat
предположительно, потому что он дает лучшие результаты, чем полагаться на системное время, но я не знаю точно. (Сторона примечания: по какой-то причине времена делятся на HZ
, а документация заявляет об этом в USER_HZ
, я не понимаю что.)
-
blkio.ticks
- "миллисекунд, потраченный на операции ввода-вывода", /proc/diskstats
docs:
Field 9 -- # of I/Os currently in progress
The only field that should go to zero. Incremented as requests are
given to appropriate struct request_queue and decremented as they finish.
Field 10 -- # of milliseconds spent doing I/Os
This field increases so long as field 9 is nonzero.
то есть. я понимаю, что ticks
- количество тиков, когда был запрошен любой запрос ввода-вывода (для этого устройства), умноженный на продолжительность между тиками.
Итак, %util = 100%
означает, что каждый раз, когда ядро выглядело (я думаю, это 1000 раз в секунду на современных ядрах, см. "HZ" ), запрос ввода-вывода выполнялся.
Здесь выдержка из другого сообщения на iostat:
[% util is] сколько времени у запоминающего устройства было выдающимся (было занято).
В правильных RAID-средах это больше похоже на "сколько времени, по крайней мере, на одном диске в RAID-массиве есть что-то делать". Im сознательно исключает какой-либо кеш здесь - если запрос может быть подан из кеша, вероятность весьма незначительна, он будет отображаться в% util, в отличие от других значений.
Что это означает - подсистема RAID может быть загружена с 6.25% (один диск делает работу) до 100% (все они заняты). Thats довольно много проницательности в одиночном значении 100%, не оно?
Ответ 3
В соответствии с man-страницей первая строка результатов из iostat является средней с момента загрузки системы.
Из моих тестов это, похоже, относится и к единственной строке, если ее называют, например, а
iostat -x.
Попробуйте:
iostat -dmx 1 5
Это даст вам пять строк с разницей в одну секунду между строками. Отбросьте первое, посмотрите на других, возможно, так, что результат будет иметь больше смысла.
Ответ 4
% util означает, сколько времени потрачено на чтение/чтение за единицу времени, вы можете вычислить его из среднего времени службы:
svctm * ( r/s + w/s ) /1000
= 0.66 *(0.24 + 0.57) /1000
= 0.0005346
следовательно, 0,05%
Я не читал ваш код, но, очевидно, менее чем за 1 чтение или запись в секунду, это не очень сильно загружает диски!