summaryrefslogtreecommitdiffstats
path: root/src/seastar/tests/perf/fstream_perf.cc
blob: b8cf450337ab82d2693c53309bc9ea7e45b0ccdc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  You may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
/*
 * Copyright (C) 2016 ScyllaDB
 */

#include <seastar/core/reactor.hh>
#include <seastar/core/fstream.hh>
#include <seastar/core/file.hh>
#include <seastar/core/app-template.hh>

using namespace seastar;
using namespace std::chrono_literals;

int main(int ac, char** av) {
    app_template at;
    namespace bpo = boost::program_options;
    at.add_options()
            ("concurrency", bpo::value<unsigned>()->default_value(1), "Write operations to issue in parallel")
            ("buffer-size", bpo::value<size_t>()->default_value(4096), "Write buffer size")
            ("total-ops", bpo::value<unsigned>()->default_value(100000), "Total write operations to issue")
            ("sloppy-size", bpo::value<bool>()->default_value(false), "Enable the sloppy-size optimization")
            ;
    return at.run(ac, av, [&at] {
        auto concurrency = at.configuration()["concurrency"].as<unsigned>();
        auto buffer_size = at.configuration()["buffer-size"].as<size_t>();
        auto total_ops = at.configuration()["total-ops"].as<unsigned>();
        auto sloppy_size = at.configuration()["sloppy-size"].as<bool>();
        file_open_options foo;
        foo.sloppy_size = sloppy_size;
        return open_file_dma(
                "testfile.tmp", open_flags::wo | open_flags::create | open_flags::exclusive,
                foo).then([=] (file f) {
            file_output_stream_options foso;
            foso.buffer_size = buffer_size;
            foso.preallocation_size = 32 << 20;
            foso.write_behind = concurrency;
            auto os = make_file_output_stream(f, foso);
            return do_with(std::move(os), std::move(f), unsigned(0), [=] (output_stream<char>& os, file& f, unsigned& completed) {
                auto start = std::chrono::steady_clock::now();
                return repeat([=, &os, &completed] {
                    if (completed == total_ops) {
                        return make_ready_future<stop_iteration>(stop_iteration::yes);
                    }
                    char buf[buffer_size];
                    memset(buf, 0, buffer_size);
                    return os.write(buf, buffer_size).then([&completed] {
                        ++completed;
                        return stop_iteration::no;
                    });
                }).then([=, &os] {
                    auto end = std::chrono::steady_clock::now();
                    using fseconds = std::chrono::duration<float, std::ratio<1, 1>>;
                    auto iops = total_ops / std::chrono::duration_cast<fseconds>(end - start).count();
                    fmt::print("{:10} {:10} {:10} {:12}\n", "bufsize", "ops", "iodepth", "IOPS");
                    fmt::print("{:10d} {:10d} {:10d} {:12.0f}\n", buffer_size, total_ops, concurrency, iops);
                    return os.flush();
                }).then([&os] {
                    return os.close();
                });
            });
        });
    });
}