一,流量模型原理
帕累托分布是一种代表性的长尾分布,极端值概率小。在曲线的头部,数据出现的频率很高,随着数据的出现频率逐渐降低,曲线也逐渐下降,缓慢趋近于横轴,看起来就像拖着一条长长的尾巴。
1,帕累托分布的on/off时间
帕累托分布的公式如下, x m i n x_{min} xmin 是分布的最小值, k k k 是形状参数,控制 Pareto 分布的“长尾”程度。当 k k k 越大时,Pareto分布的长尾越长,即分布的尾部部分包含了更多的概率质量。
帕累托分布的实现方式如下,其中,sendf是发送单个包所需时间,u是0~1之间的随机数,m是以0.87为参数的帕累托分布计算值。该实现方式以0.87为形状参数,以senf为极端值。
double u=AverageRandom(0,1);
double m=pow(u, (double)1/1.2);
if(offerload <= 0.5){
on = sendf / m;
off = ((1-offerload)/offerload)*on;
}
else{
off = sendf / m;
on = off*offerload/(1-offerload);
}
当负载小于等于0.5时,on的时间满足帕累托分布,且以sendf为极端值,保证低负载时每条流至少发一个包;当负载大于0.5时,off的时间以sendf为极端值,保证高负载时每条流至少间隔一个数据包的时间。
2,负载意义
在本模型中,所有on和off的时间严格满足:
负载从时间角度刻画,onoffapp以接入链路带宽的全速去发送流量,全速发流的时间on占此APP的on+off总时间的比例,即负载的值。
3,总体效果
网络注入速率服从帕累托分布。且流的大小取决于服从帕累托分布的on/off时间,最终其CDF有着与下图接近的趋势。
二,ns-3实现
1,变量组及注释
ns-3中生成指数分布的随机数,需要使用ExponentialRandomVariable
类,头文件需要#include “ns3/random-variable-stream.h”
int packetLengthBytes=1024;
double CDbandwidth=1024*1024*1024*10.0;//链路带宽
double sendf=packetLengthBytes*8/CDbandwidth;//发送单个包所需时间
double next_time=0;
double on=0.0, off=0.0;
char onfilename[50];
char offfilename[50];
double offerload=0.1;//负载
double run_time=0.002;//单个节点发多个流的总时间
uint32_t desttemp;
uint32_t src;
uint32_t port[10000];
double AverageRandom(double min, double max);
2,源和目的节点循环
源节点遍历全部host节点,目的节点随机生成,范围0~(numofhost-1)。确认源和目的节点后,将NextStartTime置0,保证所有节点均从0时刻开始流量传输。
for(uint32_t src=0;src<numofHost;src++){
for(uint32_t i=0;i<RandDestNum;i++){
do{
dest = rand()%numofHost;
}while(src == dest);
double NextStartTime = 0;
}
}
3,帕累托分布on/off
on/off的时间根据负载大小分情形设置极端值,并且设置为onoffapp的参数。
if(offerload <= 0.5){
on = sendf / m;
off = ((1-offerload)/offerload)*on;
}
else{
off = sendf / m;
on = off*offerload/(1-offerload);
}
sprintf(onfilename, "ns3::ConstantRandomVariable[Constant=%.9f]",on);
sprintf(offfilename, "ns3::ConstantRandomVariable[Constant=%.9f]",off);
OnOffHelper clientHelper1 ("ns3::UdpSocketFactory", Address ());
clientHelper1.SetAttribute ("OnTime", StringValue (onfilename));
clientHelper1.SetAttribute ("OffTime", StringValue (offfilename));
clientHelper1.SetAttribute ("DataRate", DataRateValue (DataRate ("10Gbps")));
clientHelper1.SetAttribute ("PacketSize", UintegerValue (1024));
clientHelper1.SetAttribute ("Totaltime", DoubleValue (on));
clientHelper1.SetAttribute ("Stoptime", DoubleValue (run_time));
发送数据流的app启动时刻以totaltime为间隔,保证了随机性。
三,流量模型实现代码
int packetLengthBytes=1024;
double CDbandwidth=1024*1024*1024*10.0;//链路带宽
double sendf=packetLengthBytes*8/CDbandwidth;//发送单个包所需时间
double next_time=0;
double on=0.0, off=0.0;
char onfilename[50];
char offfilename[50];
double offerload=0.1;//负载
double run_time=0.002;//单个节点发多个流的总时间
uint32_t desttemp;
uint32_t src;
uint32_t port[10000];
double AverageRandom(double min, double max);
...
void ParetoApp (){
for(uint32_t i=0;i<numofHost;i++){
next_time=0.0;
for(uint32_t j=0;j<3;j++){
uint32_t ii= rand()%numofHost;
if(i==ii){
j=j-1;
}
if(i!=ii){
desttemp = ii;
std::cout << "src:" << i << " dest:" << desttemp <<std::endl;
while(next_time<run_time){
double u=AverageRandom(0,1);
double m=pow(u, (double)1/1.2);
if(offerload <= 0.5){
on = sendf / m;
off = ((1-offerload)/offerload)*on;
}
else{
off = sendf / m;
on = off*offerload/(1-offerload);
}
sprintf(onfilename, "ns3::ConstantRandomVariable[Constant=%.9f]",on);
sprintf(offfilename, "ns3::ConstantRandomVariable[Constant=%.9f]",off);
OnOffHelper clientHelper1 ("ns3::UdpSocketFactory", Address ());
clientHelper1.SetAttribute ("OnTime", StringValue (onfilename));
clientHelper1.SetAttribute ("OffTime", StringValue (offfilename));
clientHelper1.SetAttribute ("DataRate", DataRateValue (DataRate ("10Gbps")));
clientHelper1.SetAttribute ("PacketSize", UintegerValue (1024));
clientHelper1.SetAttribute ("Totaltime", DoubleValue (on));
clientHelper1.SetAttribute ("Stoptime", DoubleValue (run_time));
ApplicationContainer clientApps1;
AddressValue remoteAddress (InetSocketAddress (ipEH[desttemp].GetAddress (1), port[desttemp]));
clientHelper1.SetAttribute ("Remote", remoteAddress);
clientApps1.Add (clientHelper1.Install (hostNodes.Get (i)));
clientApps1.Start (Seconds (next_time));
clientApps1.Stop (Seconds (10.0));
Address sinkLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port[desttemp]));
PacketSinkHelper sinkHelper ("ns3::UdpSocketFactory", sinkLocalAddress);
ApplicationContainer sinkApp = sinkHelper.Install (hostNodes.Get (desttemp));
sinkApp.Start (Seconds (next_time));
sinkApp.Stop (Seconds (10.0));
next_time=next_time+on+off;
port[desttemp]++;
//std::cout << "\033[1A\r port:" << port << " runtime:"<< run_time << " 精度:" << 0.0001 << std::endl;
}
}
}
}
}
double AverageRandom(double min, double max){
int minInteger = (int)(min*10000);
int maxInteger = (int)(max*10000);
int randInteger =0;
int diffInteger =0;
double resultInteger=0.0;
while(resultInteger<=0){
randInteger = rand() * rand();
diffInteger = maxInteger - minInteger;
resultInteger = (randInteger%diffInteger + minInteger)/10000.0;
}
// printf("randInteger:%d\n", randInteger);
return resultInteger;
}