/*
+ * 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的更多相关文章

  1. l2dct

    http://paste.ubuntu.com/15664711/ diff -crbB ns-allinone-2.35/ns-2.35/queue/red.cc ns-2.35/queue/red ...

  2. dctcp-ns2-patch

    diff -crbB ns-allinone-2.35/ns-2.35/queue/red.cc ns-2.35/queue/red.cc *** ns-allinone--- :: --- ns-- ...

随机推荐

  1. Django Rest Framework(阿奇)

    Django Rest Framework 一. 什么是RESTful REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中 ...

  2. 用hashmap实现redis有什么问题

    1.容量问题 hashmap是有最大容量的 2.时效问题 redis可以持久化,也可以定时时间 hashmap不可以持久化 3.线程并发问题 hashmap不是线程安全的(并且:多线程同时调用hash ...

  3. SpringCloud---客户端负载均衡---Spring Cloud Ribbon

    1.概述 1.1 Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具: 基于Netflix Ribbon实现: 通过Spring Cloud的封装,可以轻松将面向服务 ...

  4. js控制a标签点击事件 触发下载

    问题背景,动态获取data把url赋值到a标签的url中,让a标签自动下载 首先想到的应该是$('xxx').click(), 查资料明白:js中的$(...).click()事件只能触发绑定的onC ...

  5. 3dsmax2012卸载/安装失败/如何彻底卸载清除干净3dsmax2012注册表和文件的方法

    3dsmax2012提示安装未完成,某些产品无法安装该怎样解决呢?一些朋友在win7或者win10系统下安装3dsmax2012失败提示3dsmax2012安装未完成,某些产品无法安装,也有时候想重新 ...

  6. day2-模块初识之路径问题

    sys需要调用my_test,但是不在同一目录 会出现如下错误 具体办法:1.将my_test.py放到文件夹下 附:sys.py 和my-test.py具体代码 enumerate 重点:浅复制(用 ...

  7. Oracle 中运用rollup和cube实现汇总运算

    前言.看了很多的随笔博文内容都是关于rollup和cube的用法,发现一个问题,很多都是一样或者转载的,但这都不是重点,重点是,他们写的都太专业化了,直接给一个结论,并没有给出整个推理出这个结论的过程 ...

  8. MySQL prompt提示符总结

      A counter that increments for each statement you issue \D 当前日期 \d 当前数据库 \h 数据库主机 \l The current de ...

  9. 算法学习笔记之——priority queue、heapsort、symbol table、binary search trees

    Priority Queue 类似一个Queue,但是按照priority的大小顺序来出队 一般存在两种方式来实施 排序法(ordered),在元素入队时即进行排序,这样插入操作为O(N),但出队为O ...

  10. 转 File "/usr/bin/yum", line 30 except KeyboardInterrupt, e:

    因为yum包使用python2*等开发,修该为环境修改python3之后有问题, 解决: 修改文件/usr/bin/yum./usr/libexec/urlgrabber-ext-down头中相应py ...