summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorimarom <imarom@cisco.com>2016-08-18 13:49:59 +0300
committerimarom <imarom@cisco.com>2016-08-18 13:52:49 +0300
commitb8353aa9eb017f66166da9ee03ad7cd09abda175 (patch)
tree416cd03e701fdb2209034d04ea37bdc8a21bf3f4
parent5f530a21aa669b4ddc0f8d0329794d0c439f6879 (diff)
CPU util. measurements fix (more accurate and steady)
see #trex-246
-rw-r--r--scripts/automation/trex_control_plane/stl/console/trex_tui.py80
-rwxr-xr-xsrc/bp_sim.cpp3
-rw-r--r--src/main_dpdk.cpp18
-rwxr-xr-xsrc/os_time.h13
-rwxr-xr-xsrc/utl_cpuu.cpp7
-rwxr-xr-xsrc/utl_cpuu.h8
6 files changed, 92 insertions, 37 deletions
diff --git a/scripts/automation/trex_control_plane/stl/console/trex_tui.py b/scripts/automation/trex_control_plane/stl/console/trex_tui.py
index 6dff0a6f..e769b9b2 100644
--- a/scripts/automation/trex_control_plane/stl/console/trex_tui.py
+++ b/scripts/automation/trex_control_plane/stl/console/trex_tui.py
@@ -515,9 +515,31 @@ class ScreenBuffer():
self.redraw_cb(buffer)
with self.lock:
- self.snapshot = buffer.getvalue()
+ self.snapshot = buffer
self.update_flag = False
+# a policer class to make sure no too-fast redraws
+# occurs - it filters fast bursts of redraws
+class RedrawPolicer():
+ def __init__ (self, rate):
+ self.ts = 0
+ self.marked = False
+ self.rate = rate
+ self.force = False
+
+ def mark_for_redraw (self, force = False):
+ self.marked = True
+ if force:
+ self.force = True
+
+ def should_redraw (self):
+ dt = time.time() - self.ts
+ return self.force or (self.marked and (dt > self.rate))
+
+ def reset (self, restart = False):
+ self.ts = time.time()
+ self.marked = restart
+ self.force = False
# shows a textual top style window
@@ -531,6 +553,7 @@ class TrexTUI():
MIN_ROWS = 50
MIN_COLS = 111
+
class ScreenSizeException(Exception):
def __init__ (self, cols, rows):
msg = "TUI requires console screen size of at least {0}x{1}, current is {2}x{3}".format(TrexTUI.MIN_COLS,
@@ -585,7 +608,12 @@ class TrexTUI():
self.pm.init(show_log, locked)
self.state = self.STATE_ACTIVE
- self.last_redraw_ts = 0
+
+ # create print policers
+ self.full_redraw = RedrawPolicer(0.5)
+ self.keys_redraw = RedrawPolicer(0.05)
+ self.full_redraw.mark_for_redraw()
+
try:
self.sb.start()
@@ -594,11 +622,10 @@ class TrexTUI():
# draw and handle user input
status = self.async_keys.tick(self.pm)
- self.draw_screen(status)
-
- # speedup for keys, slower for no keys
- if status == AsyncKeys.STATUS_NONE:
- time.sleep(0.001)
+ # prepare the next frame
+ self.prepare(status)
+ time.sleep(0.01)
+ self.draw_screen()
with self.tui_global_lock:
self.handle_state_machine()
@@ -611,6 +638,7 @@ class TrexTUI():
print("")
+
# handle state machine
def handle_state_machine (self):
@@ -641,34 +669,44 @@ class TrexTUI():
self.state = self.STATE_LOST_CONT
- # draw once
- def draw_screen (self, status):
+ # logic before printing
+ def prepare (self, status):
+ if status == AsyncKeys.STATUS_REDRAW_ALL:
+ self.full_redraw.mark_for_redraw(force = True)
- t = time.time() - self.last_redraw_ts
- redraw = (t >= 0.5) or (status == AsyncKeys.STATUS_REDRAW_ALL)
- if redraw:
+ elif status == AsyncKeys.STATUS_REDRAW_KEYS:
+ self.keys_redraw.mark_for_redraw()
+
+ if self.full_redraw.should_redraw():
self.sb.update()
- self.last_redraw_ts = time.time()
-
+ self.full_redraw.reset(restart = True)
+ return
+
+
+ # draw once
+ def draw_screen (self):
+
+ # check for screen buffer's new screen
x = self.sb.get()
# we have a new screen to draw
if x:
self.clear_screen()
-
- sys.stdout.write(x)
- self.async_keys.draw(sys.stdout)
+
+ self.async_keys.draw(x)
+ sys.stdout.write(x.getvalue())
sys.stdout.flush()
- # we only need to redraw the keys
- elif status == AsyncKeys.STATUS_REDRAW_KEYS:
+ # maybe we need to redraw the keys
+ elif self.keys_redraw.should_redraw():
sys.stdout.write("\x1b[4A")
-
self.async_keys.draw(sys.stdout)
sys.stdout.flush()
- return
+ # reset the policer for next time
+ self.keys_redraw.reset()
+
diff --git a/src/bp_sim.cpp b/src/bp_sim.cpp
index 2d1d020b..773e82fc 100755
--- a/src/bp_sim.cpp
+++ b/src/bp_sim.cpp
@@ -4615,8 +4615,7 @@ double CFlowGenList::GetCpuUtilRaw(){
void CFlowGenList::UpdateFast(){
- int i;
- for (i=0; i<(int)m_threads_info.size(); i++) {
+ for (int i=0; i<(int)m_threads_info.size(); i++) {
CFlowGenListPerThread * lp=m_threads_info[i];
lp->Update();
}
diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp
index 6beb4e3e..0ef83c02 100644
--- a/src/main_dpdk.cpp
+++ b/src/main_dpdk.cpp
@@ -4126,15 +4126,21 @@ void
CGlobalTRex::handle_fast_path() {
/* check from messages from DP */
check_for_dp_messages();
- // update CPU%
- m_fl.UpdateFast();
- if (get_is_stateless()) {
- m_rx_sl.update_cpu_util();
- }else{
- m_mg.update_fast();
+ /* measure CPU utilization by sampling (we sample 1000 to get an accurate sampling) */
+ for (int i = 0; i < 1000; i++) {
+ m_fl.UpdateFast();
+
+ if (get_is_stateless()) {
+ m_rx_sl.update_cpu_util();
+ }else{
+ m_mg.update_fast();
+ }
+
+ rte_pause();
}
+
if ( is_all_cores_finished() ) {
mark_for_shutdown(SHUTDOWN_TEST_ENDED);
}
diff --git a/src/os_time.h b/src/os_time.h
index b1d44c03..4f10e2b5 100755
--- a/src/os_time.h
+++ b/src/os_time.h
@@ -165,6 +165,17 @@ void delay(int msec){
nanosleep(&time1,&remain);
}
-
+/**
+ * more accurate sleep by doing spin
+ *
+ */
+static inline
+void delay_spin(double sec) {
+ double target = now_sec() + sec;
+
+ while (now_sec() < target) {
+ rte_pause();
+ }
+}
#endif
diff --git a/src/utl_cpuu.cpp b/src/utl_cpuu.cpp
index 47c78c8e..c01326d6 100755
--- a/src/utl_cpuu.cpp
+++ b/src/utl_cpuu.cpp
@@ -42,10 +42,11 @@ void CCpuUtlCp::Update(){
if ( m_dpcpu->sample_data() ) {
m_work++;
}
- if (m_ticks==100) {
+ if (m_ticks==100000) {
/* LPF*/
- m_cpu_util_lpf = (m_cpu_util_lpf*0.75)+((double)m_work*0.25);
- AppendHistory(m_work);
+ double work = (m_work / double(m_ticks)) * 100;
+ m_cpu_util_lpf = (m_cpu_util_lpf*0.75)+(work*0.25);
+ AppendHistory(work);
m_ticks=0;
m_work=0;
}
diff --git a/src/utl_cpuu.h b/src/utl_cpuu.h
index b0a76fce..690eb200 100755
--- a/src/utl_cpuu.h
+++ b/src/utl_cpuu.h
@@ -47,7 +47,7 @@ public:
private:
- uint8_t m_data;
+ volatile uint8_t m_data;
} __rte_cache_aligned;
class CCpuUtlCp {
@@ -62,9 +62,9 @@ public:
void GetHistory(cpu_vct_st &cpu_vct);
private:
void AppendHistory(uint8_t);
- CCpuUtlDp * m_dpcpu;
- uint8_t m_ticks;
- uint8_t m_work;
+ CCpuUtlDp * m_dpcpu;
+ uint32_t m_ticks;
+ uint32_t m_work;
static const int m_history_size=20;
uint8_t m_cpu_util[m_history_size]; // history as cyclic array