1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
5 * Copyright (C) 2016 Red Hat Inc.
7 * Author: J. Eric Ivancich <ivancich@redhat.com>
9 * This is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License version
11 * 2.1, as published by the Free Software Foundation. See file
16 #include "test_ssched.h"
24 namespace test
= crimson::test_simple_scheduler
;
25 namespace ssched
= crimson::simple_scheduler
;
26 namespace sim
= crimson::qos_simulation
;
28 using namespace std::placeholders
;
32 namespace test_simple_scheduler
{
33 void client_data(std::ostream
& out
,
35 test::MySim::ClientFilter client_disp_filter
,
36 int head_w
, int data_w
, int data_prec
);
38 void server_data(std::ostream
& out
,
40 test::MySim::ServerFilter server_disp_filter
,
41 int head_w
, int data_w
, int data_prec
);
42 } // namespace test_simple
43 } // namespace crimson
46 using Cost
= uint32_t;
49 int main(int argc
, char* argv
[]) {
52 const unsigned server_count
= 100;
53 const unsigned server_iops
= 40;
54 const unsigned server_threads
= 1;
58 const unsigned client_total_ops
= 1000;
59 const unsigned client_count
= 100;
60 const unsigned client_server_select_range
= 10;
61 const unsigned client_wait_count
= 1;
62 const unsigned client_iops_goal
= 50;
63 const unsigned client_outstanding_ops
= 100;
64 const std::chrono::seconds
client_wait(10);
66 auto client_disp_filter
= [=] (const ClientId
& i
) -> bool {
67 return i
< 3 || i
>= (client_count
- 3);
70 auto server_disp_filter
= [=] (const ServerId
& i
) -> bool {
71 return i
< 3 || i
>= (server_count
- 3);
75 test::MySim
*simulation
;
77 // lambda to post a request to the identified server; called by client
78 test::SubmitFunc server_post_f
=
79 [&simulation
](const ServerId
& server_id
,
80 sim::TestRequest
&& request
,
81 const ClientId
& client_id
,
82 const ssched::ReqParams
& req_params
) {
83 auto& server
= simulation
->get_server(server_id
);
84 server
.post(std::move(request
), client_id
, req_params
, 1u);
87 static std::vector
<sim::CliInst
> no_wait
=
88 { { sim::req_op
, client_total_ops
, client_iops_goal
, client_outstanding_ops
} };
89 static std::vector
<sim::CliInst
> wait
=
90 { { sim::wait_op
, client_wait
},
91 { sim::req_op
, client_total_ops
, client_iops_goal
, client_outstanding_ops
} };
93 simulation
= new test::MySim();
96 test::MySim::ClientBasedServerSelectFunc server_select_f
=
97 simulation
->make_server_select_alt_range(client_server_select_range
);
99 test::MySim::ClientBasedServerSelectFunc server_select_f
=
100 std::bind(&test::MySim::server_select_random
, simulation
, _1
, _2
);
102 test::MySim::ClientBasedServerSelectFunc server_select_f
=
103 std::bind(&test::MySim::server_select_0
, simulation
, _1
, _2
);
106 test::SimpleServer::ClientRespFunc client_response_f
=
107 [&simulation
](ClientId client_id
,
108 const sim::TestResponse
& resp
,
109 const ServerId
& server_id
,
110 const ssched::NullData
& resp_params
,
112 simulation
->get_client(client_id
).receive_response(resp
,
118 test::CreateQueueF create_queue_f
=
119 [&](test::SimpleQueue::CanHandleRequestFunc can_f
,
120 test::SimpleQueue::HandleRequestFunc handle_f
) -> test::SimpleQueue
* {
121 return new test::SimpleQueue(can_f
, handle_f
);
124 auto create_server_f
= [&](ServerId id
) -> test::SimpleServer
* {
125 return new test::SimpleServer(id
,
126 server_iops
, server_threads
,
128 test::simple_server_accumulate_f
,
132 auto create_client_f
= [&](ClientId id
) -> test::SimpleClient
* {
133 return new test::SimpleClient(id
,
135 std::bind(server_select_f
, _1
, id
),
136 test::simple_client_accumulate_f
,
137 id
< (client_count
- client_wait_count
)
141 simulation
->add_servers(server_count
, create_server_f
);
142 simulation
->add_clients(client_count
, create_client_f
);
145 simulation
->display_stats(std::cout
,
146 &test::server_data
, &test::client_data
,
147 server_disp_filter
, client_disp_filter
);
151 void test::client_data(std::ostream
& out
,
153 test::MySim::ClientFilter client_disp_filter
,
154 int head_w
, int data_w
, int data_prec
) {
159 void test::server_data(std::ostream
& out
,
161 test::MySim::ServerFilter server_disp_filter
,
162 int head_w
, int data_w
, int data_prec
) {
163 out
<< std::setw(head_w
) << "requests:";
165 for (unsigned i
= 0; i
< sim
->get_server_count(); ++i
) {
166 const auto& server
= sim
->get_server(i
);
167 auto req_count
= server
.get_accumulator().request_count
;
168 total_req
+= req_count
;
169 if (!server_disp_filter(i
)) continue;
170 out
<< std::setw(data_w
) << req_count
;
172 out
<< std::setw(data_w
) << std::setprecision(data_prec
) <<
173 std::fixed
<< total_req
<< std::endl
;
176 crimson::ProfileCombiner
<std::chrono::nanoseconds
> art_combiner
;
177 crimson::ProfileCombiner
<std::chrono::nanoseconds
> rct_combiner
;
178 for (unsigned i
= 0; i
< sim
->get_server_count(); ++i
) {
179 const auto& q
= sim
->get_server(i
).get_priority_queue();
180 const auto& art
= q
.add_request_timer
;
181 art_combiner
.combine(art
);
182 const auto& rct
= q
.request_complete_timer
;
183 rct_combiner
.combine(rct
);
185 out
<< "Server add_request_timer: count:" << art_combiner
.get_count() <<
186 ", mean:" << art_combiner
.get_mean() <<
187 ", std_dev:" << art_combiner
.get_std_dev() <<
188 ", low:" << art_combiner
.get_low() <<
189 ", high:" << art_combiner
.get_high() << std::endl
;
190 out
<< "Server request_complete_timer: count:" << rct_combiner
.get_count() <<
191 ", mean:" << rct_combiner
.get_mean() <<
192 ", std_dev:" << rct_combiner
.get_std_dev() <<
193 ", low:" << rct_combiner
.get_low() <<
194 ", high:" << rct_combiner
.get_high() << std::endl
;
195 out
<< "Server combined mean: " <<
196 (art_combiner
.get_mean() + rct_combiner
.get_mean()) <<