• update_dctcp_alpha


     1  /*
     2 +  * Update dctcp alpha based on the ecn bit in the received packet.
     3 +  * This procedure is called only when dctcp_ is 1.
     4 +  */
     5 + void FullTcpAgent::update_dctcp_alpha(Packet *pkt)
     6 + {
     7 +     int ecnbit = hdr_flags::access(pkt)->ecnecho();
     8 +     int ackno = hdr_tcp::access(pkt)->ackno();
     9 +     int acked_bytes = ackno - highest_ack_; 
    10 + 
    11 +     if (acked_bytes <= 0) 
    12 +         acked_bytes = size_;    
    13 +     dctcp_total += acked_bytes;
    14 +     if (ecnbit) {
    15 +         dctcp_marked += acked_bytes;
    16 +     }
    17 + 
    18 +     /* Check for barrier indicating its time to recalculate alpha.
    19 +      * This code basically updated alpha roughly once per RTT.
    20 +      */
    21 +     if (ackno > dctcp_alpha_update_seq) {
    22 +         double temp_alpha;
    23 +         dctcp_alpha_update_seq = dctcp_maxseq;
    24 +         if (dctcp_total > 0) 
    25 +             temp_alpha = ((double) dctcp_marked) / dctcp_total;
    26 +         else 
    27 +             temp_alpha = 0.0;
    28 + 
    29 +         dctcp_alpha_ = (1 - dctcp_g_) * dctcp_alpha_ + dctcp_g_ * temp_alpha;
    30 +         dctcp_marked = 0;
    31 +         dctcp_total = 0;
    32 +     }
    33 + }

     =====================================================================================================

     1 int chooseECNSlot()
     2 {
     3     double maxProgress=0;
     4     for(int i=0;i<=nslot_;i++)
     5     { 
     6         if(slot_[i]!=NULL && window_i>2*count)
     7         {
     8             double ti=window_i/(2*count);
     9             double iProg=umap[slot_[i]]+(window_i+ti/2)*ti;
    10             for(int j=0;j<=nslot_;j++)
    11             {
    12                 if(slot_[j]!=NULL && window_j>2*count)
    13                 {
    14                     double jProg=umap[slot_[j]]+(window_j+ti/2)*ti;
    15                     if(jProg>iProg) break;
    16                 }
    17                 if(j==nslot_) 
    18                 {
    19                     return i;
    20                 }
    21             }
    22         }
    23     }//for
    24     return -1;//no flow satisfies the condition.(maybe should return the flow with max progress)
    25 }
    26 
    27 int PortClassifier::recv(Packet* p, Handler*h)
    28 {
    29     NsObject* node = find(p);//find调用classify,classify返回dport。
    30     if (node == NULL) {
    31         Packet::free(p);
    32         return;
    33     }
    34     
    35     umap[node]++;
    36     
    37     if(flag)
    38     {        
    39         hdr_flags *hf=hdr_flags::access(pickPacketForECN(p));
    40         if(hf->ce()==1)
    41         {
    42             hf->ce()=0;
    43             mark=chooseECNSlot();
    44         }
    45         if (mark != -1 &&node==slot_[mark]) 
    46         {
    47             hf->ce()=1;
    48             mark = -1;
    49         }
    50     }//end of flag
    51     
    52     node->recv(p,h);
    53 }
    54       
    55 void PortClassifier::install(int slot, NsObject* p)//install是用来向slot里赋值的。(连接agent & slot)
    56 {
    57     if (slot >= nslot_)
    58         alloc(slot);
    59     slot_[slot] = p;
    60     
    61     if (slot >= maxslot_)
    62         maxslot_ = slot;
    63         
    64     count++;
    65     if(count>=2) 
    66         flag=1;
    67     
    68 }   
    69 ==================================================================================================================================
    70 
    71 classifier-port.h里需要添加的:
    72 (1)include处
    73 #include <unordered_map> 还要using namespace std?或者不用?在底下定义的时候用std::unordered_map<NsObject*,double> umap
    74 #include "flags.h"//里面有很多需要的变量和函数,如ce()
    75 (2)3个变量
    76 count=0; flag=0; mark=-1;//可以考虑用复杂些的变量名,防止别的需要include的文件里有重名的
    77 count不止表示agent个数,同时它是server的个数!
    78 flag用来标志receiver;
    79 
    80 //【但是这样全局变量对吗?sender那边如果使用portclassifier时会累加上吗?不会的。这方法可以。亲测有效。】
    81 //【如果不行就用遍历slot的方法。每次遍历一下看有多少agent。】
    82 (3)
    83 unordered_map<NsObject*,double> umap;//看看用不用指定std::

    =====================================================================================================

     =====================================================================================================

     =====================================================================================================

    update 15.1.12

      1 int chooseECNSlot()
      2 {
      3     int maxValue=-1;
      4     int maxDport=-1;
      5     int secondMaxValue=-1;
      6     int secondMaxDport=-1;
      7     for(int i=0;i<packetsBetweenECN.size();i++)
      8     {        
      9         if(packetsBetweenECN[i].progress>maxValue)
     10         {
     11             maxValue=packetsBetweenECN[i].progress;
     12             maxDport=packetsBetweenECN[i].dport;
     13         }        
     14     }
     15     for(int i=0;i<packetsBetweenECN.size();i++)
     16     {        
     17         if(packetsBetweenECN[i].dport!=maxDport && packetsBetweenECN[i].progress>secondMaxValue)
     18         {
     19             secondMaxValue=packetsBetweenECN[i].progress;
     20             secondMaxDport=packetsBetweenECN[i].dport;
     21         }        
     22     }
     23     long long int progressOfMaxWindow;    
     24     for(int i=0;i<array.size();i++)
     25     {
     26         if(array[i].dport==maxDport)
     27         {
     28             progressOfMaxWindow=array[i].progress;
     29         }
     30     }
     31     int flag_2=0;
     32     for(int i=0;i<array.size();i++)
     33     {
     34         if(array[i].dport!=maxDport && array[i].progress<=progressOfMaxWindow)
     35             {
     36                 flag_2=1;
     37                 break;
     38             }
     39     }
     40     if(flag_2==1)
     41         return maxDport;
     42     else
     43         return secondMaxDport;
     44         
     45     //return -1;//no flow satisfies the condition.(maybe should return the flow with max progress)
     46 }
     47 
     48 int PortClassifier::recv(Packet* p, Handler*h)
     49 {
     50     NsObject* node = find(p);//find调用classify,classify返回dport。
     51     if (node == NULL) {
     52         Packet::free(p);
     53         return;
     54     }
     55     
     56     //umap[node]++;
     57     
     58     //update total sum of packets
     59     indexNode tmp;
     60     int dportOfP=classify(p);
     61     tmp.dport=dportOfP;
     62     tmp.progress=1;
     63     
     64     if(array.size()==0)
     65     {
     66         array.push_back(tmp);        
     67     }
     68     else
     69     {
     70         int flag_new=0;
     71         for(int i=0;i<array.size();i++)
     72         {
     73             if(array[i].dport==dportOfP)
     74             {
     75                 array[i].progress++;
     76                 flag_new=1;
     77                 break;
     78             }
     79         }
     80         if(flag_new==0)
     81         {
     82             array.push_back(tmp);            
     83         }
     84     }
     85     
     86     //update packetsBetweenECN
     87     if(packetsBetweenECN.size()==0)
     88     {
     89         packetsBetweenECN.push_back(tmp);
     90     }
     91     else
     92     {
     93         int flag_new=0;
     94         for(int i=0;i<packetsBetweenECN.size();i++)
     95         {
     96             if(packetsBetweenECN[i].dport==dportOfP)
     97             {
     98                 packetsBetweenECN[i].progress++;
     99                 flag_new=1;
    100                 break;
    101             }
    102         }
    103         if(flag_new==0)
    104         {
    105             packetsBetweenECN.push_back(tmp);            
    106         }
    107     }
    108     
    109     //change the behaviour of receiver
    110     
    111     hdr_flags *hf=hdr_flags::access(pickPacketForECN(p));
    112     
    113     if(flag)
    114     {            
    115         if(hf->ce()==1)
    116         {
    117             hf->ce()=0;
    118             mark=chooseECNSlot();
    119         }
    120         if (mark != -1 &&node==slot_[mark]) 
    121         {
    122             hf->ce()=1;
    123             mark = -1;
    124         }
    125     }//end of flag
    126     if(hf->cwr())
    127     {
    128         packetsBetweenECN.clear();
    129     }
    130     
    131     node->recv(p,h);
    132 }
    133      
    134 void PortClassifier::install(int slot, NsObject* p)//install是用来向slot里赋值的。(连接agent & slot)
    135 {
    136     if (slot >= nslot_)
    137         alloc(slot);
    138     slot_[slot] = p;
    139     
    140     if (slot >= maxslot_)
    141         maxslot_ = slot;
    142         
    143     count++;
    144     if(count>=2) 
    145         flag=1;
    146 }   
    147 /////////////////////////////////////////////////////////
    148 
    149 struct indexNode
    150 {
    151     int dport;
    152     long long int progress;
    153 };
    154 vector<indexNode> array;//totalSum
    155 vector<indexNode> packetsBetweenECN;
    156 
    157 
    158 
    159 ===============================================================================================================================================
    160 ===============================================================================================================================================
    161 ===============================================================================================================================================
    162 
    163 
    164 
    165 classifier-port.h里需要添加的:
    166 (1)include处
    167 //#include <unordered_map> 还要using namespace std?或者不用?在底下定义的时候用std::unordered_map<NsObject*,double> umap
    168 #include "flags.h"//里面有很多需要的变量和函数,如ce()
    169 (2)3个变量
    170 count=0; flag=0; mark=-1;//可以考虑用复杂些的变量名,防止别的需要include的文件里有重名的
    171 count不止表示agent个数,同时它是server的个数!
    172 flag用来标志receiver;
    173 
    174 //【但是这样全局变量对吗?sender那边如果使用portclassifier时会累加上吗?不会的。这方法可以。亲测有效。】
    175 //【如果不行就用遍历slot的方法。每次遍历一下看有多少agent。】
    176 (3)
    177 //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。注释掉后也会有所不同。

  • 相关阅读:
    mysql 视图使用
    mysql 5.7 Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated column ...报错
    mysql创建数据库指定字符集和校对规则
    grep 命令使用
    awk 命令使用
    if [ $# -ne 1 ] 作用
    shell 获取当前目录下的jar文件
    jar 命令使用
    unzip 命令指定解压路径
    Win10系列:JavaScript写入和读取文件
  • 原文地址:https://www.cnblogs.com/forcheryl/p/4212765.html
Copyright © 2020-2023  润新知