# compiler: clang
# osx_image: xcode8
# env: SDKROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk MACOSX_DEPLOYMENT_TARGET=10.11
- # Build on the latest OSX version (will eventually become obsolete)
+ # Build on the latest OSX version (will eventually become obsolete)
- os: osx
compiler: clang
osx_image: xcode8.2
.. option:: --parse-only
- Parse options only, don\'t start any I/O.
+ Parse options only, don't start any I/O.
.. option:: --output=filename
``sequential`` is only useful for random I/O, where fio would normally
generate a new random offset for every I/O. If you append e.g. 8 to randread,
- you would get a new random offset for every 8 I/O's. The result would be a
- seek for only every 8 I/O's, instead of for every I/O. Use ``rw=randread:8``
+ you would get a new random offset for every 8 I/Os. The result would be a
+ seek for only every 8 I/Os, instead of for every I/O. Use ``rw=randread:8``
to specify that. As sequential I/O is already sequential, setting
``sequential`` for that would not result in any differences. ``identical``
behaves in a similar fashion, except it sends the same offset 8 number of
.. option:: log_offset=int
If this is set, the iolog options will include the byte offset for the I/O
- entry as well as the other data values.
+ entry as well as the other data values. Defaults to 0 meaning that
+ offsets are not present in logs. Also see `Log File Formats`_.
.. option:: log_compression=int
**ios**
Number of I/Os performed by all groups.
**merge**
- Number of merges I/O the I/O scheduler.
+ Number of merges performed by the I/O scheduler.
**ticks**
Number of ticks we kept the disk busy.
**in_queue**
change.
Split up, the format is as follows (comments in brackets denote when a
-field was introduced or whether its specific to some terse version):
+field was introduced or whether it's specific to some terse version):
::
Fio supports a variety of log file formats, for logging latencies, bandwidth,
and IOPS. The logs share a common format, which looks like this:
- *time* (`msec`), *value*, *data direction*, *offset*
+ *time* (`msec`), *value*, *data direction*, *block size* (`bytes`),
+ *offset* (`bytes`)
-Time for the log entry is always in milliseconds. The *value* logged depends
+*Time* for the log entry is always in milliseconds. The *value* logged depends
on the type of log, it will be one of the following:
**Latency log**
**2**
I/O is a TRIM
-The *offset* is the offset, in bytes, from the start of the file, for that
-particular I/O. The logging of the offset can be toggled with
-:option:`log_offset`.
+The entry's *block size* is always in bytes. The *offset* is the offset, in bytes,
+from the start of the file, for that particular I/O. The logging of the offset can be
+toggled with :option:`log_offset`.
Fio defaults to logging every individual I/O. When IOPS are logged for individual
-I/Os the value entry will always be 1. If windowed logging is enabled through
+I/Os the *value* entry will always be 1. If windowed logging is enabled through
:option:`log_avg_msec`, fio logs the average values over the specified period of time.
If windowed logging is enabled and :option:`log_max_value` is set, then fio logs
-maximum values in that window instead of averages. Since 'data direction' and
-'offset' are per-I/O values, they aren't applicable if windowed logging is enabled.
+maximum values in that window instead of averages. Since *data direction*, *block
+size* and *offset* are per-I/O values, if windowed logging is enabled they
+aren't applicable and will be 0.
Client/Server
-------------
#define nop __asm__ __volatile__ ("nop")
#define read_barrier() __sync_synchronize()
#define write_barrier() __sync_synchronize()
+#else
+#error "unsupported ARM architecture"
#endif
#endif
.. literalinclude:: ../examples/fixed-rate-submission.fio
:language: ini
+
+Butterfly seek pattern
+-----------------------
+
+.. only:: builder_html
+
+:download:`Download butterfly.fio <../examples/butterfly.fio>`
+
+.. literalinclude:: ../examples/butterfly.fio
+ :language: ini
--- /dev/null
+# Perform a butterfly/funnel seek pattern. This won't always alternate ends on
+# every I/O but it will get close.
+
+[global]
+filename=/tmp/testfile
+bs=4k
+direct=1
+
+[forward]
+rw=read
+flow=2
+# Uncomment the size= and offset= lines to prevent each direction going past
+# the middle of the file
+#size=50%
+
+[backward]
+rw=read:-8k
+flow=-2
+#offset=50%
log_err("fio: unknown fallocate mode: %d\n", td->o.fallocate_mode);
assert(0);
}
-
}
/*
Fio defaults to read if the option is not specified.
For mixed I/O, the default split is 50/50. For certain types of io the result
may still be skewed a bit, since the speed may be different. It is possible to
-specify a number of IO's to do before getting a new offset, this is done by
+specify a number of IOs to do before getting a new offset, this is done by
appending a `:\fI<nr>\fR to the end of the string given. For a random read, it
would look like \fBrw=randread:8\fR for passing in an offset modifier with a
value of 8. If the postfix is used with a sequential IO pattern, then the value
.P
\fBsequential\fR is only useful for random IO, where fio would normally
generate a new random offset for every IO. If you append eg 8 to randread, you
-would get a new random offset for every 8 IO's. The result would be a seek for
-only every 8 IO's, instead of for every IO. Use \fBrw=randread:8\fR to specify
+would get a new random offset for every 8 IOs. The result would be a seek for
+only every 8 IOs, instead of for every IO. Use \fBrw=randread:8\fR to specify
that. As sequential IO is already sequential, setting \fBsequential\fR for that
would not result in any differences. \fBidentical\fR behaves in a similar
fashion, except it sends the same offset 8 number of times before generating a
.TP
.BI log_offset \fR=\fPbool
If this is set, the iolog options will include the byte offset for the IO
-entry as well as the other data values.
+entry as well as the other data values. Defaults to 0 meaning that offsets are
+not present in logs. See the \fBLOG FILE FORMATS\fR section.
.TP
.BI log_compression \fR=\fPint
If this is set, fio will compress the IO logs as it goes, to keep the memory
Number of I/Os performed by all groups.
.TP
.B merge
-Number of merges in the I/O scheduler.
+Number of merges performed by the I/O scheduler.
.TP
.B ticks
Number of ticks we kept the disk busy.
Fio supports a variety of log file formats, for logging latencies, bandwidth,
and IOPS. The logs share a common format, which looks like this:
-.B time (msec), value, data direction, offset
+.B time (msec), value, data direction, block size (bytes), offset (bytes)
Time for the log entry is always in milliseconds. The value logged depends
on the type of log, it will be one of the following:
.PD
.P
-The \fIoffset\fR is the offset, in bytes, from the start of the file, for that
-particular IO. The logging of the offset can be toggled with \fBlog_offset\fR.
+The entry's *block size* is always in bytes. The \fIoffset\fR is the offset, in
+bytes, from the start of the file, for that particular IO. The logging of the
+offset can be toggled with \fBlog_offset\fR.
If windowed logging is enabled through \fBlog_avg_msec\fR, then fio doesn't log
individual IOs. Instead of logs the average values over the specified
-period of time. Since \fIdata direction\fR and \fIoffset\fR are per-IO values,
-they aren't applicable if windowed logging is enabled. If windowed logging
-is enabled and \fBlog_max_value\fR is set, then fio logs maximum values in
-that window instead of averages.
+period of time. Since \fIdata direction\fR, \fIblock size\fR and \fIoffset\fR
+are per-IO values, if windowed logging is enabled they aren't applicable and
+will be 0. If windowed logging is enabled and \fBlog_max_value\fR is set, then
+fio logs maximum values in that window instead of averages.
For histogram logging the logs look like this:
fio_clock_source = CS_CPUCLOCK;
} else if (fio_clock_source == CS_CPUCLOCK)
log_info("fio: clocksource=cpu may not be reliable\n");
+ dprint(FD_TIME, "gettime: clocksource=%d\n", (int) fio_clock_source);
}
uint64_t ntime_since(const struct timespec *s, const struct timespec *e)
o->unit_base = 8;
}
+#ifndef FIO_HAVE_ANY_FALLOCATE
+ /* Platform doesn't support any fallocate so force it to none */
+ o->fallocate_mode = FIO_FALLOCATE_NONE;
+#endif
+
#ifndef CONFIG_FDATASYNC
if (o->fdatasync_blocks) {
log_info("fio: this platform does not support fdatasync()"
.parent = "nrfiles",
.hide = 1,
},
-#if defined(CONFIG_POSIX_FALLOCATE) || defined(FIO_HAVE_NATIVE_FALLOCATE)
+#ifdef FIO_HAVE_ANY_FALLOCATE
{
.name = "fallocate",
.lname = "Fallocate",
#endif
},
},
-#else /* CONFIG_POSIX_FALLOCATE */
+#else /* FIO_HAVE_ANY_FALLOCATE */
{
.name = "fallocate",
.lname = "Fallocate",
.type = FIO_OPT_UNSUPPORTED,
.help = "Your platform does not support fallocate",
},
-#endif /* CONFIG_POSIX_FALLOCATE || FIO_HAVE_NATIVE_FALLOCATE */
+#endif /* FIO_HAVE_ANY_FALLOCATE */
{
.name = "fadvise_hint",
.lname = "Fadvise hint",
#include <errno.h>
#include <unistd.h>
+#include <sys/endian.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/statvfs.h>
#include <errno.h>
#include <sys/sysctl.h>
#include <sys/disk.h>
+#include <sys/endian.h>
#include <sys/thr.h>
#include <sys/socket.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/dkio.h>
#include <sys/disklabel.h>
+#include <sys/endian.h>
/* XXX hack to avoid confilcts between rbtree.h and <sys/rb.h> */
#define rb_node _rb_node
#include <sys/sysctl.h>
#include <sys/ioctl.h>
#include <sys/dkio.h>
#include <sys/disklabel.h>
+#include <sys/endian.h>
#include <sys/utsname.h>
/* XXX hack to avoid conflicts between rbtree.h and <sys/tree.h> */
#include <sys/sysctl.h>
}
#endif
+#if defined(CONFIG_POSIX_FALLOCATE) || defined(FIO_HAVE_NATIVE_FALLOCATE)
+# define FIO_HAVE_ANY_FALLOCATE
+#endif
+
#endif