/*
+ * 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. 20190430-screen、client、offset、scroll等JS中各种宽度距离

    参考文献: JavaScript概念之screen/client/offset/scroll/inner/avail的width/left

  2. JQ 输入框控制输入 - 键盘上事件

    <li style="width: 480px">限购数量  <input type="number" name="limitNum ...

  3. 【爬虫】-爬取猫眼TOP100

    原文崔庆才<python3网络爬虫实战> 本文为自学记录,如有侵权,请联系删除 目标: 熟悉正则表达式,以及爬虫流程 获取猫眼TOP100榜单 1.网站分析 目标站点为http://www ...

  4. unity2018的坑点

    发布后有的电脑无法运行exe程序(反正我的电脑不行) 删除发布出来的一个叫UnityCrashHandler64.exe即可运行

  5. JNI注册调用完整过程-安卓4.4

    在Android系统中,JNI方法是以C/C++语言来实现的,然后编译在一个so文件里面,以我之前的例子为例Android Studio使用JNI,调用之前要加载到当前应用程序的进程的地址空间中: s ...

  6. maven配置编译器的版本

    发现每次启动idea时,项目里很多红色错误,都是的编译器版本不对,每次都要手动修改. 其实在pom里把默认编译器版本加进去就好了. <build> <plugins> < ...

  7. SpringBoot和SpringCloud区别

    SpringBoot专注于快速方便的开发单个个体微服务.    SpringCloud是关注全局的微服务协调整理治理框架,它将SpringBoot开发的一个个单体微服务整合并管理起来,    为各个服 ...

  8. C#基础笔记 转自wojiushigelg

    笔记如下: 概念:.net与c# .net/dontnet:一般指.net framework框架,一种平台,一种技术 c#(charp):一种编程语言,可以开发基于.net的应用. *java既是一 ...

  9. 05.部分类 partial

    namespace _06.部分类 { class Program { static void Main(string[] args) { } } /// <summary> /// 这个 ...

  10. Java 重写(Override)与重载(Overload)区别

    2019-04-1217:31:19 (1)方法重载是一个类中定义了多个方法名相同,而他们的参数的数量不同或数量相同而类型和次序不同,则称为方法的重载(Overloading). (2)方法重写是在子 ...