--- /dev/null
+- duration : 0.1
+ generator :
+ distribution : "seq"
+ clients_start : "16.0.0.1"
+ clients_end : "16.0.0.255"
+ servers_start : "48.0.0.1"
+ servers_end : "48.0.255.255"
+ clients_per_gb : 201
+ min_clients : 101
+ dual_port_mask : "1.0.0.0"
+ tcp_aging : 0
+ udp_aging : 0
+ mac : [0x0,0x0,0x0,0x1,0x0,0x00]
+ #cap_ipg : true
+ cap_info :
+ - name: cap2/udp_10_pkts.pcap
+ cps : 100
+ ipg : 200
+ rtt : 200
+ w : 1
+
}
+
+void CCapFileFlowInfo::update_ipg_by_factor(double factor,
+ CFlowYamlInfo * flow_info){
+ int i;
+
+ CCalcIpgDiff dtick_util(BUCKET_TIME_SEC);
+
+ for (i=0; i<(int)Size(); i++) {
+ CFlowPktInfo * lp=GetPacket((uint32_t)i);
+
+ /* update dtick from ipg */
+ double dtime=0;
+
+ if ( likely ( lp->m_pkt_indication.m_desc.IsPcapTiming()) ){
+ dtime = lp->m_pkt_indication.m_cap_ipg ;
+ }else{
+ if ( lp->m_pkt_indication.m_desc.IsRtt() ){
+ dtime = flow_info->m_rtt_sec ;
+ }else{
+ dtime = flow_info->m_ipg_sec;
+ }
+ }
+ lp->m_pkt_indication.m_cap_ipg = dtime*factor;
+ lp->m_pkt_indication.m_ticks = dtick_util.do_calc(dtime*factor);
+ }
+}
+
void CCapFileFlowInfo::update_min_ipg(dsec_t min_ipg,
dsec_t override_ipg){
}
+void CFlowGeneratorRec::updateIpg(double factor){
+ m_flow_info.update_ipg_by_factor(factor,m_info);
+}
+
+
+
void CFlowGeneratorRec::getFlowStats(CFlowStats * stats){
double t_pkt=(double)m_flow_info.Size();
double mb_sec = (cps*t_bytes*8.0)/(_1Mb_DOUBLE);
double mB_sec = (cps*t_bytes)/(_1Mb_DOUBLE);
- double c_flow_windows_sec=0.0;
+ double c_flow_windows_sec;
- if (m_info->m_cap_mode) {
- c_flow_windows_sec = m_flow_info.get_cap_file_length_sec();
- }else{
- c_flow_windows_sec = t_pkt * m_info->m_ipg_sec;
- }
+ c_flow_windows_sec = m_flow_info.get_cap_file_length_sec();
m_flow_info.get_total_memory(stats->m_memory);
m_client_config_info.dump(fd);
}
+int CFlowGenList::update_active_flows(uint32_t active_flows){
+ double d_active_flow=(double)active_flows;
+ CFlowStats stats;
+ CFlowStats sum;
+ int i;
+
+ for (i=0; i<(int)m_cap_gen.size(); i++) {
+ CFlowGeneratorRec * lp=m_cap_gen[i];
+ lp->getFlowStats(&stats);
+ sum.Add(stats);
+ }
+
+ if (sum.m_c_flows <10) {
+ /* nothing to do */
+ return (0);
+ }
+ double ipg_factor = d_active_flow/sum.m_c_flows;
+
+ /* calc it again */
+ sum.Clear();
+ for (i=0; i<(int)m_cap_gen.size(); i++) {
+ CFlowGeneratorRec * lp=m_cap_gen[i];
+ lp->updateIpg(ipg_factor);
+ lp->getFlowStats(&stats);
+ sum.Add(stats);
+ }
+
+ return(0);
+}
+
int CFlowGenList::load_from_yaml(std::string file_name,
uint32_t num_threads){
uint8_t idx;
m_tw_buckets = 1024;
m_tw_levels = 3;
m_tw_bucket_time_sec = (20.0/1000000.0);
+ m_active_flows=0;
}
CPreviewMode preview;
uint16_t m_tw_buckets;
uint16_t m_tw_levels;
+ uint32_t m_active_flows;
float m_factor;
float m_mbuf_factor;
float m_duration;
public:
void update_min_ipg(dsec_t min_ipg, dsec_t override_ipg);
+ void update_ipg_by_factor(double factor,CFlowYamlInfo * flow_info);
void update_pcap_mode();
void Dump(FILE *fd);
void Dump(FILE *fd);
void getFlowStats(CFlowStats * stats);
+ void updateIpg(double factor);
+
public:
CCapFileFlowInfo m_flow_info;
CFlowYamlInfo * m_info;
double GetCpuUtilRaw();
public:
+ /* update ipg in a way for */
+ int update_active_flows(uint32_t active_flows);
double get_total_kcps();
double get_total_pps();
double get_total_tx_bps();
OPT_CLOSE,
OPT_ARP_REF_PER,
OPT_NO_OFED_CHECK,
+ OPT_ACTIVE_FLOW
};
/* these are the argument types:
{ OPT_NO_WATCHDOG, "--no-watchdog", SO_NONE },
{ OPT_ALLOW_COREDUMP, "--allow-coredump", SO_NONE },
{ OPT_CHECKSUM_OFFLOAD, "--checksum-offload", SO_NONE },
+ { OPT_ACTIVE_FLOW, "--active-flows", SO_REQ_SEP },
{ OPT_CLOSE, "--close-at-end", SO_NONE },
{ OPT_ARP_REF_PER, "--arp-refresh-period", SO_REQ_SEP },
{ OPT_NO_OFED_CHECK, "--no-ofed-check", SO_NONE },
+
SO_END_OF_OPTIONS
};
printf(" When configuring flow stat and latency per stream rules, assume all streams uses VLAN \n");
printf(" --vm-sim : Simulate vm with driver of one input queue and one output queue \n");
printf(" -w <num> : Wait num seconds between init of interfaces and sending traffic, default is 1 \n");
+
+ printf(" --active-flows : An experimental switch to scale up or down the number of active flows. \n");
+ printf(" It is not accurate due to the quantization of flow scheduler and in some case does not work. \n");
+ printf(" Example --active-flows 500000 wil set the ballpark of the active flow to be ~0.5M \n");
+
printf("\n");
printf(" Examples: ");
printf(" basic trex run for 20 sec and multiplier of 10 \n");
po->preview.setFileWrite(true);
po->preview.setRealTime(true);
uint32_t tmp_data;
+ float tmp_double;
po->m_run_mode = CParserOption::RUN_MODE_INVALID;
case OPT_PCAP:
po->preview.set_pcap_mode_enable(true);
break;
+ case OPT_ACTIVE_FLOW:
+ sscanf(args.OptionArg(),"%f", &tmp_double);
+ po->m_active_flows=(uint32_t)tmp_double;
+ break;
case OPT_RX_CHECK :
sscanf(args.OptionArg(),"%d", &tmp_data);
po->m_rx_check_sample=(uint16_t)tmp_data;
m_fl.Create();
m_fl.load_from_yaml(CGlobalInfo::m_options.cfg_file,get_cores_tx());
+ if ( CGlobalInfo::m_options.m_active_flows>0 ) {
+ m_fl.update_active_flows(CGlobalInfo::m_options.m_active_flows);
+ }
+
/* client config */
if (CGlobalInfo::m_options.client_cfg_file != "") {
try {