in src/result_formatter.cc [269:388]
void ResultFormatterText::print_iops(const std::shared_ptr<Job>& job, Type t) {
std::shared_ptr<JobOptions> options = job->get_options();
std::shared_ptr<JobResults> results = job->get_results();
printf("thread | bytes | I/Os | MB/s | I/O per s |%s%s%s file\n",
options->measure_iops_std_dev ? " IopsStdDev |" : "",
options->measure_latency ? " AvgLat(ms) |" : "",
options->measure_latency ? " LatStdDev |" : "");
IOPS_RESULT_BAR()
double bucket_time_seconds = (double)options->io_bucket_duration_ms/1000.0;
uint64_t total_bytes = 0;
uint64_t total_iops = 0;
IoBucketizer total_bucketizer;
Histogram<uint64_t> total_histogram;
for (auto& thread_result : results->thread_results) {
for (auto& t_result : thread_result->target_results) {
printf("%6d | %15lu | %12lu | %10.2lf | %10.2lf ",
thread_result->thread_id,
IOPS_GET(read_bytes_count, write_bytes_count, bytes_count),
IOPS_GET(read_iops_count, write_iops_count, iops_count),
(double)IOPS_GET(
read_bytes_count,
write_bytes_count,
bytes_count)/ (1<<20) / (double)options->duration,
(double)IOPS_GET(
read_iops_count,
write_iops_count,
iops_count)/ (double)options->duration
);
// iops stddev
if (options->measure_iops_std_dev) {
// make a new bucketizer just for this scope
IoBucketizer curr_bucketizer;
// merge with read, write or both (makes this section a tad cleaner)
if (t == READ || t == RW) {
curr_bucketizer.Merge(t_result->read_bucketizer);
}
if (t == WRITE || t == RW) {
curr_bucketizer.Merge(t_result->write_bucketizer);
}
// merge with the total (for the final row)
total_bucketizer.Merge(curr_bucketizer);
// print this row
printf("| %10.2lf ",
curr_bucketizer.GetStandardDeviation()/bucket_time_seconds);
}
// latency statistics
if (options->measure_latency) {
// same idea as the iops above
Histogram<uint64_t> curr_histogram;
if (t == READ || t == RW) {
curr_histogram.Merge(t_result->read_latency_histogram);
}
if (t == WRITE || t == RW) {
curr_histogram.Merge(t_result->write_latency_histogram);
}
total_histogram.Merge(curr_histogram);
// us -> ms
printf("| %8.3lf ",
(double)curr_histogram.GetAvg()/1000.0);
// avoid nans
if (curr_histogram.GetSampleSize() > 0) {
printf("| %8.3lf ",
(double)curr_histogram.GetStdDev()/1000.0);
} else {
printf("| N/A ");
}
}
total_bytes += IOPS_GET(read_bytes_count, write_bytes_count, bytes_count);
total_iops += IOPS_GET(read_iops_count, write_iops_count, iops_count);
printf("| %s (%lu%s)",
t_result->target->path.c_str(),
t_result->target->size,
"B");
printf("\n");
}
}
IOPS_RESULT_BAR()
printf("total: %15lu | %12lu | %10.2lf | %10.2lf ",
total_bytes,
total_iops,
(double)total_bytes / (1<<20) / (double)options->duration,
(double)total_iops / (double)options->duration);
// total iops std dev
if (options->measure_iops_std_dev) {
printf("| %10.2lf ", total_bucketizer.GetStandardDeviation()/bucket_time_seconds);
}
// total avg lat, std dev
if (options->measure_latency) {
// us -> ms
printf("| %8.3lf ", (double)total_histogram.GetAvg()/1000.0);
// avoid nans
if (total_histogram.GetSampleSize() > 0) {
printf("| %8.3lf ", (double)total_histogram.GetStdDev()/1000.0);
} else {
printf("| N/A ");
}
}
printf("\n\n");
}