update_dctcp_alpha
/*
+ * Update dctcp alpha based on the ecn bit in the received packet.
+ * This procedure is called only when dctcp_ is 1.
+ */
+ void FullTcpAgent::update_dctcp_alpha(Packet *pkt)
+ {
+ int ecnbit = hdr_flags::access(pkt)->ecnecho();
+ int ackno = hdr_tcp::access(pkt)->ackno();
+ int acked_bytes = ackno - highest_ack_;
+
+ if (acked_bytes <= )
+ acked_bytes = size_;
+ dctcp_total += acked_bytes;
+ if (ecnbit) {
+ dctcp_marked += acked_bytes;
+ }
+
+ /* Check for barrier indicating its time to recalculate alpha.
+ * This code basically updated alpha roughly once per RTT.
+ */
+ if (ackno > dctcp_alpha_update_seq) {
+ double temp_alpha;
+ dctcp_alpha_update_seq = dctcp_maxseq;
+ if (dctcp_total > )
+ temp_alpha = ((double) dctcp_marked) / dctcp_total;
+ else
+ temp_alpha = 0.0;
+
+ dctcp_alpha_ = ( - dctcp_g_) * dctcp_alpha_ + dctcp_g_ * temp_alpha;
+ dctcp_marked = ;
+ dctcp_total = ;
+ }
+ }
=====================================================================================================
int chooseECNSlot()
{
double maxProgress=;
for(int i=;i<=nslot_;i++)
{
if(slot_[i]!=NULL && window_i>*count)
{
double ti=window_i/(*count);
double iProg=umap[slot_[i]]+(window_i+ti/)*ti;
for(int j=;j<=nslot_;j++)
{
if(slot_[j]!=NULL && window_j>*count)
{
double jProg=umap[slot_[j]]+(window_j+ti/)*ti;
if(jProg>iProg) break;
}
if(j==nslot_)
{
return i;
}
}
}
}//for
return -;//no flow satisfies the condition.(maybe should return the flow with max progress)
} int PortClassifier::recv(Packet* p, Handler*h)
{
NsObject* node = find(p);//find调用classify,classify返回dport。
if (node == NULL) {
Packet::free(p);
return;
} umap[node]++; if(flag)
{
hdr_flags *hf=hdr_flags::access(pickPacketForECN(p));
if(hf->ce()==)
{
hf->ce()=;
mark=chooseECNSlot();
}
if (mark != - &&node==slot_[mark])
{
hf->ce()=;
mark = -;
}
}//end of flag node->recv(p,h);
} void PortClassifier::install(int slot, NsObject* p)//install是用来向slot里赋值的。(连接agent & slot)
{
if (slot >= nslot_)
alloc(slot);
slot_[slot] = p; if (slot >= maxslot_)
maxslot_ = slot; count++;
if(count>=)
flag=; }
================================================================================================================================== classifier-port.h里需要添加的:
()include处
#include <unordered_map> 还要using namespace std?或者不用?在底下定义的时候用std::unordered_map<NsObject*,double> umap
#include "flags.h"//里面有很多需要的变量和函数,如ce()
()3个变量
count=; flag=; mark=-;//可以考虑用复杂些的变量名,防止别的需要include的文件里有重名的
count不止表示agent个数,同时它是server的个数!
flag用来标志receiver; //【但是这样全局变量对吗?sender那边如果使用portclassifier时会累加上吗?不会的。这方法可以。亲测有效。】
//【如果不行就用遍历slot的方法。每次遍历一下看有多少agent。】
()
unordered_map<NsObject*,double> umap;//看看用不用指定std::
=====================================================================================================
=====================================================================================================
=====================================================================================================
update 15.1.12
int chooseECNSlot()
{
int maxValue=-;
int maxDport=-;
int secondMaxValue=-;
int secondMaxDport=-;
for(int i=;i<packetsBetweenECN.size();i++)
{
if(packetsBetweenECN[i].progress>maxValue)
{
maxValue=packetsBetweenECN[i].progress;
maxDport=packetsBetweenECN[i].dport;
}
}
for(int i=;i<packetsBetweenECN.size();i++)
{
if(packetsBetweenECN[i].dport!=maxDport && packetsBetweenECN[i].progress>secondMaxValue)
{
secondMaxValue=packetsBetweenECN[i].progress;
secondMaxDport=packetsBetweenECN[i].dport;
}
}
long long int progressOfMaxWindow;
for(int i=;i<array.size();i++)
{
if(array[i].dport==maxDport)
{
progressOfMaxWindow=array[i].progress;
}
}
int flag_2=;
for(int i=;i<array.size();i++)
{
if(array[i].dport!=maxDport && array[i].progress<=progressOfMaxWindow)
{
flag_2=;
break;
}
}
if(flag_2==)
return maxDport;
else
return secondMaxDport; //return -1;//no flow satisfies the condition.(maybe should return the flow with max progress)
} int PortClassifier::recv(Packet* p, Handler*h)
{
NsObject* node = find(p);//find调用classify,classify返回dport。
if (node == NULL) {
Packet::free(p);
return;
} //umap[node]++; //update total sum of packets
indexNode tmp;
int dportOfP=classify(p);
tmp.dport=dportOfP;
tmp.progress=; if(array.size()==)
{
array.push_back(tmp);
}
else
{
int flag_new=;
for(int i=;i<array.size();i++)
{
if(array[i].dport==dportOfP)
{
array[i].progress++;
flag_new=;
break;
}
}
if(flag_new==)
{
array.push_back(tmp);
}
} //update packetsBetweenECN
if(packetsBetweenECN.size()==)
{
packetsBetweenECN.push_back(tmp);
}
else
{
int flag_new=;
for(int i=;i<packetsBetweenECN.size();i++)
{
if(packetsBetweenECN[i].dport==dportOfP)
{
packetsBetweenECN[i].progress++;
flag_new=;
break;
}
}
if(flag_new==)
{
packetsBetweenECN.push_back(tmp);
}
} //change the behaviour of receiver hdr_flags *hf=hdr_flags::access(pickPacketForECN(p)); if(flag)
{
if(hf->ce()==)
{
hf->ce()=;
mark=chooseECNSlot();
}
if (mark != - &&node==slot_[mark])
{
hf->ce()=;
mark = -;
}
}//end of flag
if(hf->cwr())
{
packetsBetweenECN.clear();
} node->recv(p,h);
} void PortClassifier::install(int slot, NsObject* p)//install是用来向slot里赋值的。(连接agent & slot)
{
if (slot >= nslot_)
alloc(slot);
slot_[slot] = p; if (slot >= maxslot_)
maxslot_ = slot; count++;
if(count>=)
flag=;
}
///////////////////////////////////////////////////////// struct indexNode
{
int dport;
long long int progress;
};
vector<indexNode> array;//totalSum
vector<indexNode> packetsBetweenECN; ===============================================================================================================================================
===============================================================================================================================================
=============================================================================================================================================== classifier-port.h里需要添加的:
()include处
//#include <unordered_map> 还要using namespace std?或者不用?在底下定义的时候用std::unordered_map<NsObject*,double> umap
#include "flags.h"//里面有很多需要的变量和函数,如ce()
()3个变量
count=; flag=; mark=-;//可以考虑用复杂些的变量名,防止别的需要include的文件里有重名的
count不止表示agent个数,同时它是server的个数!
flag用来标志receiver; //【但是这样全局变量对吗?sender那边如果使用portclassifier时会累加上吗?不会的。这方法可以。亲测有效。】
//【如果不行就用遍历slot的方法。每次遍历一下看有多少agent。】
()
//unordered_map<NsObject*,double> umap;//看看用不用指定std::
====================================================================
notes:
别忘了在PortClassifier类定义里加上一行函数声明: void install(int slot, NsObject* p);
recv函数的返回值改为void, 不是int。头文件和实现文件里都要改过来。
对于 ‘pickPacketForECN’ was not declared in this scope,添加了red.h头文件还是不行。大概是需要声明?
//把red.h里的pickPacketForECN()给public了,原本是protected。
//把之前加在classifier-port.h里的类的定义中的recv()函数给改成了public,之前是protected的。
在red.h中定义portclassifier类为友元,并在red.h中include了classifier-port.h 。
error: mobile/dumb-agent.[h,cc] 中有recv(),error说‘virtual void PortClassifier::recv(Packet*, Handler*)’ is protected
dumb-agent里class DumbAgent 是派生的agent类的,而agent本身也有recv函数。portclassifier里之前是没有定义recv函数的。莫非是因为这个干扰到了dumbAgent的recv的使用?我在portclassifier里先把recv注释掉试试。经实验,这样的话可以通过编译,但ns在使用时会segmentation fault,无法正常使用。
刚才调的时候还是使用时有问题,跑例子时就会segment fault。于是我把修改过的classifier-port.[cc,h]这两个文件放到nomad/dctcp-code文件夹备份起来,然后在ns库里删除掉,用原本未经修改过的这两个文件的原件替换进来。这样的话跑例子时就又正常了。看来我得小心翼翼一步一步的改。
最基本的检测ns能不能用,就是直接输入ns,看出不出%
现在是只把install加进去是没有问题,但是加上recv就会有问题。
这会编译能通过,但是在运行例子的时候竟然吞吐量没有变化。不知哪里出了问题。
另外我在用到pickpacketsforecn时直接把它省略了,因为我发现它是直接返回packet的。不知会不会有问题。
需要在脚本里用red而不是fifo。因为我程序里就是靠red打的标记。
在tcl脚本里将DropTail改成RED之后能在吞吐量上看到明显变化。只不过可能由于我算法考虑的不周全,吞吐量反而下降了很多。不过好在能有效果了。下面仔细分析算法的问题,跟踪查找问题并改正。
另外进一步考虑的话可以看red里上下限对齐。参考dctcp的做法。因为传统red里打ce是基于概率的,不是严格按照比例的。
另外,需要看是否发生丢包,直接在trace里就能看到。
考虑一下临界情况,比如当一个流传输完毕时,是否应该从排序候选人中剔除,如果不剔除会出现什么情况。
我似乎没有考虑到ce连续出现的情况。莫非是这个问题?对每一个ce为1的包都做处理。不过receiver好像不会理会多个ecnecho,不会说一直不停的减半。
我应该考虑改一下代码,对于连续的ce只接受一次。
为什么对返回最大窗口还是次大窗口流的代码做修改后(比如改为每次都返回最大窗口的流),吞吐量没有任何变化?莫非chooseECN函数没起作用?
怎么好像我的程序起的作用很少呢。我把recv里的if(flag)去掉后仍得到相同的吞吐量。
加了个waitingCWR变量,这样的话在遇到ce和遇到cwr之间只对一个包打ce,这样就不对连续的包打了。不过这样的话也有弊端。比如当ce=1时说明已经在拥挤了,已经倾向于丢包了,那么这时的ecnecho也是容易丢的。所以发一连串ce的话能保证肯定能把ce这个信息传到server端,只发一个的话就容易丢。
非常悲哀的发现。当我把portclassifier::recv()里自己添加的算法注释掉后,运行示例没有任何区别!坑爹啊。。不过也还好,至少说明吞吐量下降不是我算法的错,因为我的算法压根还没生效,摔。。。
--那么问题来了。既然我都注释掉那些ce操作之后,吞吐量还是那种 838,849,31,42,51,31,37,42,32,35,那么,为什么是这个数而不是838,9xx,9xx,........,104 ?
--原因是,当在nx和nc之间的链路上使用DropTail时,就会是8xx,9xx,9xx。。。104. 而如果用的是RED的话,就会是838,849,31,42这种。是不同队列算法导致的这个差异。
但是我的算法还是没起作用啊。分析一下原因。portclassifier是不是用错了。
\====================================================================================================================
1.14
会不会在tcl脚本里用的agent不是FullTCP?
果然用的不是TCP/FullTcp。在tcl里改过来之后,运行tcl脚本就会出现一堆bug。
但是我好像没有改agent相关的内容啊。我是直接改得中间的classifier啊。
现在先把classifier的两个程序替换成original code,试试是不是fulltcp本身的问题。
老师分析的没错。仅仅把DropTail换成RED不能差别这么大,估计是tcl脚本里一些细节导致的,比如loss module那块。
于是我把loss module那块注释掉,果然有变化!
这样的话出现4种状态:注释前的RED,注释前的DropTail,注释后的。。。。
还有一个是76行的,singledup。注释掉后也会有所不同。
update_dctcp_alpha的更多相关文章
- l2dct
http://paste.ubuntu.com/15664711/ diff -crbB ns-allinone-2.35/ns-2.35/queue/red.cc ns-2.35/queue/red ...
- dctcp-ns2-patch
diff -crbB ns-allinone-2.35/ns-2.35/queue/red.cc ns-2.35/queue/red.cc *** ns-allinone--- :: --- ns-- ...
随机推荐
- 20190430-BootstrapのJS插件
目录 1.引用 2. 内容 1.引用 引用该插件需注意俩点 1.1插件依赖JQ:JQ必须在所有插件之前,bower.json内列出BT所支持的JQ版本(1.9.1-3) BootCDNのJQ J ...
- [JAVA]流控及超流控后的延迟处理
流控检查(每半秒累计,因此最小留空阀值只能做到每秒2条): import java.text.SimpleDateFormat; import java.util.Date; import java. ...
- Go语言包管理工具Glide
Go语言包管理工具用于管理Go项目的库和库的依赖引用. 包管理工具普遍会在Go项目根目录生成Vendor文件夹并自动下载该Go项目需要的库. Go语言有很多开源的包管理工具,这里主要介绍Glide ...
- selenium+Python(alert 、confirm 、prompt 的处理)
alert\confirm\prompt 弹出框操作主要方法有: text 返回 alert/confirm/prompt 中的文字信息 accept 点击确认按钮 dismiss 点击取消按钮, ...
- 在VM虚拟机中彻底删除Linux系统
前言:很久之前安装了Linux虚拟系统,然后用户名忘记了,想着重新安装个Ubuntu系统,就想着删除以前的系统. 删除方法如下: 1.点击打开该Linux系统. 2. 点击虚拟机的左上方“虚拟机”-& ...
- ES6内容
iterator 遍历器iterator makeIterator是个遍历器,生成遍历器对象it var it = makeIterator(['a', 'b']); it.next() // { v ...
- Python基础(3) - 数据类型:2字符串类型
Python字符串的表示有三种方法: 1.单引号(') >>>a = 'I love python. ' 2.双引号(") >>>a = " I ...
- golang基础---Slice切片
切片Slice在go语言中是单独的类型(指向底层的数组),不同于python(对可迭代对象操作的工具),注意区分数组和slice的区别 定义一个空slice,格式var s []int,这种既没有长度 ...
- NPOI excel导出快速构建
直接上代码,这个是一个在webFrom中的例子,要请求的页面是ashx public void ExportVisaFeeAll(HttpContext context) { try { string ...
- javascript typeof 和 instanceof 的区别和联系
这篇文章是我看完<JavaScript高级程序设计(第2版)>书籍的随笔文章,目的只有一个,以备自己和网友们方便参考和记忆! typeof是什么? typeof 是一个操作 ...