mirror of https://github.com/PentHertz/srsLTE.git
update sched benchmark, created unit test to cover rbg search algorithms, improved algorithms to search for empty rbgs
This commit is contained in:
parent
8ffbf0ff6d
commit
f0f99c1e4f
|
@ -19,20 +19,10 @@ namespace srsenb {
|
|||
|
||||
rbg_interval rbg_interval::find_first_interval(const rbgmask_t& mask)
|
||||
{
|
||||
int rb_start = -1;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
int rb_start = mask.find_lowest(0, mask.size());
|
||||
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();
|
||||
}
|
||||
|
@ -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);
|
||||
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);
|
||||
if (interv.length() >= max_size) {
|
||||
return interv;
|
||||
|
|
|
@ -70,3 +70,7 @@ add_test(sched_benchmark_test sched_benchmark_test)
|
|||
add_executable(sched_cqi_test sched_cqi_test.cc)
|
||||
target_link_libraries(sched_cqi_test srsran_common srsenb_mac srsran_mac sched_test_common)
|
||||
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 {
|
||||
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;
|
||||
std::vector<uint32_t> cqi = {5, 10, 15};
|
||||
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;
|
||||
|
||||
struct throughput_stats {
|
||||
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<float> mean_dl_tbs, mean_ul_tbs, avg_dl_mcs, avg_ul_mcs;
|
||||
srsran::rolling_average<double> avg_latency;
|
||||
std::vector<uint32_t> latency_samples;
|
||||
};
|
||||
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::nanoseconds tdur = std::chrono::duration_cast<std::chrono::nanoseconds>(tp2 - tp);
|
||||
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};
|
||||
|
@ -155,6 +157,7 @@ struct run_data {
|
|||
float avg_dl_mcs;
|
||||
float avg_ul_mcs;
|
||||
std::chrono::microseconds avg_latency;
|
||||
std::chrono::microseconds q0_9_latency;
|
||||
};
|
||||
|
||||
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();
|
||||
ue_db_ctxt = tester.get_enb_ctxt().ue_db;
|
||||
}
|
||||
tester.total_stats = {};
|
||||
|
||||
// Run benchmark
|
||||
tester.total_stats = {};
|
||||
tester.total_stats.latency_samples.reserve(params.nof_ttis);
|
||||
for (uint32_t count = 0; count < params.nof_ttis; ++count) {
|
||||
tester.advance_tti();
|
||||
}
|
||||
std::sort(tester.total_stats.latency_samples.begin(), tester.total_stats.latency_samples.end());
|
||||
|
||||
run_data run_result = {};
|
||||
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_dl_mcs = tester.total_stats.avg_dl_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);
|
||||
|
||||
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)
|
||||
{
|
||||
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");
|
||||
fmt::print("---------------------------------------------------------------------------------------"
|
||||
fmt::print("------------------------------------------------------------------------------------------------------"
|
||||
"------\n");
|
||||
for (uint32_t i = 0; i < run_results.size(); ++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);
|
||||
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,
|
||||
r.params.nof_prbs,
|
||||
r.params.cqi,
|
||||
|
@ -275,7 +282,8 @@ void print_benchmark_results(const std::vector<run_data>& run_results)
|
|||
r.avg_ul_mcs,
|
||||
dl_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…
Reference in New Issue