From 47906bbc49195f2ef2ed44cd54337feb87f7dbc3 Mon Sep 17 00:00:00 2001 From: imarom Date: Sun, 24 Jul 2016 13:20:51 +0300 Subject: BUG: trex-227 - random packet size with -m 100% does not give 100% line rate https://trex-tgn.cisco.com/youtrack/issue/trex-227 --- src/stateless/cp/trex_stream.cpp | 2 +- src/stateless/cp/trex_stream.h | 2 +- src/stateless/cp/trex_stream_vm.cpp | 65 +++++++++++++++++++++++++++++++++++-- src/stateless/cp/trex_stream_vm.h | 6 ++-- 4 files changed, 67 insertions(+), 8 deletions(-) (limited to 'src/stateless/cp') diff --git a/src/stateless/cp/trex_stream.cpp b/src/stateless/cp/trex_stream.cpp index adc08ae2..7a3dfef7 100644 --- a/src/stateless/cp/trex_stream.cpp +++ b/src/stateless/cp/trex_stream.cpp @@ -141,7 +141,7 @@ TrexStream::TrexStream(uint8_t type, m_pkt.binary = NULL; m_pkt.len = 0; - m_expected_pkt_len = 0; + m_expected_pkt_len = 0.0; m_rx_check.m_enabled = false; diff --git a/src/stateless/cp/trex_stream.h b/src/stateless/cp/trex_stream.h index 8ac5ebc8..0f59356d 100644 --- a/src/stateless/cp/trex_stream.h +++ b/src/stateless/cp/trex_stream.h @@ -558,7 +558,7 @@ public: StreamVmDp *m_vm_dp; CStreamPktData m_pkt; - uint16_t m_expected_pkt_len; + double m_expected_pkt_len; /* pkt */ diff --git a/src/stateless/cp/trex_stream_vm.cpp b/src/stateless/cp/trex_stream_vm.cpp index 7a1dc122..f04c9f3a 100644 --- a/src/stateless/cp/trex_stream_vm.cpp +++ b/src/stateless/cp/trex_stream_vm.cpp @@ -27,7 +27,64 @@ limitations under the License. #include #include +/** + * provides some tools for the fast rand function + * that is used by the datapath + * some features of this function is different + * from a regular random + * (such as average can be off by few percents) + * + * @author imarom (7/24/2016) + */ +class FastRandUtils { +public: + + /** + * searches the target in the cache + * if not found iterativly calculate it + * and add it to the cache + * + */ + double calc_fastrand_avg(uint16_t target) { + auto search = m_avg_cache.find(target); + if (search != m_avg_cache.end()) { + return search->second; + } + + /* not found - calculate it */ + double avg = iterate_calc(target); + + /* if there is enough space - to the cache */ + if (m_avg_cache.size() <= G_MAX_CACHE_SIZE) { + m_avg_cache[target] = avg; + } + + return avg; + } + +private: + /** + * hard calculate a value using iterations + * + */ + double iterate_calc(uint16_t target) { + const int num_samples = 10000; + uint64_t tmp = 0; + uint32_t seed = 1; + + for (int i = 0; i < num_samples; i++) { + tmp += fastrand(seed) % (target + 1); + } + + return (tmp / double(num_samples)); + } + + std::unordered_map m_avg_cache; + static const uint16_t G_MAX_CACHE_SIZE = 9230; +}; + +static FastRandUtils g_fastrand_util; void StreamVmInstructionFixChecksumIpv4::Dump(FILE *fd){ @@ -350,9 +407,11 @@ void StreamVm::build_flow_var_table() { var.m_ins.m_ins_flowv->m_min_value =60; } - m_expected_pkt_size = (var.m_ins.m_ins_flowv->m_min_value + var.m_ins.m_ins_flowv->m_max_value) / 2; + /* expected packet size calculation */ + uint16_t range = var.m_ins.m_ins_flowv->m_max_value - var.m_ins.m_ins_flowv->m_min_value; + m_expected_pkt_size = var.m_ins.m_ins_flowv->m_min_value + g_fastrand_util.calc_fastrand_avg(range); } - }/* for */ + } } @@ -962,7 +1021,7 @@ StreamVm::~StreamVm() { * calculate expected packet size of stream's VM * */ -uint16_t +double StreamVm::calc_expected_pkt_size(uint16_t regular_pkt_size) const { /* if no packet size change - simply return the regular packet size */ diff --git a/src/stateless/cp/trex_stream_vm.h b/src/stateless/cp/trex_stream_vm.h index 58d43bd4..f55d33c1 100644 --- a/src/stateless/cp/trex_stream_vm.h +++ b/src/stateless/cp/trex_stream_vm.h @@ -1417,7 +1417,7 @@ public: m_prefix_size=0; m_bss=0; m_pkt_size=0; - m_expected_pkt_size=0; + m_expected_pkt_size=0.0; m_cur_var_offset=0; m_is_random_var=false; @@ -1435,7 +1435,7 @@ public: * if the VM changes the packet length (random) * */ - uint16_t calc_expected_pkt_size(uint16_t regular_pkt_size) const; + double calc_expected_pkt_size(uint16_t regular_pkt_size) const; @@ -1576,7 +1576,7 @@ private: uint16_t m_prefix_size; uint16_t m_pkt_size; - uint16_t m_expected_pkt_size; + double m_expected_pkt_size; uint16_t m_cur_var_offset; uint16_t m_max_field_update; /* the location of the last byte that is going to be changed in the packet */ -- cgit 1.2.3-korg