update sched benchmark, created unit test to cover rbg search algorithms, improved algorithms to search for empty rbgs

master
Francisco 4 years ago committed by Francisco Paisana
parent 8ffbf0ff6d
commit f0f99c1e4f

@ -19,20 +19,10 @@ namespace srsenb {
rbg_interval rbg_interval::find_first_interval(const rbgmask_t& mask) rbg_interval rbg_interval::find_first_interval(const rbgmask_t& mask)
{ {
int rb_start = -1; int rb_start = mask.find_lowest(0, mask.size());
for (uint32_t i = 0; i < mask.size(); i++) {
if (rb_start == -1) {
if (mask.test(i)) {
rb_start = i;
}
} else {
if (!mask.test(i)) {
return rbg_interval(rb_start, i);
}
}
}
if (rb_start != -1) { if (rb_start != -1) {
return rbg_interval(rb_start, mask.size()); int rb_end = mask.find_lowest(rb_start + 1, mask.size(), false);
return rbg_interval(rb_start, rb_end < 0 ? mask.size() : rb_end);
} }
return rbg_interval(); return rbg_interval();
} }
@ -61,7 +51,7 @@ RBInterval find_contiguous_interval(const RBMask& in_mask, uint32_t max_size)
} }
size_t max_pos = std::min(in_mask.size(), (size_t)pos + max_size); size_t max_pos = std::min(in_mask.size(), (size_t)pos + max_size);
int pos2 = in_mask.find_lowest(pos, max_pos, true); int pos2 = in_mask.find_lowest(pos + 1, max_pos, true);
RBInterval interv(pos, pos2 < 0 ? max_pos : pos2); RBInterval interv(pos, pos2 < 0 ? max_pos : pos2);
if (interv.length() >= max_size) { if (interv.length() >= max_size) {
return interv; return interv;

@ -70,3 +70,7 @@ add_test(sched_benchmark_test sched_benchmark_test)
add_executable(sched_cqi_test sched_cqi_test.cc) add_executable(sched_cqi_test sched_cqi_test.cc)
target_link_libraries(sched_cqi_test srsran_common srsenb_mac srsran_mac sched_test_common) target_link_libraries(sched_cqi_test srsran_common srsenb_mac srsran_mac sched_test_common)
add_test(sched_cqi_test sched_cqi_test) add_test(sched_cqi_test sched_cqi_test)
add_executable(sched_phy_resource_test sched_phy_resource_test.cc)
target_link_libraries(sched_phy_resource_test srsran_common srsenb_mac srsran_mac sched_test_common)
add_test(sched_phy_resource_test sched_phy_resource_test)

@ -28,7 +28,7 @@ struct run_params {
struct run_params_range { struct run_params_range {
std::vector<uint32_t> nof_prbs{srsran::lte_cell_nof_prbs.begin(), srsran::lte_cell_nof_prbs.end()}; std::vector<uint32_t> nof_prbs{srsran::lte_cell_nof_prbs.begin(), srsran::lte_cell_nof_prbs.end()};
std::vector<uint32_t> nof_ues = {1, 2, 5}; std::vector<uint32_t> nof_ues = {1, 2, 5, 32};
uint32_t nof_ttis = 10000; uint32_t nof_ttis = 10000;
std::vector<uint32_t> cqi = {5, 10, 15}; std::vector<uint32_t> cqi = {5, 10, 15};
std::vector<const char*> sched_policy = {"time_rr", "time_pf"}; std::vector<const char*> sched_policy = {"time_rr", "time_pf"};
@ -80,8 +80,9 @@ public:
std::vector<sched_interface::ul_sched_res_t> ul_result; std::vector<sched_interface::ul_sched_res_t> ul_result;
struct throughput_stats { struct throughput_stats {
srsran::rolling_average<float> mean_dl_tbs, mean_ul_tbs, avg_dl_mcs, avg_ul_mcs; srsran::rolling_average<float> mean_dl_tbs, mean_ul_tbs, avg_dl_mcs, avg_ul_mcs;
srsran::rolling_average<float> avg_latency; srsran::rolling_average<double> avg_latency;
std::vector<uint32_t> latency_samples;
}; };
throughput_stats total_stats; throughput_stats total_stats;
@ -98,6 +99,7 @@ public:
std::chrono::time_point<std::chrono::steady_clock> tp2 = std::chrono::steady_clock::now(); std::chrono::time_point<std::chrono::steady_clock> tp2 = std::chrono::steady_clock::now();
std::chrono::nanoseconds tdur = std::chrono::duration_cast<std::chrono::nanoseconds>(tp2 - tp); std::chrono::nanoseconds tdur = std::chrono::duration_cast<std::chrono::nanoseconds>(tp2 - tp);
total_stats.avg_latency.push(tdur.count()); total_stats.avg_latency.push(tdur.count());
total_stats.latency_samples.push_back(tdur.count());
} }
sf_output_res_t sf_out{get_cell_params(), tti_rx, ul_result, dl_result}; sf_output_res_t sf_out{get_cell_params(), tti_rx, ul_result, dl_result};
@ -155,6 +157,7 @@ struct run_data {
float avg_dl_mcs; float avg_dl_mcs;
float avg_ul_mcs; float avg_ul_mcs;
std::chrono::microseconds avg_latency; std::chrono::microseconds avg_latency;
std::chrono::microseconds q0_9_latency;
}; };
int run_benchmark_scenario(run_params params, std::vector<run_data>& run_results) int run_benchmark_scenario(run_params params, std::vector<run_data>& run_results)
@ -193,12 +196,14 @@ int run_benchmark_scenario(run_params params, std::vector<run_data>& run_results
tester.advance_tti(); tester.advance_tti();
ue_db_ctxt = tester.get_enb_ctxt().ue_db; ue_db_ctxt = tester.get_enb_ctxt().ue_db;
} }
tester.total_stats = {};
// Run benchmark // Run benchmark
tester.total_stats = {};
tester.total_stats.latency_samples.reserve(params.nof_ttis);
for (uint32_t count = 0; count < params.nof_ttis; ++count) { for (uint32_t count = 0; count < params.nof_ttis; ++count) {
tester.advance_tti(); tester.advance_tti();
} }
std::sort(tester.total_stats.latency_samples.begin(), tester.total_stats.latency_samples.end());
run_data run_result = {}; run_data run_result = {};
run_result.params = params; run_result.params = params;
@ -206,7 +211,9 @@ int run_benchmark_scenario(run_params params, std::vector<run_data>& run_results
run_result.avg_ul_throughput = tester.total_stats.mean_ul_tbs.value() * 8.0F / 1e-3F; run_result.avg_ul_throughput = tester.total_stats.mean_ul_tbs.value() * 8.0F / 1e-3F;
run_result.avg_dl_mcs = tester.total_stats.avg_dl_mcs.value(); run_result.avg_dl_mcs = tester.total_stats.avg_dl_mcs.value();
run_result.avg_ul_mcs = tester.total_stats.avg_ul_mcs.value(); run_result.avg_ul_mcs = tester.total_stats.avg_ul_mcs.value();
run_result.avg_latency = std::chrono::microseconds(static_cast<int>(tester.total_stats.avg_latency.value() / 1000)); run_result.avg_latency = std::chrono::microseconds(static_cast<int>(tester.total_stats.avg_latency.value() / 1000));
run_result.q0_9_latency = std::chrono::microseconds(
tester.total_stats.latency_samples[static_cast<size_t>(tester.total_stats.latency_samples.size() * 0.9)] / 1000);
run_results.push_back(run_result); run_results.push_back(run_result);
return SRSRAN_SUCCESS; return SRSRAN_SUCCESS;
@ -248,9 +255,9 @@ run_data expected_run_result(run_params params)
void print_benchmark_results(const std::vector<run_data>& run_results) void print_benchmark_results(const std::vector<run_data>& run_results)
{ {
srslog::flush(); srslog::flush();
fmt::print("run | Nprb | cqi | sched pol | Nue | DL/UL [Mbps] | DL/UL mcs | DL/UL OH [%] | latency " fmt::print("run | Nprb | cqi | sched pol | Nue | DL/UL [Mbps] | DL/UL mcs | DL/UL OH [%] | latency | latency q0.9 "
"[usec]\n"); "[usec]\n");
fmt::print("---------------------------------------------------------------------------------------" fmt::print("------------------------------------------------------------------------------------------------------"
"------\n"); "------\n");
for (uint32_t i = 0; i < run_results.size(); ++i) { for (uint32_t i = 0; i < run_results.size(); ++i) {
const run_data& r = run_results[i]; const run_data& r = run_results[i];
@ -263,7 +270,7 @@ void print_benchmark_results(const std::vector<run_data>& run_results)
tbs = srsran_ra_tbs_from_idx(tbs_idx, nof_pusch_prbs); tbs = srsran_ra_tbs_from_idx(tbs_idx, nof_pusch_prbs);
float ul_rate_overhead = 1.0F - r.avg_ul_throughput / (static_cast<float>(tbs) * 1e3F); float ul_rate_overhead = 1.0F - r.avg_ul_throughput / (static_cast<float>(tbs) * 1e3F);
fmt::print("{:>3d}{:>6d}{:>6d}{:>12}{:>6d}{:>9.2}/{:>4.2}{:>9.1f}/{:>4.1f}{:9.1f}/{:>4.1f}{:12d}\n", fmt::print("{:>3d}{:>6d}{:>6d}{:>12}{:>6d}{:>9.2}/{:>4.2}{:>9.1f}/{:>4.1f}{:9.1f}/{:>4.1f}{:>9d}{:12d}\n",
i, i,
r.params.nof_prbs, r.params.nof_prbs,
r.params.cqi, r.params.cqi,
@ -275,7 +282,8 @@ void print_benchmark_results(const std::vector<run_data>& run_results)
r.avg_ul_mcs, r.avg_ul_mcs,
dl_rate_overhead * 100, dl_rate_overhead * 100,
ul_rate_overhead * 100, ul_rate_overhead * 100,
r.avg_latency.count()); r.avg_latency.count(),
r.q0_9_latency.count());
} }
} }

@ -0,0 +1,69 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2021 Software Radio Systems Limited
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the distribution.
*
*/
#include "srsenb/hdr/stack/mac/sched_phy_ch/sched_phy_resource.h"
#include "srsran/common/common_lte.h"
#include "srsran/common/test_common.h"
#include <random>
namespace srsenb {
std::random_device rd;
std::mt19937 rand_gen(rd());
uint32_t get_rand_Nrbg()
{
return cell_nof_prb_to_rbg(srsran::lte_cell_nof_prbs[std::uniform_int_distribution<uint32_t>{
0, srsran::lte_cell_nof_prbs.size() - 1}(rand_gen)]);
}
void test_rbg_mask_helpers()
{
rbgmask_t rbgs(MAX_NOF_RBGS);
// TEST: Find contiguous range of zero RBGs in RBG mask
rbgs.set(0);
rbgs.set(2);
rbg_interval interv = find_empty_rbg_interval(1, rbgs);
TESTASSERT(not interv.empty() and interv.length() == 1 and interv.start() == 1);
interv = find_empty_rbg_interval(2, rbgs);
TESTASSERT(not interv.empty() and interv.length() == 2 and interv.start() == 3);
interv = find_empty_rbg_interval(rbgs.size(), rbgs);
TESTASSERT(interv.length() + 3 == rbgs.size() and interv.start() == 3);
// TEST: find mask of zero RBGs in RBG mask
rbgmask_t empty_rbgs = find_available_rbgmask(1, false, rbgs);
TESTASSERT(empty_rbgs.count() == 1 and empty_rbgs.test(1));
empty_rbgs = find_available_rbgmask(5, false, rbgs);
TESTASSERT(empty_rbgs.count() == 5 and empty_rbgs.test(1) and empty_rbgs.test(3) and not empty_rbgs.test(2));
// TEST: find mask of zero RBGs in random RBG mask
std::bernoulli_distribution dist{0.5};
rbgs = rbgmask_t(get_rand_Nrbg());
for (size_t i = 0; i < rbgs.size(); ++i) {
rbgs.set(i, dist(rand_gen));
}
empty_rbgs = find_available_rbgmask(rbgs.size(), false, rbgs);
TESTASSERT(empty_rbgs == ~rbgs);
uint32_t L = std::uniform_int_distribution<uint32_t>{1, (uint32_t)rbgs.size() - 1}(rand_gen);
empty_rbgs = find_available_rbgmask(L, false, rbgs);
TESTASSERT(empty_rbgs.count() <= L and (empty_rbgs & rbgs).none());
uint32_t nprb = count_prb_per_tb(rbgs);
TESTASSERT(nprb <= MAX_NOF_PRBS);
}
} // namespace srsenb
int main()
{
srsenb::test_rbg_mask_helpers();
}
Loading…
Cancel
Save