diff --git a/sim/dmc_sim_example.conf b/sim/dmc_sim_example.conf index 989f2f0..e98b870 100644 --- a/sim/dmc_sim_example.conf +++ b/sim/dmc_sim_example.conf @@ -1,6 +1,6 @@ [global] server_groups = 1 -client_groups = 3 +client_groups = 4 server_random_selection = false server_soft_limit = false @@ -36,6 +36,19 @@ client_outstanding_ops = 32 client_reservation = 0.0 client_limit = 50.0 client_weight = 2.0 +client_req_cost = 1 + +[client.3] +client_count = 1 +client_wait = 10 +client_total_ops = 2000 +client_server_select_range = 1 +client_iops_goal = 200 +client_outstanding_ops = 32 +client_reservation = 0.0 +client_limit = 50.0 +client_weight = 2.0 +client_req_cost = 3 [server.0] server_count = 1 diff --git a/sim/src/config.cc b/sim/src/config.cc index 79a7b28..c1769b8 100644 --- a/sim/src/config.cc +++ b/sim/src/config.cc @@ -175,6 +175,8 @@ int crimson::qos_simulation::parse_config_file(const std::string &fname, sim_con ct.client_limit = std::stod(val); if (!cf.read(section, "client_weight", val)) ct.client_weight = std::stod(val); + if (!cf.read(section, "client_req_cost", val)) + ct.client_req_cost = std::stoul(val); g_conf.cli_group.push_back(ct); } diff --git a/sim/src/config.h b/sim/src/config.h index 41a675e..8bb8218 100644 --- a/sim/src/config.h +++ b/sim/src/config.h @@ -37,6 +37,7 @@ namespace crimson { double client_reservation; double client_limit; double client_weight; + uint64_t client_req_cost; cli_group_t(uint _client_count = 100, uint _client_wait = 0, @@ -46,7 +47,8 @@ namespace crimson { uint _client_outstanding_ops = 100, double _client_reservation = 20.0, double _client_limit = 60.0, - double _client_weight = 1.0) : + double _client_weight = 1.0, + uint64_t _client_req_cost = 1u) : client_count(_client_count), client_wait(std::chrono::seconds(_client_wait)), client_total_ops(_client_total_ops), @@ -55,7 +57,8 @@ namespace crimson { client_outstanding_ops(_client_outstanding_ops), client_reservation(_client_reservation), client_limit(_client_limit), - client_weight(_client_weight) + client_weight(_client_weight), + client_req_cost(_client_req_cost) { // empty } @@ -72,7 +75,8 @@ namespace crimson { std::fixed << std::setprecision(1) << "client_reservation = " << cli_group.client_reservation << "\n" << "client_limit = " << cli_group.client_limit << "\n" << - "client_weight = " << cli_group.client_weight; + "client_weight = " << cli_group.client_weight << "\n" << + "client_req_cost = " << cli_group.client_req_cost; return out; } }; // class cli_group_t diff --git a/sim/src/sim_client.h b/sim/src/sim_client.h index 328fe18..fd4d2a0 100644 --- a/sim/src/sim_client.h +++ b/sim/src/sim_client.h @@ -112,6 +112,7 @@ namespace crimson { TestResponse response; ServerId server_id; RespPm resp_params; + uint64_t request_cost; }; const ClientId id; @@ -202,9 +203,11 @@ namespace crimson { void receive_response(const TestResponse& resp, const ServerId& server_id, - const RespPm& resp_params) { + const RespPm& resp_params, + uint64_t request_cost) { RespGuard g(mtx_resp); - resp_queue.push_back(RespQueueItem{resp, server_id, resp_params}); + resp_queue.push_back( + RespQueueItem{ resp, server_id, resp_params, request_cost }); cv_resp.notify_one(); } @@ -300,7 +303,7 @@ namespace crimson { time_stats(internal_stats.mtx, internal_stats.track_resp_time, [&](){ - service_tracker.track_resp(item.server_id, item.resp_params); + service_tracker.track_resp(item.server_id, item.resp_params, item.request_cost); }); count_stats(internal_stats.mtx, internal_stats.track_resp_count); diff --git a/sim/src/sim_server.h b/sim/src/sim_server.h index 9d2d5a2..d7c450e 100644 --- a/sim/src/sim_server.h +++ b/sim/src/sim_server.h @@ -35,13 +35,16 @@ namespace crimson { ClientId client; std::unique_ptr request; RespPm additional; + uint64_t request_cost; QueueItem(const ClientId& _client, std::unique_ptr&& _request, - const RespPm& _additional) : + const RespPm& _additional, + uint64_t _request_cost) : client(_client), request(std::move(_request)), - additional(_additional) + additional(_additional), + request_cost(_request_cost) { // empty } @@ -69,7 +72,8 @@ namespace crimson { using ClientRespFunc = std::function; + const RespPm&, + uint64_t)>; using ServerAccumFunc = std::function; @@ -105,7 +109,7 @@ namespace crimson { using CanHandleRequestFunc = std::function; using HandleRequestFunc = - std::function,const RespPm&)>; + std::function,const RespPm&, uint64_t)>; using CreateQueueF = std::function; @@ -122,7 +126,8 @@ namespace crimson { this, std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3))), + std::placeholders::_3, + std::placeholders::_4))), client_resp_f(_client_resp_f), iops(_iops), thread_pool_size(_thread_pool_size), @@ -156,13 +161,16 @@ namespace crimson { void post(TestRequest&& request, const ClientId& client_id, - const ReqPm& req_params) + const ReqPm& req_params, + uint64_t request_cost) { time_stats(internal_stats.mtx, internal_stats.add_request_time, [&](){ priority_queue->add_request(std::move(request), - client_id, req_params); + client_id, + req_params, + request_cost); }); count_stats(internal_stats.mtx, internal_stats.add_request_count); @@ -181,13 +189,15 @@ namespace crimson { void inner_post(const ClientId& client, std::unique_ptr request, - const RespPm& additional) { + const RespPm& additional, + uint64_t request_cost) { Lock l(inner_queue_mtx); assert(!finishing); accum_f(accumulator, additional); inner_queue.emplace_back(QueueItem(client, std::move(request), - additional)); + additional, + request_cost)); inner_queue_cv.notify_one(); } @@ -202,17 +212,18 @@ namespace crimson { auto client = front.client; auto req = std::move(front.request); auto additional = front.additional; + auto request_cost = front.request_cost; inner_queue.pop_front(); l.unlock(); // simulation operation by sleeping; then call function to // notify server of completion - std::this_thread::sleep_for(op_time); + std::this_thread::sleep_for(op_time * request_cost); // TODO: rather than assuming this constructor exists, perhaps // pass in a function that does this mapping? - client_resp_f(client, TestResponse{req->epoch}, id, additional); + client_resp_f(client, TestResponse{req->epoch}, id, additional, request_cost); time_stats(internal_stats.mtx, internal_stats.request_complete_time, diff --git a/sim/src/ssched/ssched_client.h b/sim/src/ssched/ssched_client.h index 89ff148..91f2273 100644 --- a/sim/src/ssched/ssched_client.h +++ b/sim/src/ssched/ssched_client.h @@ -34,12 +34,12 @@ namespace crimson { // emptry } - - void track_resp(const S& server_id, const NullData& ignore) { + void track_resp(const S& server_id, + const NullData& ignore, + uint64_t request_cost) { // empty } - /* * Returns the ReqParams for the given server. */ diff --git a/sim/src/ssched/ssched_server.h b/sim/src/ssched/ssched_server.h index dc49628..c4e057a 100644 --- a/sim/src/ssched/ssched_server.h +++ b/sim/src/ssched/ssched_server.h @@ -45,7 +45,7 @@ namespace crimson { // a function to submit a request to the server; the second // parameter is a callback when it's completed using HandleRequestFunc = - std::function; + std::function; struct PullReq { enum class Type { returning, none }; @@ -111,14 +111,16 @@ namespace crimson { void add_request(R&& request, const C& client_id, - const ReqParams& req_params) { + const ReqParams& req_params, + uint64_t request_cost) { add_request(RequestRef(new R(std::move(request))), - client_id, req_params); + client_id, req_params, request_cost); } void add_request(RequestRef&& request, const C& client_id, - const ReqParams& req_params) { + const ReqParams& req_params, + uint64_t request_cost) { DataGuard g(queue_mtx); #ifdef PROFILE @@ -183,7 +185,7 @@ namespace crimson { if (!queue.empty() && can_handle_f()) { auto& front = queue.front(); static NullData null_data; - handle_f(front.client, std::move(front.request), null_data); + handle_f(front.client, std::move(front.request), null_data, 1u); queue.pop_front(); } } diff --git a/sim/src/test_dmclock.h b/sim/src/test_dmclock.h index 1bbe5f7..1c7a559 100644 --- a/sim/src/test_dmclock.h +++ b/sim/src/test_dmclock.h @@ -36,7 +36,7 @@ namespace crimson { }; using DmcQueue = dmc::PushPriorityQueue; - using DmcServiceTracker = dmc::ServiceTracker; + using DmcServiceTracker = dmc::ServiceTracker; using DmcServer = sim::SimulatedServer const test::dmc::ClientInfo* { + auto client_info_f = + [=](const ClientId& c) -> const test::dmc::ClientInfo* { return &client_info[ret_client_group_f(c)]; }; @@ -143,12 +144,16 @@ int main(int argc, char* argv[]) { // lambda to post a request to the identified server; called by client test::SubmitFunc server_post_f = - [&simulation](const ServerId& server, - sim::TestRequest&& request, - const ClientId& client_id, - const test::dmc::ReqParams& req_params) { - test::DmcServer& s = simulation->get_server(server); - s.post(std::move(request), client_id, req_params); + [&simulation, + &cli_group, + &ret_client_group_f](const ServerId& server, + sim::TestRequest&& request, + const ClientId& client_id, + const test::dmc::ReqParams& req_params) { + test::DmcServer& s = simulation->get_server(server); + uint64_t request_cost = + cli_group[ret_client_group_f(client_id)].client_req_cost; + s.post(std::move(request), client_id, req_params, request_cost); }; std::vector> cli_inst; @@ -175,10 +180,12 @@ int main(int argc, char* argv[]) { [&simulation](ClientId client_id, const sim::TestResponse& resp, const ServerId& server_id, - const dmc::PhaseType& phase) { + const dmc::PhaseType& phase, + uint64_t request_cost) { simulation->get_client(client_id).receive_response(resp, server_id, - phase); + phase, + request_cost); }; test::CreateQueueF create_queue_f = diff --git a/sim/src/test_ssched_main.cc b/sim/src/test_ssched_main.cc index 82bc381..a496106 100644 --- a/sim/src/test_ssched_main.cc +++ b/sim/src/test_ssched_main.cc @@ -78,7 +78,7 @@ int main(int argc, char* argv[]) { const ClientId& client_id, const ssched::ReqParams& req_params) { auto& server = simulation->get_server(server_id); - server.post(std::move(request), client_id, req_params); + server.post(std::move(request), client_id, req_params, 1u); }; static std::vector no_wait = @@ -104,10 +104,12 @@ int main(int argc, char* argv[]) { [&simulation](ClientId client_id, const sim::TestResponse& resp, const ServerId& server_id, - const ssched::NullData& resp_params) { + const ssched::NullData& resp_params, + uint64_t request_cost) { simulation->get_client(client_id).receive_response(resp, server_id, - resp_params); + resp_params, + request_cost); }; test::CreateQueueF create_queue_f = diff --git a/src/dmclock_client.h b/src/dmclock_client.h index 7cebd9e..1c1227a 100644 --- a/src/dmclock_client.h +++ b/src/dmclock_client.h @@ -45,7 +45,7 @@ namespace crimson { public: OrigTracker(Counter global_delta, - Counter global_rho) : + Counter global_rho) : delta_prev_req(global_delta), rho_prev_req(global_rho), my_delta(0), @@ -57,8 +57,8 @@ namespace crimson { } inline ReqParams prepare_req(Counter& the_delta, Counter& the_rho) { - Counter delta_out = 1 + the_delta - delta_prev_req - my_delta; - Counter rho_out = 1 + the_rho - rho_prev_req - my_rho; + Counter delta_out = the_delta - delta_prev_req - my_delta; + Counter rho_out = the_rho - rho_prev_req - my_rho; delta_prev_req = the_delta; rho_prev_req = the_rho; my_delta = 0; @@ -68,12 +68,13 @@ namespace crimson { inline void resp_update(PhaseType phase, Counter& the_delta, - Counter& the_rho) { - ++the_delta; - ++my_delta; + Counter& the_rho, + Counter cost) { + the_delta += cost; + my_delta += cost; if (phase == PhaseType::reservation) { - ++the_rho; - ++my_rho; + the_rho += cost; + my_rho += cost; } } @@ -139,10 +140,11 @@ namespace crimson { inline void resp_update(PhaseType phase, Counter& the_delta, - Counter& the_rho) { - ++the_delta; + Counter& the_rho, + Counter cost) { + the_delta += cost; if (phase == PhaseType::reservation) { - ++the_rho; + the_rho += cost; } } @@ -152,9 +154,13 @@ namespace crimson { }; // struct BorrowingTracker - // S is server identifier type - // T is the server info class that adheres to ServerTrackerIfc interface - template + /* + * S is server identifier type + * + * T is the server info class that adheres to ServerTrackerIfc + * interface + */ + template class ServiceTracker { // we don't want to include gtest.h just for FRIEND_TEST friend class dmclock_client_server_erase_Test; @@ -210,9 +216,11 @@ namespace crimson { /* - * Incorporates the RespParams received into the various counter. + * Incorporates the response data received into the counters. */ - void track_resp(const S& server_id, const PhaseType& phase) { + void track_resp(const S& server_id, + const PhaseType& phase, + Counter request_cost = 1u) { DataGuard g(data_mtx); auto it = server_map.find(server_id); @@ -224,7 +232,7 @@ namespace crimson { T::create(delta_counter, rho_counter)); it = i.first; } - it->second.resp_update(phase, delta_counter, rho_counter); + it->second.resp_update(phase, delta_counter, rho_counter, request_cost); } /* diff --git a/src/dmclock_recs.h b/src/dmclock_recs.h index 4b574f8..e5685fd 100644 --- a/src/dmclock_recs.h +++ b/src/dmclock_recs.h @@ -32,21 +32,21 @@ namespace crimson { } struct ReqParams { - // count of all replies since last request; MUSTN'T BE 0 + // count of all replies since last request uint32_t delta; - // count of reservation replies since last request; MUSTN'T BE 0 + // count of reservation replies since last request uint32_t rho; ReqParams(uint32_t _delta, uint32_t _rho) : delta(_delta), rho(_rho) { - assert(0 != delta && 0 != rho && rho <= delta); + assert(rho <= delta); } ReqParams() : - ReqParams(1, 1) + ReqParams(0, 0) { // empty } diff --git a/src/dmclock_server.h b/src/dmclock_server.h index 39a6b78..8e99425 100644 --- a/src/dmclock_server.h +++ b/src/dmclock_server.h @@ -72,6 +72,12 @@ namespace crimson { std::numeric_limits::lowest(); constexpr uint tag_modulo = 1000000; + // we're abstracting cost to its own type to better allow for + // future changes; we're assuming that Cost is relatively small + // and that it would be more efficient to pass-by-value than + // by-reference. + using Cost = uint64_t; + struct ClientInfo { double reservation; // minimum double weight; // proportional @@ -112,41 +118,47 @@ namespace crimson { struct RequestTag { - double reservation; - double proportion; - double limit; - bool ready; // true when within limit - Time arrival; + double reservation; + double proportion; + double limit; + Cost cost; + bool ready; // true when within limit + Time arrival; RequestTag(const RequestTag& prev_tag, const ClientInfo& client, const uint32_t delta, const uint32_t rho, const Time time, - const double cost = 0.0, + const Cost _cost = 1u, const double anticipation_timeout = 0.0) : + cost(_cost), ready(false), arrival(time) { + assert(cost > 0); Time max_time = time; if (time - anticipation_timeout < prev_tag.arrival) max_time -= anticipation_timeout; - reservation = cost + tag_calc(max_time, - prev_tag.reservation, - client.reservation_inv, - rho, - true); + reservation = tag_calc(max_time, + prev_tag.reservation, + client.reservation_inv, + rho, + true, + cost); proportion = tag_calc(max_time, prev_tag.proportion, client.weight_inv, delta, - true); + true, + cost); limit = tag_calc(max_time, prev_tag.limit, client.limit_inv, delta, - false); + false, + cost); assert(reservation < max_tag || proportion < max_tag); } @@ -155,19 +167,23 @@ namespace crimson { const ClientInfo& client, const ReqParams req_params, const Time time, - const double cost = 0.0, + const Cost cost = 1u, const double anticipation_timeout = 0.0) : RequestTag(prev_tag, client, req_params.delta, req_params.rho, time, cost, anticipation_timeout) { /* empty */ } - RequestTag(double _res, double _prop, double _lim, const Time _arrival) : + RequestTag(const double _res, const double _prop, const double _lim, + const Time _arrival, + const Cost _cost = 1u) : reservation(_res), proportion(_prop), limit(_lim), + cost(_cost), ready(false), arrival(_arrival) { + assert(cost > 0); assert(reservation < max_tag || proportion < max_tag); } @@ -175,11 +191,10 @@ namespace crimson { reservation(other.reservation), proportion(other.proportion), limit(other.limit), + cost(other.cost), ready(other.ready), arrival(other.arrival) - { - // empty - } + { /* empty */ } static std::string format_tag_change(double before, double after) { if (before == after) { @@ -204,17 +219,16 @@ namespace crimson { private: static double tag_calc(const Time time, - double prev, - double increment, - uint32_t dist_req_val, - bool extreme_is_high) { + const double prev, + const double increment, + const uint32_t dist_req_val, + const bool extreme_is_high, + const Cost cost) { if (0.0 == increment) { return extreme_is_high ? max_tag : min_tag; } else { - if (0 != dist_req_val) { - increment *= dist_req_val; - } - return std::max(time, prev + increment); + double tag_increment = increment * (dist_req_val + cost); + return std::max(time, prev + tag_increment); } } @@ -808,7 +822,7 @@ namespace crimson { const C& client_id, const ReqParams& req_params, const Time time, - const double cost = 0.0) { + const Cost cost = 1u) { ++tick; // this pointer will help us create a reference to a shared @@ -886,7 +900,7 @@ namespace crimson { } // if this client was idle #ifndef DO_NOT_DELAY_TAG_CALC - RequestTag tag(0, 0, 0, time); + RequestTag tag(0, 0, 0, time, cost); if (!client.has_request()) { const ClientInfo* client_info = get_cli_info(client); @@ -945,10 +959,12 @@ namespace crimson { template void pop_process_request(IndIntruHeap& heap, std::function process) { // gain access to data ClientRec& top = heap.top(); + Cost request_cost = top.next_request().tag.cost; RequestRef request = std::move(top.next_request().request); #ifndef DO_NOT_DELAY_TAG_CALC RequestTag tag = top.next_request().tag; @@ -965,7 +981,8 @@ namespace crimson { next_first.tag = RequestTag(tag, *client_info, top.cur_delta, top.cur_rho, next_first.tag.arrival, - 0.0, anticipation_timeout); + next_first.tag.cost, + anticipation_timeout); // copy tag to previous tag for client top.update_req_tag(next_first.tag, tick); @@ -980,7 +997,7 @@ namespace crimson { ready_heap.demote(top); // process - process(top.client, request); + process(top.client, request_cost, request); } // pop_process_request @@ -1171,9 +1188,10 @@ namespace crimson { // When a request is pulled, this is the return type. struct PullReq { struct Retn { - C client; - typename super::RequestRef request; - PhaseType phase; + C client; + typename super::RequestRef request; + PhaseType phase; + Cost cost; }; typename super::NextReqType type; @@ -1229,63 +1247,62 @@ namespace crimson { inline void add_request(R&& request, const C& client_id, const ReqParams& req_params, - double addl_cost = 0.0) { + const Cost cost = 1u) { add_request(typename super::RequestRef(new R(std::move(request))), client_id, req_params, get_time(), - addl_cost); + cost); } inline void add_request(R&& request, const C& client_id, - double addl_cost = 0.0) { + const Cost cost = 1u) { static const ReqParams null_req_params; add_request(typename super::RequestRef(new R(std::move(request))), client_id, null_req_params, get_time(), - addl_cost); + cost); } - inline void add_request_time(R&& request, const C& client_id, const ReqParams& req_params, const Time time, - double addl_cost = 0.0) { + const Cost cost = 1u) { add_request(typename super::RequestRef(new R(std::move(request))), client_id, req_params, time, - addl_cost); + cost); } inline void add_request(typename super::RequestRef&& request, const C& client_id, const ReqParams& req_params, - double addl_cost = 0.0) { - add_request(request, req_params, client_id, get_time(), addl_cost); + const Cost cost = 1u) { + add_request(request, req_params, client_id, get_time(), cost); } inline void add_request(typename super::RequestRef&& request, const C& client_id, - double addl_cost = 0.0) { + const Cost cost = 1u) { static const ReqParams null_req_params; - add_request(request, null_req_params, client_id, get_time(), addl_cost); + add_request(request, null_req_params, client_id, get_time(), cost); } // this does the work; the versions above provide alternate interfaces void add_request(typename super::RequestRef&& request, - const C& client_id, - const ReqParams& req_params, - const Time time, - double addl_cost = 0.0) { + const C& client_id, + const ReqParams& req_params, + const Time time, + const Cost cost = 1u) { typename super::DataGuard g(this->data_mtx); #ifdef PROFILE add_request_timer.start(); @@ -1294,7 +1311,7 @@ namespace crimson { client_id, req_params, time, - addl_cost); + cost); // no call to schedule_request for pull version #ifdef PROFILE add_request_timer.stop(); @@ -1307,7 +1324,7 @@ namespace crimson { } - PullReq pull_request(Time now) { + PullReq pull_request(const Time now) { PullReq result; typename super::DataGuard g(this->data_mtx); #ifdef PROFILE @@ -1334,18 +1351,23 @@ namespace crimson { auto process_f = [&] (PullReq& pull_result, PhaseType phase) -> std::function { return [&pull_result, phase](const C& client, + const Cost request_cost, typename super::RequestRef& request) { - pull_result.data = - typename PullReq::Retn{client, std::move(request), phase}; + pull_result.data = typename PullReq::Retn{ client, + std::move(request), + phase, + request_cost }; }; }; switch(next.heap_id) { case super::HeapId::reservation: super::pop_process_request(this->resv_heap, - process_f(result, PhaseType::reservation)); + process_f(result, + PhaseType::reservation)); ++this->reserv_sched_count; break; case super::HeapId::ready: @@ -1396,7 +1418,7 @@ namespace crimson { // a function to submit a request to the server; the second // parameter is a callback when it's completed using HandleRequestFunc = - std::function; + std::function; protected: @@ -1470,20 +1492,20 @@ namespace crimson { inline void add_request(R&& request, const C& client_id, const ReqParams& req_params, - double addl_cost = 0.0) { + const Cost cost = 1u) { add_request(typename super::RequestRef(new R(std::move(request))), client_id, req_params, get_time(), - addl_cost); + cost); } inline void add_request(typename super::RequestRef&& request, const C& client_id, const ReqParams& req_params, - double addl_cost = 0.0) { - add_request(request, req_params, client_id, get_time(), addl_cost); + const Cost cost = 1u) { + add_request(request, req_params, client_id, get_time(), cost); } @@ -1491,12 +1513,12 @@ namespace crimson { const C& client_id, const ReqParams& req_params, const Time time, - double addl_cost = 0.0) { + const Cost cost = 1u) { add_request(typename super::RequestRef(new R(request)), client_id, req_params, time, - addl_cost); + cost); } @@ -1504,7 +1526,7 @@ namespace crimson { const C& client_id, const ReqParams& req_params, const Time time, - double addl_cost = 0.0) { + const Cost cost = 1u) { typename super::DataGuard g(this->data_mtx); #ifdef PROFILE add_request_timer.start(); @@ -1513,7 +1535,7 @@ namespace crimson { client_id, req_params, time, - addl_cost); + cost); schedule_request(); #ifdef PROFILE add_request_timer.stop(); @@ -1554,9 +1576,10 @@ namespace crimson { super::pop_process_request(heap, [this, phase, &client_result] (const C& client, + const Cost request_cost, typename super::RequestRef& request) { client_result = client; - handle_f(client, std::move(request), phase); + handle_f(client, std::move(request), phase, request_cost); }); return client_result; } diff --git a/test/test_dmclock_client.cc b/test/test_dmclock_client.cc index 8be3eaa..5884045 100644 --- a/test/test_dmclock_client.cc +++ b/test/test_dmclock_client.cc @@ -105,7 +105,7 @@ namespace crimson { } // TEST - TEST(dmclock_client, delta_rho_values) { + TEST(dmclock_client, delta_rho_values_borrowing_tracker) { using ServerId = int; // using ClientId = int; @@ -115,8 +115,8 @@ namespace crimson { // RespParams resp_params(server, dmc::PhaseType::reservation); - dmc::ServiceTracker st(std::chrono::seconds(2), - std::chrono::seconds(3)); + dmc::ServiceTracker st(std::chrono::seconds(2), + std::chrono::seconds(3)); auto rp1 = st.get_req_params(server1); EXPECT_EQ(1u, rp1.delta) << @@ -136,7 +136,7 @@ namespace crimson { "other servers"; // RESPONSE - st.track_resp(server1, dmc::PhaseType::priority); + st.track_resp(server1, dmc::PhaseType::priority, 1u); auto rp3 = st.get_req_params(server1); @@ -148,7 +148,7 @@ namespace crimson { "other servers"; // RESPONSE - st.track_resp(server2, dmc::PhaseType::priority); + st.track_resp(server2, dmc::PhaseType::priority, 1u); auto rp4 = st.get_req_params(server1); @@ -169,7 +169,7 @@ namespace crimson { "other servers"; // RESPONSE - st.track_resp(server2, dmc::PhaseType::reservation); + st.track_resp(server2, dmc::PhaseType::reservation, 1u); auto rp6 = st.get_req_params(server1); @@ -180,13 +180,13 @@ namespace crimson { "rho should be 2 with one intervening reservation responses by " << "another server"; - st.track_resp(server2, dmc::PhaseType::reservation); - st.track_resp(server1, dmc::PhaseType::priority); - st.track_resp(server2, dmc::PhaseType::priority); - st.track_resp(server2, dmc::PhaseType::reservation); - st.track_resp(server1, dmc::PhaseType::reservation); - st.track_resp(server1, dmc::PhaseType::priority); - st.track_resp(server2, dmc::PhaseType::priority); + st.track_resp(server2, dmc::PhaseType::reservation, 1u); + st.track_resp(server1, dmc::PhaseType::priority, 1u); + st.track_resp(server2, dmc::PhaseType::priority, 1u); + st.track_resp(server2, dmc::PhaseType::reservation, 1u); + st.track_resp(server1, dmc::PhaseType::reservation, 1u); + st.track_resp(server1, dmc::PhaseType::priority, 1u); + st.track_resp(server2, dmc::PhaseType::priority, 1u); auto rp7 = st.get_req_params(server1); @@ -228,7 +228,7 @@ namespace crimson { // NB: the BorrowingTracker has not been fully tested and the // expected values below have not yet been compared with the // theoretically correct values. - TEST(dmclock_client, orig_tracker_delta_rho_values) { + TEST(dmclock_client, delta_rho_values_orig_tracker) { using ServerId = int; ServerId server1 = 101; @@ -244,63 +244,63 @@ namespace crimson { auto rp2 = st.get_req_params(server1); - EXPECT_EQ(1u, rp2.delta); - EXPECT_EQ(1u, rp2.rho); + EXPECT_EQ(0u, rp2.delta); + EXPECT_EQ(0u, rp2.rho); - st.track_resp(server1, dmc::PhaseType::priority); + st.track_resp(server1, dmc::PhaseType::priority, 1u); auto rp3 = st.get_req_params(server1); - EXPECT_EQ(1u, rp3.delta); - EXPECT_EQ(1u, rp3.rho); + EXPECT_EQ(0u, rp3.delta); + EXPECT_EQ(0u, rp3.rho); - st.track_resp(server2, dmc::PhaseType::priority); + st.track_resp(server2, dmc::PhaseType::priority, 1u); auto rp4 = st.get_req_params(server1); - EXPECT_EQ(2u, rp4.delta); - EXPECT_EQ(1u, rp4.rho); + EXPECT_EQ(1u, rp4.delta); + EXPECT_EQ(0u, rp4.rho); auto rp5 = st.get_req_params(server1); - EXPECT_EQ(1u, rp5.delta); - EXPECT_EQ(1u, rp5.rho); + EXPECT_EQ(0u, rp5.delta); + EXPECT_EQ(0u, rp5.rho); - st.track_resp(server2, dmc::PhaseType::reservation); + st.track_resp(server2, dmc::PhaseType::reservation, 1u); auto rp6 = st.get_req_params(server1); - EXPECT_EQ(2u, rp6.delta); - EXPECT_EQ(2u, rp6.rho); + EXPECT_EQ(1u, rp6.delta); + EXPECT_EQ(1u, rp6.rho); // auto rp6_b = st.get_req_params(server2); - st.track_resp(server2, dmc::PhaseType::reservation); - st.track_resp(server1, dmc::PhaseType::priority); - st.track_resp(server2, dmc::PhaseType::priority); - st.track_resp(server2, dmc::PhaseType::reservation); - st.track_resp(server1, dmc::PhaseType::reservation); - st.track_resp(server1, dmc::PhaseType::priority); - st.track_resp(server2, dmc::PhaseType::priority); + st.track_resp(server2, dmc::PhaseType::reservation, 1u); + st.track_resp(server1, dmc::PhaseType::priority, 1u); + st.track_resp(server2, dmc::PhaseType::priority, 1u); + st.track_resp(server2, dmc::PhaseType::reservation, 1u); + st.track_resp(server1, dmc::PhaseType::reservation, 1u); + st.track_resp(server1, dmc::PhaseType::priority, 1u); + st.track_resp(server2, dmc::PhaseType::priority, 1u); auto rp7 = st.get_req_params(server1); - EXPECT_EQ(5u, rp7.delta); - EXPECT_EQ(3u, rp7.rho); + EXPECT_EQ(4u, rp7.delta); + EXPECT_EQ(2u, rp7.rho); auto rp7b = st.get_req_params(server2); - EXPECT_EQ(4u, rp7b.delta); - EXPECT_EQ(2u, rp7b.rho); + EXPECT_EQ(3u, rp7b.delta); + EXPECT_EQ(1u, rp7b.rho); auto rp8 = st.get_req_params(server1); - EXPECT_EQ(1u, rp8.delta); - EXPECT_EQ(1u, rp8.rho); + EXPECT_EQ(0u, rp8.delta); + EXPECT_EQ(0u, rp8.rho); auto rp8b = st.get_req_params(server2); - EXPECT_EQ(1u, rp8b.delta); - EXPECT_EQ(1u, rp8b.rho); + EXPECT_EQ(0u, rp8b.delta); + EXPECT_EQ(0u, rp8b.rho); } // TEST } // namespace dmclock diff --git a/test/test_dmclock_server.cc b/test/test_dmclock_server.cc index 3cc4972..4033272 100644 --- a/test/test_dmclock_server.cc +++ b/test/test_dmclock_server.cc @@ -105,7 +105,8 @@ namespace crimson { auto server_ready_f = [] () -> bool { return true; }; auto submit_req_f = [] (const ClientId& c, std::unique_ptr req, - dmc::PhaseType phase) { + dmc::PhaseType phase, + uint64_t req_cost) { // empty; do nothing }; @@ -865,7 +866,7 @@ namespace crimson { QueueRef pq(new Queue(client_info_f, false)); - ReqParams req_params(1,1); + ReqParams req_params(0, 0); // make sure all times are well before now auto start_time = dmc::get_time() - 100.0; diff --git a/test/test_test_client.cc b/test/test_test_client.cc index a4aff6e..d8f4b2a 100644 --- a/test/test_test_client.cc +++ b/test/test_test_client.cc @@ -45,6 +45,7 @@ TEST(test_client, full_bore_timing) { sim::TestResponse resp(0); dmc::PhaseType resp_params = dmc::PhaseType::priority; test::DmcClient* client; + const uint64_t request_cost = 1u; auto start = now(); client = @@ -54,7 +55,7 @@ TEST(test_client, full_bore_timing) { const ClientId& client_id, const dmc::ReqParams& req_params) { ++count; - client->receive_response(resp, client_id, resp_params); + client->receive_response(resp, client_id, resp_params, request_cost); }, [&] (const uint64_t seed) -> ServerId& { return server_id; @@ -85,6 +86,7 @@ TEST(test_client, paused_timing) { sim::TestResponse resp(0); dmc::PhaseType resp_params = dmc::PhaseType::priority; + const uint64_t request_cost = 1u; test::DmcClient* client; auto start = now(); @@ -96,7 +98,7 @@ TEST(test_client, paused_timing) { const dmc::ReqParams& req_params) { ++count; if (auto_respond.load()) { - client->receive_response(resp, client_id, resp_params); + client->receive_response(resp, client_id, resp_params, request_cost); } else { ++unresponded_count; } @@ -116,7 +118,7 @@ TEST(test_client, paused_timing) { auto_respond = true; // respond to those 50 calls for(int i = 0; i < 50; ++i) { - client->receive_response(resp, my_client_id, resp_params); + client->receive_response(resp, my_client_id, resp_params, 1); --unresponded_count; } });