/*
+ * 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. java centos7配置查看jdk环境变量

    [root@bogon java-1.8.0-openjdk-1.8.0.212.b04-0.el7_6.x86_64]# which java/usr/bin/java[root@bogon jav ...

  2. mysql 5.7 的 /etc/my.cnf

    mysql的my.cnf文件纯净版的.随意享用. # Example MySQL config file for medium systems. # # This is for a system wi ...

  3. oracle--块信息深入解析

    一,创建 Data Block是数据库中最小的I/O单元 01,建立一个新的表空间 查看默认表空间位置 select TABLESPACE_NAME,FILE_NAME from dba_data_f ...

  4. javascrpit sort()数组对象中排序

    /*ionic 调用 * @param attr 排序的属性 如number属性 * @param rev true表示升序排列,false降序排序 * */ commonSortMethod(att ...

  5. (转)Linux:使用libgen.h:basename,dirname

    Linux:使用libgen.h:basename,dirname basename以及dirname是两个命令: [test1280@localhost ~]$ which basename /bi ...

  6. unittest实现批量处理测试集

    批量执行测试集 #coding=utf-8 from selenium import webdriver from selenium.webdriver.common.by import By fro ...

  7. 【随笔】node.js + npm的安装

    需要用到node.js和npm,所以来安装下. 在网上找了找教程,好多都是分开装的,各种麻烦各种事,最后还是在node.js官网里下载解决了.记录一下. 如果安装在当前环境,直接点击install会自 ...

  8. oracle系统包——dbms_alert用法

    oracle内部提供的在数据库内部和应用程序间通信的方式有以下几种:1.警报,就是DBMS_ALERT包提供的功能:2.管道,由DBMS_PIPE提供:3.高级队列,这个就很复杂,当然提供的功能也是很 ...

  9. Python基础(2) - 动态数据类型

    Python是一门强类型语言,单定义变量时不需要制定类型. C#这样定义变量: ; VB这样定义变量: Python不需要制定类型,给变量赋什么类型的值,它就是什么类型.(穿神马就是神马?) > ...

  10. 使用idea开发工具,nginx服务部署Extjs6,SpringBoot项目到服务器

    编译ExtJs文件 1.输入命令 2.开始编译 3.找到编译后的文件 E:\idea_project\BaiSheng_Model\fin-ui\build\production\Admin 4.将文 ...