Commit 4bc48dcd authored by Konstantin Khlebnikov's avatar Konstantin Khlebnikov

ioping: add option -t for detecting cache hits

Signed-off-by: default avatarKonstantin Khlebnikov <koct9i@gmail.com>
parent 2edfa99c
...@@ -6,6 +6,7 @@ ioping \- simple disk I/O latency monitoring tool ...@@ -6,6 +6,7 @@ ioping \- simple disk I/O latency monitoring tool
.OP \-ABCDLRWkq .OP \-ABCDLRWkq
.OP \-c count .OP \-c count
.OP \-i interval .OP \-i interval
.OP \-t time
.OP \-s size .OP \-s size
.OP \-S wsize .OP \-S wsize
.OP \-o offset .OP \-o offset
...@@ -30,6 +31,10 @@ Stop after \fIcount\fR requests. ...@@ -30,6 +31,10 @@ Stop after \fIcount\fR requests.
.BI \-i \ interval .BI \-i \ interval
Set time between requests to \fIinterval\fR (\fB1s\fR). Set time between requests to \fIinterval\fR (\fB1s\fR).
.TP .TP
.BI \-t \ time
Minimal valid request time for cache misses (\fB0us\fR).
Cache hits are ignored in statistics.
.TP
.BI \-s \ size .BI \-s \ size
Request size (\fB4k\fR). Request size (\fB4k\fR).
.TP .TP
......
...@@ -252,6 +252,7 @@ void usage(void) ...@@ -252,6 +252,7 @@ void usage(void)
"\n" "\n"
" -c <count> stop after <count> requests\n" " -c <count> stop after <count> requests\n"
" -i <interval> interval between requests (1s)\n" " -i <interval> interval between requests (1s)\n"
" -t <time> minimal valid request time (0us)\n"
" -s <size> request size (4k)\n" " -s <size> request size (4k)\n"
" -S <wsize> working set size (1m)\n" " -S <wsize> working set size (1m)\n"
" -o <offset> working set offset (0)\n" " -o <offset> working set offset (0)\n"
...@@ -449,6 +450,8 @@ long long interval = 1000000; ...@@ -449,6 +450,8 @@ long long interval = 1000000;
struct timespec interval_ts; struct timespec interval_ts;
long long deadline = 0; long long deadline = 0;
long long min_valid_time = 0;
ssize_t default_size = 1<<12; ssize_t default_size = 1<<12;
ssize_t size = 0; ssize_t size = 0;
off_t wsize = 0; off_t wsize = 0;
...@@ -459,7 +462,6 @@ int keep_file = 0; ...@@ -459,7 +462,6 @@ int keep_file = 0;
off_t offset = 0; off_t offset = 0;
off_t woffset = 0; off_t woffset = 0;
int request;
int stop_at_request = 0; int stop_at_request = 0;
int exiting = 0; int exiting = 0;
...@@ -473,7 +475,7 @@ void parse_options(int argc, char **argv) ...@@ -473,7 +475,7 @@ void parse_options(int argc, char **argv)
exit(1); exit(1);
} }
while ((opt = getopt(argc, argv, "hvkALRDCWBqi:w:s:S:c:o:p:P:")) != -1) { while ((opt = getopt(argc, argv, "hvkALRDCWBqi:t:w:s:S:c:o:p:P:")) != -1) {
switch (opt) { switch (opt) {
case 'h': case 'h':
usage(); usage();
...@@ -509,6 +511,9 @@ void parse_options(int argc, char **argv) ...@@ -509,6 +511,9 @@ void parse_options(int argc, char **argv)
interval = parse_time(optarg); interval = parse_time(optarg);
custom_interval = 1; custom_interval = 1;
break; break;
case 't':
min_valid_time = parse_time(optarg);
break;
case 'w': case 'w':
deadline = parse_time(optarg); deadline = parse_time(optarg);
custom_deadline = 1; custom_deadline = 1;
...@@ -964,7 +969,8 @@ int main (int argc, char **argv) ...@@ -964,7 +969,8 @@ int main (int argc, char **argv)
struct stat st; struct stat st;
int ret; int ret;
int part_request; int request, part_request;
int total_valid, part_valid;
long long this_time; long long this_time;
double part_min, part_max, time_min, time_max; double part_min, part_max, time_min, time_max;
double time_sum, time_sum2, time_mdev, time_avg; double time_sum, time_sum2, time_mdev, time_avg;
...@@ -1123,9 +1129,12 @@ skip_preparation: ...@@ -1123,9 +1129,12 @@ skip_preparation:
set_signal(); set_signal();
request = 0; request = 0;
total_valid = 0;
woffset = 0; woffset = 0;
part_request = 0; part_request = 0;
part_valid = 0;
part_min = time_min = LLONG_MAX; part_min = time_min = LLONG_MAX;
part_max = time_max = LLONG_MIN; part_max = time_max = LLONG_MIN;
part_sum = time_sum = 0; part_sum = time_sum = 0;
...@@ -1168,12 +1177,15 @@ skip_preparation: ...@@ -1168,12 +1177,15 @@ skip_preparation:
this_time = time_now - this_time; this_time = time_now - this_time;
time_next = time_now + interval; time_next = time_now + interval;
if (this_time >= min_valid_time) {
part_valid++;
part_sum += this_time; part_sum += this_time;
part_sum2 += this_time * this_time; part_sum2 += this_time * this_time;
if (this_time < part_min) if (this_time < part_min)
part_min = this_time; part_min = this_time;
if (this_time > part_max) if (this_time > part_max)
part_max = this_time; part_max = this_time;
}
if (!quiet) { if (!quiet) {
print_size(ret_size); print_size(ret_size);
...@@ -1183,20 +1195,13 @@ skip_preparation: ...@@ -1183,20 +1195,13 @@ skip_preparation:
print_size(device_size); print_size(device_size);
printf("): request=%d time=", request); printf("): request=%d time=", request);
print_time(this_time); print_time(this_time);
if (this_time < min_valid_time)
printf(" (cache hit)");
printf("\n"); printf("\n");
} }
if ((period_request && (part_request >= period_request)) || if ((period_request && (part_request >= period_request)) ||
(period_time && (time_next >= period_deadline))) { (period_time && (time_next >= period_deadline))) {
part_avg = part_sum / part_request;
part_mdev = sqrt(part_sum2 / part_request - part_avg * part_avg);
printf("%d %.0f %.0f %.0f %.0f %.0f %.0f %.0f\n",
part_request, part_sum,
1000000. * part_request / part_sum,
1000000. * part_request * size / part_sum,
part_min, part_avg,
part_max, part_mdev);
time_sum += part_sum; time_sum += part_sum;
time_sum2 += part_sum2; time_sum2 += part_sum2;
...@@ -1204,10 +1209,32 @@ skip_preparation: ...@@ -1204,10 +1209,32 @@ skip_preparation:
time_min = part_min; time_min = part_min;
if (part_max > time_max) if (part_max > time_max)
time_max = part_max; time_max = part_max;
if (part_valid) {
part_avg = part_sum / part_valid;
part_mdev = sqrt(part_sum2 / part_valid -
part_avg * part_avg);
} else {
part_min = 0;
part_avg = 0;
part_max = 0;
part_mdev = 0;
part_sum = 0.1;
}
printf("%d %.0f %.0f %.0f %.0f %.0f %.0f %.0f\n",
part_valid, part_sum,
1000000. * part_valid / part_sum,
1000000. * part_valid * size / part_sum,
part_min, part_avg,
part_max, part_mdev);
part_min = LLONG_MAX; part_min = LLONG_MAX;
part_max = LLONG_MIN; part_max = LLONG_MIN;
part_sum = part_sum2 = 0; part_sum = part_sum2 = 0;
part_request = 0; part_request = 0;
total_valid += part_valid;
part_valid = 0;
period_deadline = time_now + period_time; period_deadline = time_now + period_time;
} }
...@@ -1237,15 +1264,24 @@ skip_preparation: ...@@ -1237,15 +1264,24 @@ skip_preparation:
time_min = part_min; time_min = part_min;
if (part_max > time_max) if (part_max > time_max)
time_max = part_max; time_max = part_max;
total_valid += part_valid;
time_avg = time_sum / request; if (total_valid) {
time_mdev = sqrt(time_sum2 / request - time_avg * time_avg); time_avg = time_sum / total_valid;
time_mdev = sqrt(time_sum2 / total_valid - time_avg * time_avg);
} else {
time_min = 0;
time_avg = 0;
time_max = 0;
time_mdev = 0;
time_sum = 0.1;
}
if (batch_mode) { if (batch_mode) {
printf("%d %.0f %.0f %.0f %.0f %.0f %.0f %.0f\n", printf("%d %.0f %.0f %.0f %.0f %.0f %.0f %.0f\n",
request, time_sum, total_valid, time_sum,
1000000. * request / time_sum, 1000000. * total_valid / time_sum,
1000000. * request * size / time_sum, 1000000. * total_valid * size / time_sum,
time_min, time_avg, time_min, time_avg,
time_max, time_mdev); time_max, time_mdev);
} else if (!quiet || (!period_time && !period_request)) { } else if (!quiet || (!period_time && !period_request)) {
...@@ -1253,15 +1289,19 @@ skip_preparation: ...@@ -1253,15 +1289,19 @@ skip_preparation:
if (device_size) if (device_size)
print_size(device_size); print_size(device_size);
printf(") ioping statistics ---\n"); printf(") ioping statistics ---\n");
print_int(request); print_int(total_valid);
printf(" requests completed in "); printf(" requests completed in ");
print_time(time_sum); print_time(time_sum);
printf(", "); printf(", ");
print_size((long long)request * size); if (total_valid < request) {
print_int(request - total_valid);
printf(" cache hits, ");
}
print_size((long long)total_valid * size);
printf(" %s, ", write_test ? "written" : "read"); printf(" %s, ", write_test ? "written" : "read");
print_int(1000000. * request / time_sum); print_int(1000000. * total_valid / time_sum);
printf(" iops, "); printf(" iops, ");
print_size(1000000. * request * size / time_sum); print_size(1000000. * total_valid * size / time_sum);
printf("/s\n"); printf("/s\n");
printf("min/avg/max/mdev = "); printf("min/avg/max/mdev = ");
print_time(time_min); print_time(time_min);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment