在LTE协议栈的PDCP层和RLC层,都有一个重排序窗口(reordering window),主要用来保证数据的可靠传输,PDCP层的重排序窗口主要用于handover时保证数据的可靠传输,这里暂且不表,只讨论RLC层的重排序窗口。

对RLC层,在AM接收模式和UM接收模式下,UM接收实体/AM实体接收端有一个重排序窗口,当接收到的RLC PDU位于重排序窗口内,且之前没有被接收过时,接收端才会对该RLC PDU进行处理,重排序窗口大小无论是在UM模式还是AM模块下都是序列号(SN)取值范围的一半。例如,在AM模式下,假如SN长度为10bit,那么SN取值范围为0 ~ 2^10-1,即0 ~ 1023,则重排序窗口大小为512。

刚开始的时候,我一直不太明白,为什么重排序窗口要选择这么一个数?不能取大点或者取小点吗?我想了一下,没想明白,就囫囵吞枣地默认了这个事实,直到有一天,我在Andrew S. Tanenbaum写的Computer Networks一书中才偶然发现了答案。As an aside,这里推荐一下Tanenbaum写的另外一本书——Modern operating systems,这本书对现代操作系统里面基本的元素和概念都进行了比较详细的阐述,虽然有些地方略有晦涩,并且似乎有点far-fetched之嫌,但是不深究里面的code snippet,仅从其对操作系统一些思想的论述来理解操作系统的设计的话,仍然大有裨益。

回到前面的讨论,在AM模式下,RLC PDU不一定要按序接收,假如收到的RLC PDU不是期望接收到的下一帧RLC PDU(i.e. 其SN不等于VR(R)变量的值),但是却位于重排序窗口内,那么接收端仍然会将该RLC PDU缓存下来,这种非顺序接收(Nonsequential receive)方法相比只能按序接收的协议会引入一个问题,而这个问题恰好可以通过对重排序窗口大小的设置来优雅地解决掉。这里我直接引用Tanenbaum的Computer Networks一书中3.4.3节的例子来阐述这个问题。

假设现在RLC PDU的SN号长度为3bit,初始时刻,发送端和接收端的窗口如图所示。图中,a图是初始时刻发送端和接收端窗口的情况。发送端发送窗口为0~6,假设发送端将发送窗口内的RLC PDU全都发送出去了,接收端成功地接收到了SN0~6 RLC PDU,那么接收端就会将窗口往右挪,并将VR(MS)更新为7,此时接收窗口变为7、0~5,如b图所示。同时,接收端会给发送端发ACK,通知发送端它已经接收到了SN0 ~6 RLC PDU,发送端可以发送新的RLC PDU了。不幸的是,接收端给发送端回复的ACK全都丢失了,发送端一个都没收着,其发送窗口仍然保持不动,这种情况被称为window stalling(窗口停滞)。就这样,一段时间过后,发送端的t-Pol 大专栏  对RLC重排序窗口大小的一点讨论lRetransmit timer将会超时,此时发送端还没有收到0~6 RLC PDU的ACK,它会认为对方可能没有收到这7个RLC PDU,于是又重传SN0 RLC PDU,并且将该RLC PDU header里的Poll位置1,询问对方是不是没有收着它刚发出去的7个RLC PDU。当SN0 RLC PDU到达接收端时,接收端检查其是否位于接收窗口内,此时接收窗口为7、0~5,如b图所示。很不幸,SN0 RLC PDU正好位于其中,接收端认为这是一帧新的RLC PDU,于是很愉快地接收下这帧RLC PDU,然后回了一帧status report(因为它收到的RLC PDU的P位为1),ACK_SN为7,告诉发送端SN 0~6 RLC PDU都已经接收到了。发送端这会终于收到ACK了(i.e. status report),知道SN 0~6 RLC PDU已经被对方成功接收了,于是很愉快地把发送窗口往前移动,发送窗口变为7、0~5。发送端继续发送SN7、0 ~ 5 RLC PDU给对方,接收端收到SN7、0~5RLC PDU后,发现接收buffer里面已经有SN0 RLC PDU了,就认为新接收到的SN0 RLC PDU是duplicate packet,于是就把新接收到的SN0 RLC PDU给丢弃了,然后对接收buffer里的旧的SN0 RLC PDU连同新接收到的SN7、SN1~5 RLC PDU一起解析,再向上提交给PDCP层。显然,PDCP会得到错误的packet,原因就在于RLC层把旧的SN0 RLC PDU当成了新的RLC PDU,而把真正的新的RLC PDU当成了duplicate packet给丢弃了,通信就此出错。

解决这个问题的方法就是要确保接收窗口在往右移动的过程中,不会把原来的窗口给覆盖掉(即窗口移进来的部分不会与窗口移出去的部分发生重叠),上面的例子之所以会出错,就是因为接收窗口往右移动的过程中,新的窗口右边缘为SN5,刚好落入到旧的窗口里面(SN0~6),新的窗口把旧的窗口的一部分给覆盖掉了(覆盖了SN0 ~ 5)。为了保证新的窗口不会覆盖到旧的窗口,窗口的大小最大不能超过序列号范围的一半。以图c和图d为例,序列号的范围仍然为0~7,发送窗口大小变为4,任何时刻最多只能有4帧没有被确认的RLC PDU。这种情况下,当接收端接收到SN0 ~ 3 RLC PDU之后,将会往右移动接收窗口,允许接收SN 4 ~ 7 RLC PDU,这时候,接收端可以明确地区分出发送端发过来的是重传的RLC PDU(SN0 ~ 3)还是新的RLC PDU(SN4 ~ 7)。一般来说,接收窗口和发送窗口的大小为(MAX_SEQ+1)/2,MAX_SEQ为SN的最大取值。上面的例子中,MAX_SEQ为7,因此窗口大小应该设置为4。当然了,窗口大小也可以取小一点,(MAX_SEQ+1)/2只是一个上界,极端一点的话,甚至可以把窗口大小设为1,但是没人会这么干,因为这样的话每次发送都只能发送一帧RLC PDU,然后又要等上老半天,等接收到对方的回复的确认才能发下一帧,采用这种通信方式效率会非常低。所以,这就是为什么RLC层窗口的大小要设置为序列号一半的原因。

对RLC重排序窗口大小的一点讨论的更多相关文章

  1. 深入浅出 Java Concurrency (4): 原子操作 part 3 指令重排序与happens-before法则

    转: http://www.blogjava.net/xylz/archive/2010/07/03/325168.html 在这个小结里面重点讨论原子操作的原理和设计思想. 由于在下一个章节中会谈到 ...

  2. 深入浅出 Java Concurrency (4): 原子操作 part 3 指令重排序与happens-before法则[转]

    在这个小结里面重点讨论原子操作的原理和设计思想. 由于在下一个章节中会谈到锁机制,因此此小节中会适当引入锁的概念. 在Java Concurrency in Practice中是这样定义线程安全的: ...

  3. 指令重排序 as-if-serial

    笔者认为看完一本书或刚要了解完一个知识点  最好自己先运行一些DEMO 自己尝试着去了解下各种意思  这样知识点最终一定是你的.靠死记硬背的讨论或简单的粗暴的看下资料 脑子里肯定还是一团浆糊. p.p ...

  4. Java的多线程机制系列:不得不提的volatile及指令重排序(happen-before)

    一.不得不提的volatile volatile是个很老的关键字,几乎伴随着JDK的诞生而诞生,我们都知道这个关键字,但又不太清楚什么时候会使用它:我们在JDK及开源框架中随处可见这个关键字,但并发专 ...

  5. Java的多线程机制系列:(四)不得不提的volatile及指令重排序(happen-before)

    一.不得不提的volatile volatile是个很老的关键字,几乎伴随着JDK的诞生而诞生,我们都知道这个关键字,但又不太清楚什么时候会使用它:我们在JDK及开源框架中随处可见这个关键字,但并发专 ...

  6. Java内存访问重排序笔记

    >>关于重排序 重排序通常是编译器或运行时环境为了优化程序性能而采取的对指令进行重新排序执行的一种手段. 重排序分为两类:编译期重排序和运行期重排序,分别对应编译时和运行时环境. > ...

  7. 指令重排序及Happens-before法则随笔

    指令重排序 对主存的一次访问一般花费硬件的数百次时钟周期.处理器通过缓存(caching)能够从数量级上降低内存延迟的成本这些缓存为了性能重新排列待定内存操作的顺序.也就是说,程序的读写操作不一定会按 ...

  8. 深入浅出Java并发包—指令重排序

    前面大致提到了JDK中的一些个原子类,也提到原子类是并发的基础,更提到所谓的线程安全,其实这些类或者并发包中的这么一些类,都是为了保证系统在运行时是线程安全的,那到底怎么样才算是线程安全呢? Java ...

  9. 轻松学JVM(二)——内存模型、可见性、指令重排序

    上一篇我们介绍了JVM的基本运行流程以及内存结构,对JVM有了初步的认识,这篇文章我们将根据JVM的内存模型探索java当中变量的可见性以及不同的java指令在并发时可能发生的指令重排序的情况. 内存 ...

随机推荐

  1. python深度学习6.2

    Deep Learning with Python>第六章 6.2 理解循环神经网络(RNN) 神机喵算 2018.09.01 20:40 字数 2879 阅读 104评论 0喜欢 1 沉下心来 ...

  2. 洛谷p1006 传纸条 三维解法

    原题目如下 原地址https://www.luogu.com.cn/problem/P1006 题目描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做 ...

  3. 吴裕雄--天生自然python Google深度学习框架:图像识别与卷积神经网络

  4. SaltSatck常用指令一

    1.查看版本号: salt --version [root@master ~]# salt --version salt (Fluorine) [root@master ~]# 2.显示依赖关系及版本 ...

  5. java gc 总结

    垃圾查找 1.基于计数器 对象有引用计数,计数为0的,可以被收集 2.基于有向图 从gc root(栈.静态变量.JNI 变量)遍历,能访问的对象,不用被收集,其他的,可以被收集 因为计数器不能解决 ...

  6. VMware vSphere ESXi 和 vCenter Server 5.1 文档地址

    VMware vSphere ESXi 和 vCenter Server 5.1 文档地址       https://pubs.vmware.com/vsphere-51/index.jsp?top ...

  7. 二十四、SSH介绍

    1.ssh介绍: SSH先对联机数据包通过加密技术进行加密处理,加密后在进行数据传输,确保了传递的数据安全.(运维的一大重视点就是要对安全敏感) 在当前的生产环境运维工作中,绝大多数企业都是SSH协议 ...

  8. WMS出库单重复

    发货通知单?WMS备货单选项勾选 不自动复制?新增?

  9. ASA5505升级license

    1.准备工作 首先先看下目前的license # show activation-key Serial Number: JMX1J364741 Running Permanent Activation ...

  10. 算法笔记4.3递归 问题 B: 数列

    题目描述 编写一个求斐波那契数列的递归函数,输入n 值,使用该递归函数,输出如下图形(参见样例). 输入 输入第一行为样例数m,接下来有m行每行一个整数n,n不超过10. 输出 对应每个样例输出要求的 ...