Skip to content

Commit

Permalink
iotune: Report disk IOPS instead of kernel IOPS
Browse files Browse the repository at this point in the history
The iotune tool measures disk throughput and IOPS by doing four
sequential measurements:

1. sequentially writes into a big file
2. sequentially reads from the same file
3. randomly writes into this file again
4. randomly reads from, you know, the File

It's improtant that the measurement #1 comes first. On start
the test file is created and truncated to its size and this
first measurement fills it with data which is then read by steps
2 and 4. Respectively, after the 1st measurement the size of
the file should be updated to reflect the real amount of data
written into it.

The latter is done by taking the number of bytes written into
file. But in reality the first test may wrap around the initial
file size and re-write some data into it. After this the file
size can be seen bigger than it actually is, even times bigger.

Subsequently, the next tests will go and read from/write to
random holes in this area. For reading tests this becomes quite
problematic as the kernel will not submit real IO requess for
reads from missing (due to holes) blocks. As a result, the shown
bandwidth and IOPS will be some average value of disk IOPS and
kernel "reads-from-holes-per-second".

Fix this by getting the maximum position at which the first test
writes and limiting the next tests with this value, instead of
the amount of (over-)writter bytes.

Signed-off-by: Pavel Emelyanov <xemul@scylladb.com>
Message-Id: <20200623185120.17694-1-xemul@scylladb.com>
  • Loading branch information
xemul authored and avikivity committed Jun 24, 2020
1 parent e7d8950 commit 8391951
Showing 1 changed file with 6 additions and 5 deletions.
11 changes: 6 additions & 5 deletions apps/iotune/iotune.cc
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ class read_request_issuer : public request_issuer {

class io_worker {
uint64_t _bytes = 0;
uint64_t _max_offset = 0;
unsigned _requests = 0;
size_t _buffer_size;
std::chrono::time_point<iotune_clock, std::chrono::duration<double>> _start_measuring;
Expand Down Expand Up @@ -319,8 +320,10 @@ class io_worker {
}

future<> issue_request(char* buf) {
return _req_impl->issue_request(_pos_impl->get_pos(), buf, _buffer_size).then([this] (size_t size) {
uint64_t pos = _pos_impl->get_pos();
return _req_impl->issue_request(pos, buf, _buffer_size).then([this, pos] (size_t size) {
auto now = iotune_clock::now();
_max_offset = std::max(_max_offset, pos + size);
if ((now > _start_measuring) && (now < _end_measuring)) {
_last_time_seen = now;
_bytes += size;
Expand All @@ -329,9 +332,7 @@ class io_worker {
});
}

uint64_t bytes() const {
return _bytes;
}
uint64_t max_offset() const noexcept { return _max_offset; }

io_rates get_io_rates() const {
io_rates rates;
Expand Down Expand Up @@ -407,7 +408,7 @@ class test_file {
}

if (update_file_size) {
_file_size = worker->bytes();
_file_size = worker->max_offset();
}
return make_ready_future<io_rates>(worker->get_io_rates());
});
Expand Down

0 comments on commit 8391951

Please sign in to comment.