completion latency below which 99.5% and 99.9% of the observed latencies
fell, respectively.
+.. option:: significant_figures=int
+
+ If using :option:`--output-format` of `normal`, set the significant figures
+ to this value. Higher values will yield more precise IOPS and throughput
+ units, while lower values will round. Requires a minimum value of 1 and a
+ maximum value of 10. Defaults to 4.
+
Error handling
~~~~~~~~~~~~~~
o->clat_percentiles = le32_to_cpu(top->clat_percentiles);
o->lat_percentiles = le32_to_cpu(top->lat_percentiles);
o->percentile_precision = le32_to_cpu(top->percentile_precision);
+ o->sig_figs = le32_to_cpu(top->sig_figs);
o->continue_on_error = le32_to_cpu(top->continue_on_error);
o->cgroup_weight = le32_to_cpu(top->cgroup_weight);
o->cgroup_nodelete = le32_to_cpu(top->cgroup_nodelete);
top->clat_percentiles = cpu_to_le32(o->clat_percentiles);
top->lat_percentiles = cpu_to_le32(o->lat_percentiles);
top->percentile_precision = cpu_to_le32(o->percentile_precision);
+ top->sig_figs = cpu_to_le32(o->sig_figs);
top->continue_on_error = cpu_to_le32(o->continue_on_error);
top->cgroup_weight = cpu_to_le32(o->cgroup_weight);
top->cgroup_nodelete = cpu_to_le32(o->cgroup_nodelete);
dst->kb_base = le32_to_cpu(src->kb_base);
dst->unit_base = le32_to_cpu(src->unit_base);
+ dst->sig_figs = le32_to_cpu(src->sig_figs);
+
dst->latency_depth = le32_to_cpu(src->latency_depth);
dst->latency_target = le64_to_cpu(src->latency_target);
dst->latency_window = le64_to_cpu(src->latency_window);
dst->kb_base = le32_to_cpu(src->kb_base);
dst->unit_base = le32_to_cpu(src->unit_base);
+ dst->sig_figs = le32_to_cpu(src->sig_figs);
dst->groupid = le32_to_cpu(src->groupid);
dst->unified_rw_rep = le32_to_cpu(src->unified_rw_rep);
}
je->nr_threads = le32_to_cpu(je->nr_threads);
je->is_pow2 = le32_to_cpu(je->is_pow2);
je->unit_base = le32_to_cpu(je->unit_base);
+ je->sig_figs = le32_to_cpu(je->sig_figs);
}
void fio_client_sum_jobs_eta(struct jobs_eta *dst, struct jobs_eta *je)
char *tr, *mr;
mr = num2str(je->m_rate[0] + je->m_rate[1] + je->m_rate[2],
- 4, 0, je->is_pow2, N2S_BYTEPERSEC);
+ je->sig_figs, 0, je->is_pow2, N2S_BYTEPERSEC);
tr = num2str(je->t_rate[0] + je->t_rate[1] + je->t_rate[2],
- 4, 0, je->is_pow2, N2S_BYTEPERSEC);
+ je->sig_figs, 0, je->is_pow2, N2S_BYTEPERSEC);
p += sprintf(p, ", %s-%s", mr, tr);
free(tr);
`\-\-percentile_list=99.5:99.9' will cause fio to report the values of
completion latency below which 99.5% and 99.9% of the observed latencies
fell, respectively.
+.TP
+.BI significant_figures \fR=\fPint
+If using \fB\-\-output\-format\fR of `normal', set the significant figures
+to this value. Higher values will yield more precise IOPS and throughput
+units, while lower values will round. Requires a minimum value of 1 and a
+maximum value of 10. Defaults to 4.
.SS "Error handling"
.TP
.BI exitall_on_error
sprintf(output, "%3.1f%% done", perc);
}
- iops_str[0] = num2str(je->iops[0], 4, 1, 0, N2S_PERSEC);
- iops_str[1] = num2str(je->iops[1], 4, 1, 0, N2S_PERSEC);
- iops_str[2] = num2str(je->iops[2], 4, 1, 0, N2S_PERSEC);
+ iops_str[0] = num2str(je->iops[0], je->sig_figs, 1, 0, N2S_PERSEC);
+ iops_str[1] = num2str(je->iops[1], je->sig_figs, 1, 0, N2S_PERSEC);
+ iops_str[2] = num2str(je->iops[2], je->sig_figs, 1, 0, N2S_PERSEC);
- rate_str[0] = num2str(je->rate[0], 4, 10, i2p, N2S_BYTEPERSEC);
- rate_alt[0] = num2str(je->rate[0], 4, 10, !i2p, N2S_BYTEPERSEC);
+ rate_str[0] = num2str(je->rate[0], je->sig_figs, 10, i2p, N2S_BYTEPERSEC);
+ rate_alt[0] = num2str(je->rate[0], je->sig_figs, 10, !i2p, N2S_BYTEPERSEC);
snprintf(tmp, sizeof(tmp), "%s (%s)", rate_str[0], rate_alt[0]);
gtk_entry_set_text(GTK_ENTRY(ge->eta.read_bw), tmp);
gtk_entry_set_text(GTK_ENTRY(ge->eta.read_iops), iops_str[0]);
- rate_str[1] = num2str(je->rate[1], 4, 10, i2p, N2S_BYTEPERSEC);
- rate_alt[1] = num2str(je->rate[1], 4, 10, !i2p, N2S_BYTEPERSEC);
+ rate_str[1] = num2str(je->rate[1], je->sig_figs, 10, i2p, N2S_BYTEPERSEC);
+ rate_alt[1] = num2str(je->rate[1], je->sig_figs, 10, !i2p, N2S_BYTEPERSEC);
snprintf(tmp, sizeof(tmp), "%s (%s)", rate_str[1], rate_alt[1]);
gtk_entry_set_text(GTK_ENTRY(ge->eta.write_bw), tmp);
gtk_entry_set_text(GTK_ENTRY(ge->eta.write_iops), iops_str[1]);
- rate_str[2] = num2str(je->rate[2], 4, 10, i2p, N2S_BYTEPERSEC);
- rate_alt[2] = num2str(je->rate[2], 4, 10, !i2p, N2S_BYTEPERSEC);
+ rate_str[2] = num2str(je->rate[2], je->sig_figs, 10, i2p, N2S_BYTEPERSEC);
+ rate_alt[2] = num2str(je->rate[2], je->sig_figs, 10, !i2p, N2S_BYTEPERSEC);
snprintf(tmp, sizeof(tmp), "%s (%s)", rate_str[2], rate_alt[2]);
gtk_entry_set_text(GTK_ENTRY(ge->eta.trim_bw), tmp);
gtk_entry_set_text(GTK_ENTRY(ge->eta.trim_iops), iops_str[2]);
sprintf(output, "%3.1f%% done", perc);
}
- iops_str[0] = num2str(je->iops[0], 4, 1, 0, N2S_PERSEC);
- iops_str[1] = num2str(je->iops[1], 4, 1, 0, N2S_PERSEC);
- iops_str[2] = num2str(je->iops[2], 4, 1, 0, N2S_PERSEC);
+ iops_str[0] = num2str(je->iops[0], je->sig_figs, 1, 0, N2S_PERSEC);
+ iops_str[1] = num2str(je->iops[1], je->sig_figs, 1, 0, N2S_PERSEC);
+ iops_str[2] = num2str(je->iops[2], je->sig_figs, 1, 0, N2S_PERSEC);
- rate_str[0] = num2str(je->rate[0], 4, 10, i2p, N2S_BYTEPERSEC);
- rate_alt[0] = num2str(je->rate[0], 4, 10, !i2p, N2S_BYTEPERSEC);
+ rate_str[0] = num2str(je->rate[0], je->sig_figs, 10, i2p, N2S_BYTEPERSEC);
+ rate_alt[0] = num2str(je->rate[0], je->sig_figs, 10, !i2p, N2S_BYTEPERSEC);
snprintf(tmp, sizeof(tmp), "%s (%s)", rate_str[0], rate_alt[0]);
gtk_entry_set_text(GTK_ENTRY(ui->eta.read_bw), tmp);
gtk_entry_set_text(GTK_ENTRY(ui->eta.read_iops), iops_str[0]);
- rate_str[1] = num2str(je->rate[1], 4, 10, i2p, N2S_BYTEPERSEC);
- rate_alt[1] = num2str(je->rate[1], 4, 10, !i2p, N2S_BYTEPERSEC);
+ rate_str[1] = num2str(je->rate[1], je->sig_figs, 10, i2p, N2S_BYTEPERSEC);
+ rate_alt[1] = num2str(je->rate[1], je->sig_figs, 10, !i2p, N2S_BYTEPERSEC);
snprintf(tmp, sizeof(tmp), "%s (%s)", rate_str[1], rate_alt[1]);
gtk_entry_set_text(GTK_ENTRY(ui->eta.write_bw), tmp);
gtk_entry_set_text(GTK_ENTRY(ui->eta.write_iops), iops_str[1]);
- rate_str[2] = num2str(je->rate[2], 4, 10, i2p, N2S_BYTEPERSEC);
- rate_alt[2] = num2str(je->rate[2], 4, 10, !i2p, N2S_BYTEPERSEC);
+ rate_str[2] = num2str(je->rate[2], je->sig_figs, 10, i2p, N2S_BYTEPERSEC);
+ rate_alt[2] = num2str(je->rate[2], je->sig_figs, 10, !i2p, N2S_BYTEPERSEC);
snprintf(tmp, sizeof(tmp), "%s (%s)", rate_str[2], rate_alt[2]);
gtk_entry_set_text(GTK_ENTRY(ui->eta.trim_bw), tmp);
gtk_entry_set_text(GTK_ENTRY(ui->eta.trim_iops), iops_str[2]);
multitext_add_entry(&ge->eta.iotype, tmp);
i2p = is_power_of_2(o->kb_base);
- c1 = num2str(o->min_bs[DDIR_READ], 4, 1, i2p, N2S_BYTE);
- c2 = num2str(o->max_bs[DDIR_READ], 4, 1, i2p, N2S_BYTE);
- c3 = num2str(o->min_bs[DDIR_WRITE], 4, 1, i2p, N2S_BYTE);
- c4 = num2str(o->max_bs[DDIR_WRITE], 4, 1, i2p, N2S_BYTE);
+ c1 = num2str(o->min_bs[DDIR_READ], o->sig_figs, 1, i2p, N2S_BYTE);
+ c2 = num2str(o->max_bs[DDIR_READ], o->sig_figs, 1, i2p, N2S_BYTE);
+ c3 = num2str(o->min_bs[DDIR_WRITE], o->sig_figs, 1, i2p, N2S_BYTE);
+ c4 = num2str(o->max_bs[DDIR_WRITE], o->sig_figs, 1, i2p, N2S_BYTE);
sprintf(tmp, "%s-%s,%s-%s", c1, c2, c3, c4);
free(c1);
bw = (1000 * ts->io_bytes[ddir]) / runt;
iops = (1000 * (uint64_t)ts->total_io_u[ddir]) / runt;
- iops_p = num2str(iops, 4, 1, 0, N2S_PERSEC);
+ iops_p = num2str(iops, ts->sig_figs, 1, 0, N2S_PERSEC);
box = gtk_hbox_new(FALSE, 3);
gtk_box_pack_start(GTK_BOX(mbox), box, TRUE, FALSE, 3);
gtk_box_pack_start(GTK_BOX(main_vbox), box, TRUE, FALSE, 3);
label = new_info_label_in_frame(box, "IO");
- io_p = num2str(ts->io_bytes[ddir], 4, 1, i2p, N2S_BYTE);
- io_palt = num2str(ts->io_bytes[ddir], 4, 1, !i2p, N2S_BYTE);
+ io_p = num2str(ts->io_bytes[ddir], ts->sig_figs, 1, i2p, N2S_BYTE);
+ io_palt = num2str(ts->io_bytes[ddir], ts->sig_figs, 1, !i2p, N2S_BYTE);
snprintf(tmp, sizeof(tmp), "%s (%s)", io_p, io_palt);
gtk_label_set_text(GTK_LABEL(label), tmp);
label = new_info_label_in_frame(box, "Bandwidth");
- bw_p = num2str(bw, 4, 1, i2p, ts->unit_base);
- bw_palt = num2str(bw, 4, 1, !i2p, ts->unit_base);
+ bw_p = num2str(bw, ts->sig_figs, 1, i2p, ts->unit_base);
+ bw_palt = num2str(bw, ts->sig_figs, 1, !i2p, ts->unit_base);
snprintf(tmp, sizeof(tmp), "%s (%s)", bw_p, bw_palt);
gtk_label_set_text(GTK_LABEL(label), tmp);
char *c5 = NULL, *c6 = NULL;
int i2p = is_power_of_2(o->kb_base);
- c1 = num2str(o->min_bs[DDIR_READ], 4, 1, i2p, N2S_BYTE);
- c2 = num2str(o->max_bs[DDIR_READ], 4, 1, i2p, N2S_BYTE);
- c3 = num2str(o->min_bs[DDIR_WRITE], 4, 1, i2p, N2S_BYTE);
- c4 = num2str(o->max_bs[DDIR_WRITE], 4, 1, i2p, N2S_BYTE);
+ c1 = num2str(o->min_bs[DDIR_READ], o->sig_figs, 1, i2p, N2S_BYTE);
+ c2 = num2str(o->max_bs[DDIR_READ], o->sig_figs, 1, i2p, N2S_BYTE);
+ c3 = num2str(o->min_bs[DDIR_WRITE], o->sig_figs, 1, i2p, N2S_BYTE);
+ c4 = num2str(o->max_bs[DDIR_WRITE], o->sig_figs, 1, i2p, N2S_BYTE);
if (!o->bs_is_seq_rand) {
- c5 = num2str(o->min_bs[DDIR_TRIM], 4, 1, i2p, N2S_BYTE);
- c6 = num2str(o->max_bs[DDIR_TRIM], 4, 1, i2p, N2S_BYTE);
+ c5 = num2str(o->min_bs[DDIR_TRIM], o->sig_figs, 1, i2p, N2S_BYTE);
+ c6 = num2str(o->max_bs[DDIR_TRIM], o->sig_figs, 1, i2p, N2S_BYTE);
}
log_info("%s: (g=%d): rw=%s, ", td->o.name,
.category = FIO_OPT_C_STAT,
.group = FIO_OPT_G_INVALID,
},
+ {
+ .name = "significant_figures",
+ .lname = "Significant figures",
+ .type = FIO_OPT_INT,
+ .off1 = offsetof(struct thread_options, sig_figs),
+ .maxval = 10,
+ .minval = 1,
+ .help = "Significant figures for output-format set to normal",
+ .def = "4",
+ .interval = 1,
+ .category = FIO_OPT_C_STAT,
+ .group = FIO_OPT_G_INVALID,
+ },
#ifdef FIO_HAVE_DISK_UTIL
{
p.ts.latency_window = cpu_to_le64(ts->latency_window);
p.ts.latency_percentile.u.i = cpu_to_le64(fio_double_to_uint64(ts->latency_percentile.u.f));
+ p.ts.sig_figs = cpu_to_le32(ts->sig_figs);
+
p.ts.nr_block_infos = cpu_to_le64(ts->nr_block_infos);
for (i = 0; i < p.ts.nr_block_infos; i++)
p.ts.block_infos[i] = cpu_to_le32(ts->block_infos[i]);
if (!rs->max_run[i])
continue;
- io = num2str(rs->iobytes[i], 4, 1, i2p, N2S_BYTE);
- ioalt = num2str(rs->iobytes[i], 4, 1, !i2p, N2S_BYTE);
- agg = num2str(rs->agg[i], 4, 1, i2p, rs->unit_base);
- aggalt = num2str(rs->agg[i], 4, 1, !i2p, rs->unit_base);
- min = num2str(rs->min_bw[i], 4, 1, i2p, rs->unit_base);
- minalt = num2str(rs->min_bw[i], 4, 1, !i2p, rs->unit_base);
- max = num2str(rs->max_bw[i], 4, 1, i2p, rs->unit_base);
- maxalt = num2str(rs->max_bw[i], 4, 1, !i2p, rs->unit_base);
+ io = num2str(rs->iobytes[i], rs->sig_figs, 1, i2p, N2S_BYTE);
+ ioalt = num2str(rs->iobytes[i], rs->sig_figs, 1, !i2p, N2S_BYTE);
+ agg = num2str(rs->agg[i], rs->sig_figs, 1, i2p, rs->unit_base);
+ aggalt = num2str(rs->agg[i], rs->sig_figs, 1, !i2p, rs->unit_base);
+ min = num2str(rs->min_bw[i], rs->sig_figs, 1, i2p, rs->unit_base);
+ minalt = num2str(rs->min_bw[i], rs->sig_figs, 1, !i2p, rs->unit_base);
+ max = num2str(rs->max_bw[i], rs->sig_figs, 1, i2p, rs->unit_base);
+ maxalt = num2str(rs->max_bw[i], rs->sig_figs, 1, !i2p, rs->unit_base);
log_buf(out, "%s: bw=%s (%s), %s-%s (%s-%s), io=%s (%s), run=%llu-%llumsec\n",
rs->unified_rw_rep ? " MIXED" : str[i],
agg, aggalt, min, max, minalt, maxalt, io, ioalt,
runt = ts->runtime[ddir];
bw = (1000 * ts->io_bytes[ddir]) / runt;
- io_p = num2str(ts->io_bytes[ddir], 4, 1, i2p, N2S_BYTE);
- bw_p = num2str(bw, 4, 1, i2p, ts->unit_base);
- bw_p_alt = num2str(bw, 4, 1, !i2p, ts->unit_base);
+ io_p = num2str(ts->io_bytes[ddir], ts->sig_figs, 1, i2p, N2S_BYTE);
+ bw_p = num2str(bw, ts->sig_figs, 1, i2p, ts->unit_base);
+ bw_p_alt = num2str(bw, ts->sig_figs, 1, !i2p, ts->unit_base);
iops = (1000 * (uint64_t)ts->total_io_u[ddir]) / runt;
- iops_p = num2str(iops, 4, 1, 0, N2S_NONE);
+ iops_p = num2str(iops, ts->sig_figs, 1, 0, N2S_NONE);
log_buf(out, " %s: IOPS=%s, BW=%s (%s)(%s/%llumsec)\n",
rs->unified_rw_rep ? "mixed" : str[ddir],
bw_mean = steadystate_bw_mean(ts);
iops_mean = steadystate_iops_mean(ts);
- p1 = num2str(bw_mean / ts->kb_base, 4, ts->kb_base, i2p, ts->unit_base);
- p1alt = num2str(bw_mean / ts->kb_base, 4, ts->kb_base, !i2p, ts->unit_base);
- p2 = num2str(iops_mean, 4, 1, 0, N2S_NONE);
+ p1 = num2str(bw_mean / ts->kb_base, ts->sig_figs, ts->kb_base, i2p, ts->unit_base);
+ p1alt = num2str(bw_mean / ts->kb_base, ts->sig_figs, ts->kb_base, !i2p, ts->unit_base);
+ p2 = num2str(iops_mean, ts->sig_figs, 1, 0, N2S_NONE);
log_buf(out, " steadystate : attained=%s, bw=%s (%s), iops=%s, %s%s=%.3f%s\n",
ts->ss_state & __FIO_SS_ATTAINED ? "yes" : "no",
ts->kb_base = td->o.kb_base;
ts->unit_base = td->o.unit_base;
+ ts->sig_figs = td->o.sig_figs;
ts->unified_rw_rep = td->o.unified_rw_rep;
} else if (ts->kb_base != td->o.kb_base && !kb_base_warned) {
log_info("fio: kb_base differs for jobs in group, using"
rs = &runstats[ts->groupid];
rs->kb_base = ts->kb_base;
rs->unit_base = ts->unit_base;
+ rs->sig_figs = ts->sig_figs;
rs->unified_rw_rep += ts->unified_rw_rep;
for (j = 0; j < DDIR_RWDIR_CNT; j++) {
uint64_t agg[DDIR_RWDIR_CNT];
uint32_t kb_base;
uint32_t unit_base;
+ uint32_t sig_figs;
uint32_t groupid;
uint32_t unified_rw_rep;
} __attribute__((packed));
fio_fp64_t latency_percentile;
uint64_t latency_window;
+ uint32_t sig_figs;
+
uint64_t ss_dur;
uint32_t ss_state;
uint32_t ss_head;
uint32_t is_pow2;
uint32_t unit_base;
+ uint32_t sig_figs;
+
uint32_t files_open;
/*
unsigned long long latency_window;
fio_fp64_t latency_percentile;
+ unsigned int sig_figs;
+
unsigned block_error_hist;
unsigned int replay_align;
uint64_t latency_window;
fio_fp64_t latency_percentile;
+ uint32_t sig_figs;
+
uint32_t block_error_hist;
uint32_t replay_align;