From e73f799983788c328fa5901b9171acfc66de6d5c Mon Sep 17 00:00:00 2001 From: Ido Barnea Date: Mon, 30 May 2016 11:33:22 +0300 Subject: Fixes to latency histogram: Make it multi thread + correct average calculation --- src/time_histogram.cpp | 242 +++++++++++++++++++++---------------------------- 1 file changed, 104 insertions(+), 138 deletions(-) (limited to 'src/time_histogram.cpp') diff --git a/src/time_histogram.cpp b/src/time_histogram.cpp index a6b98079..dd15c4be 100755 --- a/src/time_histogram.cpp +++ b/src/time_histogram.cpp @@ -1,13 +1,11 @@ -#include "time_histogram.h" -#include -#include "utl_json.h" /* Hanoh Haim + Ido Barnea Cisco Systems, Inc. */ /* -Copyright (c) 2015-2015 Cisco Systems, Inc. +Copyright (c) 2015-2016 Cisco Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -22,182 +20,154 @@ See the License for the specific language governing permissions and limitations under the License. */ +#include +#include +#include "utl_json.h" +#include "pal/linux/sanb_atomic.h" +#include "time_histogram.h" - - -void CTimeHistogram::Reset(){ - m_max_dt=0.0; - m_cnt =0; - m_high_cnt =0; - m_max_win_dt=0; - m_max_win_last_dt=0; - m_average=0.0; - memset(&m_max_ar[0],0,sizeof(m_max_ar)); - m_win_cnt=0; +void CTimeHistogram::Reset() { + m_period_data[0].reset(); + m_period_data[1].reset(); + m_period = 0; + m_max_dt = 0; + m_average = 0; + memset(&m_max_ar[0],0,sizeof(m_max_ar)); + m_win_cnt = 0; int i; int j; - for (i=0;i0) { - low=low-1; + if (high == 0) { + if (low > 0) { + low = low - 1; } m_hcnt[j][low]++; break; - }else{ - d_10usec =high; + } else { + d_10usec = high; } } + period_elem.update_sum(dt); + return true; } +void CTimeHistogram::update() { + // switch period, and get values for pervious period + CTimeHistogramPerPeriodData &period_elem = m_period_data[m_period]; + uint8_t new_period; -void CTimeHistogram::update(){ - - m_max_ar[m_win_cnt]=m_max_win_dt; - m_max_win_last_dt=m_max_win_dt; - m_max_win_dt=0.0; - m_win_cnt++; - if (m_win_cnt==HISTOGRAM_QUEUE_SIZE) { - m_win_cnt=0; - } - update_average(); -} - -double CTimeHistogram::get_cur_average(){ - int i,j; - uint64_t d_cnt; - uint64_t d_cnt_high; - - d_cnt = m_cnt - m_cnt_shadow; - m_cnt_shadow =m_cnt; - d_cnt_high = m_high_cnt - m_high_cnt_shadow; - m_high_cnt_shadow =m_high_cnt; - - uint64_t low_events = d_cnt - d_cnt_high; - uint64_t sum= low_events; - double s = ((double)low_events * 5.0); - - - for (j=0; j 0 ) { - uint64_t d= cnt - m_hcnt_shadow[j][i]; - sum += d; - s+= ((double)d)*1.5*get_base_usec(j,i); - m_hcnt_shadow[j][i] = cnt; - } - } + if (m_period == 0) { + new_period = 1; + } else { + new_period = 0; } - - double c_average; - if ( sum > 0 ) { - c_average=s/(double)sum; - }else{ - c_average=0.0; + m_period_data[new_period].reset(); + sanb_smp_memory_barrier(); + m_period = new_period; + sanb_smp_memory_barrier(); + + m_max_ar[m_win_cnt] = period_elem.get_max(); + m_win_cnt++; + if (m_win_cnt == HISTOGRAM_QUEUE_SIZE) { + m_win_cnt = 0; } - return c_average; + update_average(period_elem); } -void CTimeHistogram::update_average(){ - double c_average=get_cur_average(); +void CTimeHistogram::update_average(CTimeHistogramPerPeriodData &period_elem) { + double c_average; - // low pass filter - m_average = 0.5*m_average + 0.5*c_average; -} + if (period_elem.get_cnt() != 0) + c_average = period_elem.get_sum() / period_elem.get_cnt(); + else + c_average = 0; -dsec_t CTimeHistogram::get_total_average(){ - return (get_cur_average()); + // low pass filter + m_average = 0.5 * m_average + 0.5 * c_average; } -dsec_t CTimeHistogram::get_average_latency(){ +dsec_t CTimeHistogram::get_average_latency() { return (m_average); } -uint32_t CTimeHistogram::get_usec(dsec_t d){ +uint32_t CTimeHistogram::get_usec(dsec_t d) { return (uint32_t)(d*1000000.0); } -void CTimeHistogram::DumpWinMax(FILE *fd){ - - int i; - uint32_t ci=m_win_cnt; +void CTimeHistogram::DumpWinMax(FILE *fd) { + int i; + uint32_t ci=m_win_cnt; - for (i=0; iHISTOGRAM_QUEUE_SIZE-1) { - ci=0; - } - fprintf(fd," %.0f ",d); - } + for (i=0; iHISTOGRAM_QUEUE_SIZE-1) { + ci=0; + } + fprintf(fd," %.0f ",d); + } } -void CTimeHistogram::Dump(FILE *fd){ +void CTimeHistogram::Dump(FILE *fd) { + CTimeHistogramPerPeriodData &period_elem = m_period_data[get_read_period_index()]; + fprintf (fd," min_delta : %lu usec \n", (ulong)get_usec(m_min_delta)); - fprintf (fd," cnt : %lu \n",m_cnt); - fprintf (fd," high_cnt : %lu \n",m_high_cnt); + fprintf (fd," cnt : %lu \n", period_elem.get_cnt()); + fprintf (fd," high_cnt : %lu \n", period_elem.get_high_cnt()); fprintf (fd," max_d_time : %lu usec\n", (ulong)get_usec(m_max_dt)); - //fprintf (fd," average : %.0f usec\n", get_total_average()); fprintf (fd," sliding_average : %.0f usec\n", get_average_latency()); - fprintf (fd," precent : %.1f %%\n",(100.0*(double)m_high_cnt/(double)m_cnt)); + fprintf (fd," precent : %.1f %%\n",(100.0*(double)period_elem.get_high_cnt()/(double)period_elem.get_cnt())); fprintf (fd," histogram \n"); fprintf (fd," -----------\n"); int i; int j; int base=10; - for (j=0; j0 ) { + for (j = 0; j < HISTOGRAM_SIZE_LOG; j++) { + for (i = 0; i < HISTOGRAM_SIZE; i++) { + if (m_hcnt[j][i] > 0) { fprintf (fd," h[%u] : %llu \n",(base*(i+1)),(unsigned long long)m_hcnt[j][i]); } } @@ -210,7 +180,8 @@ void CTimeHistogram::Dump(FILE *fd){ */ -void CTimeHistogram::dump_json(std::string name,std::string & json ){ +void CTimeHistogram::dump_json(std::string name,std::string & json ) { + CTimeHistogramPerPeriodData &period_elem = m_period_data[get_read_period_index()]; char buff[200]; if (name != "") sprintf(buff,"\"%s\":{",name.c_str()); @@ -218,37 +189,32 @@ void CTimeHistogram::dump_json(std::string name,std::string & json ){ sprintf(buff,"{"); json+=std::string(buff); - json+=add_json("min_usec",get_usec(m_min_delta)); - json+=add_json("max_usec",get_usec(m_max_dt)); - json+=add_json("high_cnt",m_high_cnt); - json+=add_json("cnt",m_cnt); - //json+=add_json("t_avg",get_total_average()); - json+=add_json("s_avg",get_average_latency()); + json += add_json("min_usec", get_usec(m_min_delta)); + json += add_json("max_usec", get_usec(m_max_dt)); + json += add_json("high_cnt", period_elem.get_high_cnt()); + json += add_json("cnt", period_elem.get_cnt()); + json+=add_json("s_avg", get_average_latency()); int i; int j; uint32_t base=10; json+=" \"histogram\": ["; - bool first=true; - for (j=0; j0 ) { - if ( first ){ - first=false; + bool first=true; + for (j = 0; j < HISTOGRAM_SIZE_LOG; j++) { + for (i = 0; i < HISTOGRAM_SIZE; i++) { + if (m_hcnt[j][i] > 0) { + if ( first ) { + first = false; }else{ - json+=","; + json += ","; } - json+="{"; - json+=add_json("key",(base*(i+1))); - json+=add_json("val",m_hcnt[j][i],true); - json+="}"; + json += "{"; + json += add_json("key",(base*(i+1))); + json += add_json("val",m_hcnt[j][i],true); + json += "}"; } } - base=base*10; + base = base * 10; } json+=" ] } ,"; - } - - - -- cgit 1.2.3-korg