log: batch entries of samples before deflating
This both speeds up the log and gets better compression
ratios for the data.
Signed-off-by: Jens Axboe <axboe@kernel.dk>
diff --git a/iolog.c b/iolog.c
index 6807a9f..4eeee4c 100644
--- a/iolog.c
+++ b/iolog.c
@@ -550,23 +550,80 @@
free(log);
}
+static void write_log_samples(FILE *f, struct io_sample *samples,
+ unsigned long nr_samples)
+{
+ unsigned long i;
+
+ for (i = 0; i < nr_samples; i++) {
+ struct io_sample *s = &samples[i];
+
+ s->time = le64_to_cpu(s->time);
+ s->val = le64_to_cpu(s->val);
+ s->ddir = le32_to_cpu(s->ddir);
+ s->bs = le32_to_cpu(s->bs);
+
+ fprintf(f, "%lu, %lu, %u, %u\n",
+ (unsigned long) s->time, (unsigned long) s->val,
+ s->ddir, s->bs);
+ }
+}
+
#ifdef CONFIG_ZLIB
+static void flush_batch_samples(struct io_log *iolog)
+{
+ int ret;
+
+ iolog->stream.next_in = (void *) iolog->batch_samples;
+ iolog->stream.avail_in = sizeof(struct io_sample) * iolog->nr_batch_samples;
+
+ if (iolog->buf_size - iolog->stream.total_out < IOLOG_Z_WINDOW_MIN) {
+ void *new_buf;
+
+ iolog->buf_size += IOLOG_Z_WINDOW;
+ new_buf = realloc(iolog->buf, iolog->buf_size);
+ if (!new_buf) {
+ log_err("fio: failed extending iolog! Will stop logging.\n");
+ iolog->disabled = 1;
+ return;
+ }
+
+ iolog->buf = new_buf;
+ }
+
+ iolog->stream.avail_out = iolog->buf_size - iolog->stream.total_out;
+ iolog->stream.next_out = iolog->buf + iolog->stream.total_out;
+
+ ret = deflate(&iolog->stream, Z_NO_FLUSH);
+ if (ret < 0) {
+ log_err("fio: log deflation failed (%d)\n", ret);
+ iolog->disabled = 1;
+ }
+
+ iolog->nr_batch_samples = 0;
+}
+
static void __finish_log_method(struct io_log *log, FILE *f)
{
struct io_sample *samples;
- unsigned int i;
z_stream out;
int err;
/*
- * Finish deflation of the log
+ * Finish deflation of the log, flush out any left batched
+ * samples first.
*/
+ if (log->nr_batch_samples)
+ flush_batch_samples(log);
+
deflate(&log->stream, Z_FINISH);
deflateEnd(&log->stream);
if (!log->stream.total_out)
return;
+ printf("Compression level: 1 : %.2f\n", ((float) sizeof(struct io_sample) * log->nr_samples) / (float) log->buf_size);
+
out.zalloc = Z_NULL;
out.zfree = Z_NULL;
out.opaque = Z_NULL;
@@ -596,20 +653,7 @@
}
nr = (this_out - out.avail_out) / sizeof(struct io_sample);
-
- for (i = 0; i < nr; i++) {
- struct io_sample *s = &samples[i];
-
- s->time = le64_to_cpu(s->time);
- s->val = le64_to_cpu(s->val);
- s->ddir = le32_to_cpu(s->ddir);
- s->bs = le32_to_cpu(s->bs);
-
- fprintf(f, "%lu, %lu, %u, %u\n",
- (unsigned long) s->time,
- (unsigned long) s->val,
- s->ddir, s->bs);
- }
+ write_log_samples(f, samples, nr);
} while (out.avail_in);
err = inflateEnd(&out);
@@ -619,21 +663,7 @@
#else
static void __finish_log_method(struct io_log *log, FILE *f)
{
- unsigned int i;
-
- for (i = 0; i < log->nr_samples; i++) {
- struct io_sample *s = &log->log[i];
-
- s->time = le64_to_cpu(s->time);
- s->val = le64_to_cpu(s->val);
- s->ddir = le32_to_cpu(s->ddir);
- s->bs = le32_to_cpu(s->bs);
-
- fprintf(f, "%lu, %lu, %u, %u\n",
- (unsigned long) s->time,
- (unsigned long) s->val,
- s->ddir, s->bs);
- }
+ write_log_samples(f, log->log, log->nr_samples);
}
#endif
@@ -676,34 +706,11 @@
#ifdef CONFIG_ZLIB
static void __add_log_sample_gz(struct io_log *iolog, struct io_sample *s)
{
- int ret;
+ if (iolog->nr_batch_samples == BATCH_SAMPLES)
+ flush_batch_samples(iolog);
- iolog->stream.next_in = (void *) s;
- iolog->stream.avail_in = sizeof(*s);
-
- if (iolog->buf_size - iolog->stream.total_out < IOLOG_Z_WINDOW_MIN) {
- void *new_buf;
-
- iolog->buf_size += IOLOG_Z_WINDOW;
- new_buf = realloc(iolog->buf, iolog->buf_size);
- if (!new_buf) {
- log_err("fio: failed extending iolog! Will stop logging.\n");
- iolog->disabled = 1;
- return;
- }
-
- iolog->buf = new_buf;
- }
-
- iolog->stream.avail_out = iolog->buf_size - iolog->stream.total_out;
- iolog->stream.next_out = iolog->buf + iolog->stream.total_out;
-
- ret = deflate(&iolog->stream, Z_NO_FLUSH);
- if (ret < 0) {
- log_err("fio: log deflation failed (%d)\n", ret);
- iolog->disabled = 1;
- }
-
+ memcpy(&iolog->batch_samples[iolog->nr_batch_samples], s, sizeof(*s));
+ ++iolog->nr_batch_samples;
}
#else
static void __add_log_sample_plain(struct io_log *iolog, struct io_sample *s)
diff --git a/iolog.h b/iolog.h
index 0d14e78..dae6b50 100644
--- a/iolog.h
+++ b/iolog.h
@@ -55,6 +55,10 @@
unsigned long nr_samples;
#ifdef CONFIG_ZLIB
+#define BATCH_SAMPLES 64
+ struct io_sample batch_samples[BATCH_SAMPLES];
+ unsigned int nr_batch_samples;
+
void *buf;
unsigned long buf_size;