Optimization of cc_sched_ue::cqi_to_tbs(...) method via the use of root-finding algorithm

master
Francisco 4 years ago committed by Andre Puschmann
parent 94efeab672
commit 8d181ef41c

@ -89,10 +89,10 @@ bool operator==(const sched_interface::ue_cfg_t::cc_cfg_t& lhs, const sched_inte
return lhs.enb_cc_idx == rhs.enb_cc_idx and lhs.active == rhs.active; return lhs.enb_cc_idx == rhs.enb_cc_idx and lhs.active == rhs.active;
} }
template <typename YType, typename Callable, typename ErrorDetect> template <typename YType, typename Callable>
std::tuple<int, YType, int, YType> false_position_method(int x1, int x2, YType y0, const Callable& f) std::tuple<int, YType, int, YType> false_position_method(int x1, int x2, YType y0, const Callable& f)
{ {
return false_position_method(x1, x2, y0, f, []() { return false; }); return false_position_method(x1, x2, y0, f, [](int x) { return false; });
} }
template <typename YType, typename Callable, typename ErrorDetect> template <typename YType, typename Callable, typename ErrorDetect>
std::tuple<int, YType, int, YType> std::tuple<int, YType, int, YType>
@ -1261,44 +1261,52 @@ int sched_ue::enb_to_ue_cc_idx(uint32_t enb_cc_idx) const
int cc_sched_ue::cqi_to_tbs(uint32_t nof_prb, uint32_t nof_re, bool use_tbs_index_alt, bool is_ul, uint32_t* mcs) int cc_sched_ue::cqi_to_tbs(uint32_t nof_prb, uint32_t nof_re, bool use_tbs_index_alt, bool is_ul, uint32_t* mcs)
{ {
using ul64qam_cap = sched_interface::ue_cfg_t::ul64qam_cap; using ul64qam_cap = sched_interface::ue_cfg_t::ul64qam_cap;
uint32_t cqi, max_mcs, max_Qm; uint32_t max_Qm;
int max_mcs;
float max_coderate; float max_coderate;
if (is_ul) { if (is_ul) {
cqi = ul_cqi;
max_mcs = max_mcs_ul; max_mcs = max_mcs_ul;
max_Qm = cfg->support_ul64qam == ul64qam_cap::enabled ? 6 : 4; max_Qm = cfg->support_ul64qam == ul64qam_cap::enabled ? 6 : 4;
max_coderate = srslte_cqi_to_coderate(std::min(cqi + 1u, 15u), false); max_coderate = srslte_cqi_to_coderate(std::min(ul_cqi + 1u, 15u), false);
} else { } else {
cqi = dl_cqi;
max_mcs = max_mcs_dl; max_mcs = max_mcs_dl;
max_Qm = use_tbs_index_alt ? 8 : 6; max_Qm = use_tbs_index_alt ? 8 : 6;
max_coderate = srslte_cqi_to_coderate(std::min(cqi + 1u, 15u), use_tbs_index_alt); max_coderate = srslte_cqi_to_coderate(std::min(dl_cqi + 1u, 15u), use_tbs_index_alt);
} }
// Take the upper bound code-rate // function with sign-flip at solution
int sel_mcs = max_mcs + 1; auto compute_tbs = [&](int sel_mcs) -> float {
float coderate = 99; uint32_t tbs_idx = srslte_ra_tbs_idx_from_mcs(sel_mcs, use_tbs_index_alt, is_ul);
int tbs = 0; int tbs = srslte_ra_tbs_from_idx(tbs_idx, nof_prb);
uint32_t Qm = 0; float coderate = srslte_coderate(tbs, nof_re);
do {
sel_mcs--;
uint32_t tbs_idx = srslte_ra_tbs_idx_from_mcs(sel_mcs, use_tbs_index_alt, is_ul);
tbs = srslte_ra_tbs_from_idx(tbs_idx, nof_prb);
coderate = srslte_coderate(tbs, nof_re);
srslte_mod_t mod = srslte_mod_t mod =
(is_ul) ? srslte_ra_ul_mod_from_mcs(sel_mcs) : srslte_ra_dl_mod_from_mcs(sel_mcs, use_tbs_index_alt); (is_ul) ? srslte_ra_ul_mod_from_mcs(sel_mcs) : srslte_ra_dl_mod_from_mcs(sel_mcs, use_tbs_index_alt);
Qm = SRSLTE_MIN(max_Qm, srslte_mod_bits_x_symbol(mod)); uint32_t Qm = std::min(max_Qm, srslte_mod_bits_x_symbol(mod));
} while (sel_mcs > 0 && coderate > SRSLTE_MIN(max_coderate, 0.930 * Qm)); return coderate - std::min(max_coderate, 0.930f * Qm);
};
if (mcs != nullptr) { std::tuple<int, float, int, float> ret;
*mcs = (uint32_t)sel_mcs; if (nof_prb > 1) {
// for non-voip case
ret = false_position_method(0, max_mcs, 0.0f, compute_tbs);
} else {
// avoid 6 prbs (voip case), where function is not monotonic
ret = false_position_method(7, max_mcs, 0.0f, compute_tbs);
if (std::get<1>(ret) > 0) {
ret = false_position_method(0, 5, 0.0f, compute_tbs);
}
} }
int chosen_mcs = std::get<0>(ret);
uint32_t tbs_idx = srslte_ra_tbs_idx_from_mcs(chosen_mcs, use_tbs_index_alt, is_ul);
int chosen_tbs = srslte_ra_tbs_from_idx(tbs_idx, nof_prb);
if (mcs != nullptr) {
*mcs = (uint32_t)chosen_mcs;
}
// If coderate > SRSLTE_MIN(max_coderate, 0.930 * Qm) we should set TBS=0. We don't because it's not correctly // If coderate > SRSLTE_MIN(max_coderate, 0.930 * Qm) we should set TBS=0. We don't because it's not correctly
// handled by the scheduler, but we might be scheduling undecodable codewords at very low SNR // handled by the scheduler, but we might be scheduling undecodable codewords at very low SNR
return tbs; return chosen_tbs;
} }
/************************************************************************************************ /************************************************************************************************

@ -332,6 +332,7 @@ sched_sim_events rand_sim_params(uint32_t nof_ttis)
std::uniform_int_distribution<uint32_t> dist_prb_idx(0, 5); std::uniform_int_distribution<uint32_t> dist_prb_idx(0, 5);
uint32_t prb_idx = dist_prb_idx(srsenb::get_rand_gen()); uint32_t prb_idx = dist_prb_idx(srsenb::get_rand_gen());
uint32_t nof_prb = std::array<uint32_t, 6>({6, 15, 25, 50, 75, 100})[prb_idx]; uint32_t nof_prb = std::array<uint32_t, 6>({6, 15, 25, 50, 75, 100})[prb_idx];
printf("Number of PRBs is %u\n", nof_prb);
sched_sim_event_generator generator; sched_sim_event_generator generator;

Loading…
Cancel
Save