]>
git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/tests/perf/fair_queue_perf.cc
2 * This file is open source software, licensed to you under the terms
3 * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
4 * distributed with this work for additional information regarding copyright
5 * ownership. You may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing,
12 * software distributed under the License is distributed on an
13 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 * KIND, either express or implied. See the License for the
15 * specific language governing permissions and limitations
19 * Copyright (C) 2020 ScyllaDB Ltd.
23 #include <seastar/testing/perf_tests.hh>
24 #include <seastar/core/sharded.hh>
25 #include <seastar/core/thread.hh>
26 #include <seastar/core/fair_queue.hh>
27 #include <seastar/core/semaphore.hh>
28 #include <seastar/core/loop.hh>
29 #include <seastar/core/when_all.hh>
30 #include <boost/range/irange.hpp>
32 static constexpr fair_queue::class_id cid
= 0;
34 struct local_fq_and_class
{
35 seastar::fair_group fg
;
36 seastar::fair_queue fq
;
37 seastar::fair_queue sfq
;
38 unsigned executed
= 0;
40 static fair_group::config
fg_config() {
41 fair_group::config cfg
;
42 cfg
.weight_rate
= std::numeric_limits
<int>::max();
43 cfg
.size_rate
= std::numeric_limits
<int>::max();
47 seastar::fair_queue
& queue(bool local
) noexcept
{ return local
? fq
: sfq
; }
49 local_fq_and_class(seastar::fair_group
& sfg
)
51 , fq(fg
, seastar::fair_queue::config())
52 , sfq(sfg
, seastar::fair_queue::config())
54 fq
.register_priority_class(cid
, 1);
55 sfq
.register_priority_class(cid
, 1);
58 ~local_fq_and_class() {
59 fq
.unregister_priority_class(cid
);
60 sfq
.unregister_priority_class(cid
);
64 struct local_fq_entry
{
65 seastar::fair_queue_entry ent
;
66 std::function
<void()> submit
;
68 template <typename Func
>
69 local_fq_entry(unsigned weight
, unsigned index
, Func
&& f
)
70 : ent(seastar::fair_queue_ticket(weight
, index
))
71 , submit(std::move(f
)) {}
74 struct perf_fair_queue
{
76 static constexpr unsigned requests_to_dispatch
= 1000;
78 seastar::sharded
<local_fq_and_class
> local_fq
;
80 seastar::fair_group shared_fg
;
82 static fair_group::config
fg_config() {
83 fair_group::config cfg
;
84 cfg
.weight_rate
= std::numeric_limits
<int>::max();
85 cfg
.size_rate
= std::numeric_limits
<int>::max();
90 : shared_fg(fg_config())
92 local_fq
.start(std::ref(shared_fg
)).get();
96 local_fq
.stop().get();
99 future
<> test(bool local
);
102 future
<> perf_fair_queue::test(bool loc
) {
104 auto invokers
= local_fq
.invoke_on_all([loc
] (local_fq_and_class
& local
) {
105 return parallel_for_each(boost::irange(0u, requests_to_dispatch
), [&local
, loc
] (unsigned dummy
) {
106 auto req
= std::make_unique
<local_fq_entry
>(1, 1, [&local
, loc
] {
108 local
.queue(loc
).notify_request_finished(seastar::fair_queue_ticket
{1, 1});
110 local
.queue(loc
).queue(cid
, req
->ent
);
112 return make_ready_future
<>();
116 auto collectors
= local_fq
.invoke_on_all([loc
] (local_fq_and_class
& local
) {
117 // Zeroing this counter must be here, otherwise should the collectors win the
118 // execution order in when_all_succeed(), the do_until()'s stopping callback
119 // would return true immediately and the queue would not be dispatched.
121 // At the same time, although this counter is incremented by the lambda from
122 // invokers, it's not called until the fq.dispatch_requests() is, so there's no
123 // opposite problem if zeroing it here.
126 return do_until([&local
] { return local
.executed
== requests_to_dispatch
; }, [&local
, loc
] {
127 local
.queue(loc
).dispatch_requests([] (fair_queue_entry
& ent
) {
128 local_fq_entry
* le
= boost::intrusive::get_parent_from_member(&ent
, &local_fq_entry::ent
);
132 return make_ready_future
<>();
136 return when_all_succeed(std::move(invokers
), std::move(collectors
)).discard_result();
139 PERF_TEST_F(perf_fair_queue
, contended_local
)
143 PERF_TEST_F(perf_fair_queue
, contended_shared
)