mirror of https://github.com/PentHertz/srsLTE.git
add configurable fairness parameter to pf scheduler
This commit is contained in:
parent
ffe513415c
commit
ea8ad153c4
|
@ -46,6 +46,7 @@ public:
|
||||||
|
|
||||||
struct sched_args_t {
|
struct sched_args_t {
|
||||||
std::string sched_policy = "time_pf";
|
std::string sched_policy = "time_pf";
|
||||||
|
std::string sched_policy_args = "2";
|
||||||
int pdsch_mcs = -1;
|
int pdsch_mcs = -1;
|
||||||
int pdsch_max_mcs = 28;
|
int pdsch_max_mcs = 28;
|
||||||
int pusch_mcs = -1;
|
int pusch_mcs = -1;
|
||||||
|
|
|
@ -23,7 +23,7 @@ class sched_time_pf final : public sched_base
|
||||||
using ue_cit_t = std::map<uint16_t, sched_ue>::const_iterator;
|
using ue_cit_t = std::map<uint16_t, sched_ue>::const_iterator;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
sched_time_pf(const sched_cell_params_t& cell_params_);
|
sched_time_pf(const sched_cell_params_t& cell_params_, const sched_interface::sched_args_t& sched_args);
|
||||||
void sched_dl_users(std::map<uint16_t, sched_ue>& ue_db, sf_sched* tti_sched) override;
|
void sched_dl_users(std::map<uint16_t, sched_ue>& ue_db, sf_sched* tti_sched) override;
|
||||||
void sched_ul_users(std::map<uint16_t, sched_ue>& ue_db, sf_sched* tti_sched) override;
|
void sched_ul_users(std::map<uint16_t, sched_ue>& ue_db, sf_sched* tti_sched) override;
|
||||||
|
|
||||||
|
@ -31,11 +31,12 @@ private:
|
||||||
void new_tti(std::map<uint16_t, sched_ue>& ue_db, sf_sched* tti_sched);
|
void new_tti(std::map<uint16_t, sched_ue>& ue_db, sf_sched* tti_sched);
|
||||||
|
|
||||||
const sched_cell_params_t* cc_cfg = nullptr;
|
const sched_cell_params_t* cc_cfg = nullptr;
|
||||||
|
float fairness_coeff = 1;
|
||||||
|
|
||||||
srslte::tti_point current_tti_rx;
|
srslte::tti_point current_tti_rx;
|
||||||
|
|
||||||
struct ue_ctxt {
|
struct ue_ctxt {
|
||||||
ue_ctxt(uint16_t rnti_) : rnti(rnti_) {}
|
ue_ctxt(uint16_t rnti_, float fairness_coeff_) : rnti(rnti_), fairness_coeff(fairness_coeff_) {}
|
||||||
float dl_avg_rate() const { return dl_nof_samples == 0 ? 0 : dl_avg_rate_; }
|
float dl_avg_rate() const { return dl_nof_samples == 0 ? 0 : dl_avg_rate_; }
|
||||||
float ul_avg_rate() const { return ul_nof_samples == 0 ? 0 : ul_avg_rate_; }
|
float ul_avg_rate() const { return ul_nof_samples == 0 ? 0 : ul_avg_rate_; }
|
||||||
uint32_t dl_count() const { return dl_nof_samples; }
|
uint32_t dl_count() const { return dl_nof_samples; }
|
||||||
|
@ -45,6 +46,7 @@ private:
|
||||||
void save_ul_alloc(uint32_t alloc_bytes, float alpha);
|
void save_ul_alloc(uint32_t alloc_bytes, float alpha);
|
||||||
|
|
||||||
const uint16_t rnti;
|
const uint16_t rnti;
|
||||||
|
const float fairness_coeff;
|
||||||
|
|
||||||
int ue_cc_idx = 0;
|
int ue_cc_idx = 0;
|
||||||
float dl_prio = 0;
|
float dl_prio = 0;
|
||||||
|
|
|
@ -22,7 +22,7 @@ class sched_time_rr final : public sched_base
|
||||||
const static int MAX_RBG = 25;
|
const static int MAX_RBG = 25;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
sched_time_rr(const sched_cell_params_t& cell_params_);
|
sched_time_rr(const sched_cell_params_t& cell_params_, const sched_interface::sched_args_t& sched_args);
|
||||||
void sched_dl_users(std::map<uint16_t, sched_ue>& ue_db, sf_sched* tti_sched) override;
|
void sched_dl_users(std::map<uint16_t, sched_ue>& ue_db, sf_sched* tti_sched) override;
|
||||||
void sched_ul_users(std::map<uint16_t, sched_ue>& ue_db, sf_sched* tti_sched) override;
|
void sched_ul_users(std::map<uint16_t, sched_ue>& ue_db, sf_sched* tti_sched) override;
|
||||||
|
|
||||||
|
|
|
@ -133,6 +133,7 @@ void parse_args(all_args_t* args, int argc, char* argv[])
|
||||||
|
|
||||||
/* Scheduling section */
|
/* Scheduling section */
|
||||||
("scheduler.policy", bpo::value<string>(&args->stack.mac.sched.sched_policy)->default_value("time_pf"), "DL and UL data scheduling policy (E.g. time_rr, time_pf)")
|
("scheduler.policy", bpo::value<string>(&args->stack.mac.sched.sched_policy)->default_value("time_pf"), "DL and UL data scheduling policy (E.g. time_rr, time_pf)")
|
||||||
|
("scheduler.policy_args", bpo::value<string>(&args->stack.mac.sched.sched_policy_args)->default_value("2"), "Scheduler policy-specific arguments")
|
||||||
("scheduler.pdsch_mcs", bpo::value<int>(&args->stack.mac.sched.pdsch_mcs)->default_value(-1), "Optional fixed PDSCH MCS (ignores reported CQIs if specified)")
|
("scheduler.pdsch_mcs", bpo::value<int>(&args->stack.mac.sched.pdsch_mcs)->default_value(-1), "Optional fixed PDSCH MCS (ignores reported CQIs if specified)")
|
||||||
("scheduler.pdsch_max_mcs", bpo::value<int>(&args->stack.mac.sched.pdsch_max_mcs)->default_value(-1), "Optional PDSCH MCS limit")
|
("scheduler.pdsch_max_mcs", bpo::value<int>(&args->stack.mac.sched.pdsch_max_mcs)->default_value(-1), "Optional PDSCH MCS limit")
|
||||||
("scheduler.pusch_mcs", bpo::value<int>(&args->stack.mac.sched.pusch_mcs)->default_value(-1), "Optional fixed PUSCH MCS (ignores reported CQIs if specified)")
|
("scheduler.pusch_mcs", bpo::value<int>(&args->stack.mac.sched.pusch_mcs)->default_value(-1), "Optional fixed PUSCH MCS (ignores reported CQIs if specified)")
|
||||||
|
|
|
@ -289,10 +289,10 @@ void sched::carrier_sched::carrier_cfg(const sched_cell_params_t& cell_params_)
|
||||||
|
|
||||||
// Setup data scheduling algorithms
|
// Setup data scheduling algorithms
|
||||||
if (cell_params_.sched_cfg->sched_policy == "time_rr") {
|
if (cell_params_.sched_cfg->sched_policy == "time_rr") {
|
||||||
sched_algo.reset(new sched_time_rr{*cc_cfg});
|
sched_algo.reset(new sched_time_rr{*cc_cfg, *cell_params_.sched_cfg});
|
||||||
log_h->info("Using time-domain RR scheduling policy for cc=%d\n", cc_cfg->enb_cc_idx);
|
log_h->info("Using time-domain RR scheduling policy for cc=%d\n", cc_cfg->enb_cc_idx);
|
||||||
} else {
|
} else {
|
||||||
sched_algo.reset(new sched_time_pf{*cc_cfg});
|
sched_algo.reset(new sched_time_pf{*cc_cfg, *cell_params_.sched_cfg});
|
||||||
log_h->info("Using time-domain PF scheduling policy for cc=%d\n", cc_cfg->enb_cc_idx);
|
log_h->info("Using time-domain PF scheduling policy for cc=%d\n", cc_cfg->enb_cc_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,9 +16,12 @@ namespace srsenb {
|
||||||
|
|
||||||
using srslte::tti_point;
|
using srslte::tti_point;
|
||||||
|
|
||||||
sched_time_pf::sched_time_pf(const sched_cell_params_t& cell_params_)
|
sched_time_pf::sched_time_pf(const sched_cell_params_t& cell_params_, const sched_interface::sched_args_t& sched_args)
|
||||||
{
|
{
|
||||||
cc_cfg = &cell_params_;
|
cc_cfg = &cell_params_;
|
||||||
|
if (not sched_args.sched_policy_args.empty()) {
|
||||||
|
fairness_coeff = std::stof(sched_args.sched_policy_args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sched_time_pf::new_tti(std::map<uint16_t, sched_ue>& ue_db, sf_sched* tti_sched)
|
void sched_time_pf::new_tti(std::map<uint16_t, sched_ue>& ue_db, sf_sched* tti_sched)
|
||||||
|
@ -36,7 +39,7 @@ void sched_time_pf::new_tti(std::map<uint16_t, sched_ue>& ue_db, sf_sched* tti_s
|
||||||
for (auto& u : ue_db) {
|
for (auto& u : ue_db) {
|
||||||
auto it = ue_history_db.find(u.first);
|
auto it = ue_history_db.find(u.first);
|
||||||
if (it == ue_history_db.end()) {
|
if (it == ue_history_db.end()) {
|
||||||
it = ue_history_db.insert(std::make_pair(u.first, ue_ctxt{u.first})).first;
|
it = ue_history_db.insert(std::make_pair(u.first, ue_ctxt{u.first, fairness_coeff})).first;
|
||||||
}
|
}
|
||||||
it->second.new_tti(*cc_cfg, u.second, tti_sched);
|
it->second.new_tti(*cc_cfg, u.second, tti_sched);
|
||||||
if (it->second.dl_newtx_h != nullptr or it->second.dl_retx_h != nullptr) {
|
if (it->second.dl_newtx_h != nullptr or it->second.dl_retx_h != nullptr) {
|
||||||
|
@ -162,7 +165,7 @@ void sched_time_pf::ue_ctxt::new_tti(const sched_cell_params_t& cell, sched_ue&
|
||||||
// calculate DL PF priority
|
// calculate DL PF priority
|
||||||
float r = ue.get_expected_dl_bitrate(ue_cc_idx) / 8;
|
float r = ue.get_expected_dl_bitrate(ue_cc_idx) / 8;
|
||||||
float R = dl_avg_rate();
|
float R = dl_avg_rate();
|
||||||
dl_prio = (R != 0) ? r / R : (r == 0 ? 0 : std::numeric_limits<float>::max());
|
dl_prio = (R != 0) ? pow(r, fairness_coeff) / R : (r == 0 ? 0 : std::numeric_limits<float>::max());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate UL priority
|
// Calculate UL priority
|
||||||
|
@ -177,24 +180,24 @@ void sched_time_pf::ue_ctxt::new_tti(const sched_cell_params_t& cell, sched_ue&
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sched_time_pf::ue_ctxt::save_dl_alloc(uint32_t alloc_bytes, float alpha)
|
void sched_time_pf::ue_ctxt::save_dl_alloc(uint32_t alloc_bytes, float exp_avg_alpha)
|
||||||
{
|
{
|
||||||
if (dl_nof_samples < 1 / alpha) {
|
if (dl_nof_samples < 1 / exp_avg_alpha) {
|
||||||
// fast start
|
// fast start
|
||||||
dl_avg_rate_ = dl_avg_rate_ + (alloc_bytes - dl_avg_rate_) / (dl_nof_samples + 1);
|
dl_avg_rate_ = dl_avg_rate_ + (alloc_bytes - dl_avg_rate_) / (dl_nof_samples + 1);
|
||||||
} else {
|
} else {
|
||||||
dl_avg_rate_ = (1 - alpha) * dl_avg_rate_ + (alpha)*alloc_bytes;
|
dl_avg_rate_ = (1 - exp_avg_alpha) * dl_avg_rate_ + (exp_avg_alpha)*alloc_bytes;
|
||||||
}
|
}
|
||||||
dl_nof_samples++;
|
dl_nof_samples++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sched_time_pf::ue_ctxt::save_ul_alloc(uint32_t alloc_bytes, float alpha)
|
void sched_time_pf::ue_ctxt::save_ul_alloc(uint32_t alloc_bytes, float exp_avg_alpha)
|
||||||
{
|
{
|
||||||
if (ul_nof_samples < 1 / alpha) {
|
if (ul_nof_samples < 1 / exp_avg_alpha) {
|
||||||
// fast start
|
// fast start
|
||||||
ul_avg_rate_ = ul_avg_rate_ + (alloc_bytes - ul_avg_rate_) / (ul_nof_samples + 1);
|
ul_avg_rate_ = ul_avg_rate_ + (alloc_bytes - ul_avg_rate_) / (ul_nof_samples + 1);
|
||||||
} else {
|
} else {
|
||||||
ul_avg_rate_ = (1 - alpha) * ul_avg_rate_ + (alpha)*alloc_bytes;
|
ul_avg_rate_ = (1 - exp_avg_alpha) * ul_avg_rate_ + (exp_avg_alpha)*alloc_bytes;
|
||||||
}
|
}
|
||||||
ul_nof_samples++;
|
ul_nof_samples++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
namespace srsenb {
|
namespace srsenb {
|
||||||
|
|
||||||
sched_time_rr::sched_time_rr(const sched_cell_params_t& cell_params_)
|
sched_time_rr::sched_time_rr(const sched_cell_params_t& cell_params_, const sched_interface::sched_args_t& sched_args)
|
||||||
{
|
{
|
||||||
cc_cfg = &cell_params_;
|
cc_cfg = &cell_params_;
|
||||||
}
|
}
|
||||||
|
@ -66,8 +66,12 @@ void sched_time_rr::sched_dl_newtxs(std::map<uint16_t, sched_ue>& ue_db, sf_sche
|
||||||
iter = ue_db.begin(); // wrap around
|
iter = ue_db.begin(); // wrap around
|
||||||
}
|
}
|
||||||
sched_ue& user = iter->second;
|
sched_ue& user = iter->second;
|
||||||
|
int ue_cc_idx = user.enb_to_ue_cc_idx(cc_cfg->enb_cc_idx);
|
||||||
|
if (ue_cc_idx < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const dl_harq_proc* h = get_dl_newtx_harq(user, tti_sched);
|
const dl_harq_proc* h = get_dl_newtx_harq(user, tti_sched);
|
||||||
rbg_interval req_rbgs = user.get_required_dl_rbgs(user.enb_to_ue_cc_idx(cc_cfg->enb_cc_idx));
|
rbg_interval req_rbgs = user.get_required_dl_rbgs(ue_cc_idx);
|
||||||
// Check if there is an empty harq for the newtx
|
// Check if there is an empty harq for the newtx
|
||||||
if (h == nullptr or req_rbgs.stop() == 0) {
|
if (h == nullptr or req_rbgs.stop() == 0) {
|
||||||
continue;
|
continue;
|
||||||
|
|
Loading…
Reference in New Issue