https://mp.weixin.qq.com/s/kNQrhlf33AErK7IzalnUDw

 
简单介绍Fragmenter的实现。
 
 
1. 基本介绍
 
用于把上游节点地址空间范围比较大的访问请求,拆分成下游支持的多个地址空间范围较小的访问请求。
 
1) 类参数
 
a. minSize:向下游节点发起的最小的访问大小;
b. maxSize:上游节点可以下发的最大的访问大小;
c. alwaysMin:是否把所有上游节点的请求,都拆分成minSize大小的访问请求:
- 如果为真:把所有上游节点的请求,都拆分成minSize大小的访问请求;
- 如果为假:根据下游节点的能力大小来拆分上游节点的访问请求;
d. earlyAck:针对一个Put burst,是在第一个beat回复响应消息,还是再最后一个beat回复响应消息;
e. holdFirstDeny:针对一个Get burst,在出现denied时就一直保持,直到整个burst结束;
 
2) 参数限制
 
要求minSize/maxSize都是2的幂,并且minSize小于等于maxSize:
 
3) minSize/maxSize
 
a. 实例
其中:ramBeatBytes是RAM支持的访问大小的物理能力。而maxSize是Fragmenter能拆分的最大访问请求的大小。
 
b. minSize
 
minSize实际上更多的指代下游节点的物理能力,比如说总线宽度。
 
c. 实际访问大小
 
但上游节点的访问请求,可能会小于minSize。此时不需要拆分,直接以原请求大小透传即可。
比如:minSize = ramBeatBytes = 4,而Get请求的大小为2,即读取两个字节。
 
2. diplomacy node
 
1) 添加的编码位
 
a. fragmentBits:分片编号所需要占用的比特数;
b. fullBits:是否需要earlyAck所需要占用的比特数,All和None都不需要这个比特:
c. toggleBits:用于区分两个连续的burst请求的比特位;
d. addedBits:上面加在一起就是需要添加的全部比特位的数目;
 
2) expandTransfer
 
扩展Transfer x的大小:
a. 如果x为none,则不进行扩展;
b. 把x.max扩展为maxSize,即Fragmenter支持的最大传输大小;
c. x.min不变;
 
3) shrinkTransfer
 
缩小transfer x的大小:
A. 如果不要求把所有的请求都拆分成minSize大小,则不需要缩小x;
B. 如果要求把所有的请求都拆分成minSize大小:
a. 如果x.min大于minSize,那么该传输不支持;
b. 如果x.min小于等于minSize,则把x.max限定在不大于minSize;
 
总结:缩小的意思是把传输大小的最大值限定在minSize以下。
 
4) mapManager
 
放大或缩小manager支持的各项操作的传输大小:
a. 对Atomic操作的大小进行缩小;
b. 对Get/Put/Hint操作的大小进行放大;
 
根据注释:
a. Arithmetic操作透传:数学运算需要提供操作数,而操作数不能分片,所以只能透传;
b. Get/Put/Hint/Logical操作可以分片:相较之下,位运算的结果只与当前位相关,所以可以分片进行运算;
c. 不支持Acquire操作;
 
Arithmetic操作要把传输大小缩小可以理解,因为其不支持分片。Logical操作呢?可以把传输大小放大吗?我认为是可以的,所以这里针对supportsLogical,应该是expandTransfer,而不是shrinkTransfer。
 
但考虑到Logical操作是原子操作,分片后的多个Logical请求之间,是否会被插入其他的请求消息呢?有可能,为了避免这种情况,还是shrinkTransfer较为妥当,毕竟Fragmenter不处理这种同步问题。
 
5) diplomacy node
 
A. clientFn:把Fragmenter看到的上游节点的参数,转换为下游节点看到的Fragmenter的参数。
 
这里进行了如下调整:
a. name:名称为TLFragmenter;
b. sourceId:需要把分片号等信息编码进sourceId中,所以其范围扩大了;
c. requestFifo:需要下游节点实现按请求顺序返回响应信息;
 
B. managerFn:把Fragmenter看到的下游节点的参数,转换为上游节点看到的Fragmenter的参数。
 
这里把下游节点各manager支持的传输能力大小进行了转换。
 
3. lazy module
 
1) 成对的输入边和输出边
 
 
2) 如果不需要分片,则直连即可:
 
 
3) 限定条件
 
a. 所有manager的fifoId都相同,因为需要manager按顺序返回响应消息:
 
b. manager不支持cache:
 
 
c. minSize >= beatBytes
 
这里的beatBytes是真正的总线宽度,虽然minSize经常被设置为与beatBytes相同,但也可以比其大。如果minSize = 2 * beatBytes,那么Fragmenter拆分后的请求基本上都是包含2个beat的burst。
 
d. 上下游节点都不支持Cache:
 
 
e. 如果可能拒绝Get请求,那么需要保持deny信号:
 
 
f. 如果可能拒绝Put请求,那么不能提早对其进行响应:
 
4) beat数目
 
beatBytes是Fragmenter与下游节点之间的总线宽度,maxSize是上游节点向Fragmenter发起的请求的最大传输大小。
 
两者的商是最大传输大小的请求,最终对应的针对下游节点的请求的beat数。
 
对比一下:
maxSize/minSize:最大传输大小的请求,转化为针对下游节点的请求的数目。
如果minSize == beatBytes,那么这个请求的数目即是beat的数目。
如果minSize > beatBytes,那么这个请求的数目是指burst请求的数目。每个burst请求中包含多少个beat,则由minSize/beatBytes的值决定。
 
即:
maxSize/minSize = 分片的数目 = (burst)请求的数目
maxSize/beatBytes = 所有请求中beat的数目之和
 
5) maxDownSize
 
向下游发送请求时能使用的最大传输大小:
 
6) 响应相关的变量
 
这里不再详细介绍。
 
7) 响应处理
 
A. out.d.fire()
 
记录如下信息:
a. ackNum:如果是第一个响应消息,那么响应编号(ackNum)= dFirst_AckNum,后面逐个递减ack_Decrement;
b. 记录dOrig;
c. 从source中取出编码进去的toggle位;
 
B. 计算是否要EarlyAck:
 
其中,如果earlyAck的类型为只针对PutFull,那么则从source中取出相应的编码位;
 
C. drop
 
是否丢弃这一个响应消息:
a. 如果有数据,则不能drop;
b. 如果要EarlyAck,那么不是第一个的响应消息,都应该丢弃;
c. 如果非EarlyAck,那么不是最后一个的响应消息,都应该丢弃;
 
D. 把out.d导向in.d
 
 
E. 处理针对Put的denied信号:
 
若出现denied信号,则保持住:
需要注意的是:这里的保持denied信号,不是指在单个burst请求的多个beat之间保持。而是指在多个分片请求的响应消息之间保持,每个分片请求都有可能是burst请求。
 
F. 处理针对Get的denied信号:
 
 
8) 请求分片
 
A. 计算每个manager针对每种操作的最大传输能力
 
 
并转换为lg值:
这里如果manager支持的最大能力为0,也就是manager不支持这种操作,使用lgMinSize代替。注释里的意思是:我们寄希望于client不对某个manager发出他不支持的request,所以这里无论是使用lgMinSize代替或者其他任何值,都没有意义。
 
根据请求访问的地址,确定地址所属的manager,进而确定支持的最大传输大小:
 
B. 确定分片的最大大小:
 
 
C. 请求分片相关的变量
 
这里不做详细介绍。
 
D. 使用repeater重复in.a的请求
 
a. 从in.a输入,输出到in_a:
 
b. 何时重复in.a?
 
需要同时满足一下条件:
- 请求消息中没有数据:如果有数据就透传;
- 分片编号不为0,为0代表最后一个分片;
 
如果没有数据的请求,即Get/Hint请求消息,则把in.a的数据保存到最后一个分片发出为止。
 
Arithmetic/Logical都带有数据,但是他们的传输大小是被缩小了的,所以下游节点可以支持透传。如果是Put请求呢?其传输大小是被放大了的。这个问题下面单独研究。
 
E. 组装各个编码位:
 
 
F. 两点优化
 
a. 直连in.a.bits.data到out.a.bits.data,不需要repeater中转
 
这个问题会在下面单独研究。
 
b. 如果repeater.io.full为真,则out.a.bits.mask应当为全1
 
意思是说,如果当前正在发送一个分片,那么这个分片的大小包含下游节点支持的beatBytes中的所有字节。
 
9) 不支持Cache
 
 
4. Put请求
 
首先,下游节点支持的Put请求的大小,被Fragmenter放大了。
其次,Put请求不经过repeater,而直接传递给out.a。
 
那么问题来了:
a. Put请求是否分片?如果分片,原始请求在哪里缓存或者说阻塞以等待所有分片请求发完?
b. 如果in.a.bits.data直连out.a.bits.data会不会丢失数据?
 
进而,针对Get请求:
c. out.d.bits.data直连in.d.bits.data,会不会丢失数据?
 
直接说结论:这三个问题,实际上都牵涉到数据的传输。数据的传输是由beatBytes也就是总线位宽限定的(而不是请求中的size域)。
 
那么Fragmenter改变了上游节点和下游节点的总线宽度了吗?答案是没有。
 
跟一下代码:
 
a. channel a的data域的宽度由参数params.dataBits决定:
 
b. params在创建TLBundle时传入:
 
c. 创建输入边和输出边的TLBundle,分别使用输入边和输出边中的bundle参数:
 
d. TLBundleParameters中的dataBits取决于manager的beatBytes:
 
e. 这个manager是指TLManagerPortParameters:
 
也就是说:
a. Fragmenter与下游节点之间数据总线的宽度,由下游节点的beatBytes参数决定;
b. Fragmenter与上游节点之间数据总线的宽度,由Fragmenter的beatBytes参数决定;
 
Fragmenter的beatBytes参数由下游节点使用managerFn转换而来:
 
这个managerFn只改变了支持的能力的大小,并没有改变beatBytes的大小:
也就是说,改变了可以填到channel a的size域的值的大小,并没有改变数据总线的宽度。
 
这下就好理解了:
a. Put请求,无论size多大,数据终究需要受数据总线的限制,一个beat一个beat的传输。在这种情况下Fragmenter逐个beat透传没有问题。
b. Get请求,无论size多大,返回的数据也终究需要收数据总线的限制,一个beat一个beat的传输。
 

Rocket - tilelink - Fragmenter的更多相关文章

  1. Rocket - tilelink - RegisterRouter

    https://mp.weixin.qq.com/s/DaJhf7hEoWsEi_AjwSrOfA   简单介绍RegisterRouter的实现.   ​​   1. 基本介绍   实现挂在Tile ...

  2. Rocket - tilelink - HintHandler

    https://mp.weixin.qq.com/s/MHW_aBSL72YNee9bVWWeaw   简单介绍HintHandler的实现.   ​​   1. 基本功能   实现Hint请求的处理 ...

  3. Rocket - tilelink - Nodes

    https://mp.weixin.qq.com/s/KJ8pVH76rdxPOZ1vE3QlKA   简单介绍tilelink对Diplomacy Nodes的实现.   ​​   1. TLImp ...

  4. Rocket - tilelink - AsyncCrossing

    https://mp.weixin.qq.com/s/v8plWCBD8vZkxykjJe4TCg   介绍AsyncCrossing的实现,主要介绍如何实现diplomacy Node和LazyMo ...

  5. Rocket - tilelink - mask

    https://mp.weixin.qq.com/s/Gqv09RIgSSg5VKe-wb4aGg   讨论tilelink中使用MaskGen生成mask的用法.   1. tilelink中的ma ...

  6. Rocket - tilelink - Parameters

    https://mp.weixin.qq.com/s/1I6DcONr0Mg7xiX8F1C7SQ   简单介绍TileLink相关的参数实现(具体问题暂时不展开,后续用到时再做分析).   ​​   ...

  7. Rocket - tilelink - Bundles

    https://mp.weixin.qq.com/s/jrqBg2AIpQogBrpwNXjmwg   简单介绍Bundles文件中对TileLink规范(1.7.1)的定义. 参考链接:https: ...

  8. Rocket - tilelink - TLBusWrapper.to

    https://mp.weixin.qq.com/s/jSnhBzU5_ayQCg5fWAcx-g 简单介绍TLBusWrapper.to()的实现.主要介绍确定this{...}对应代码的过程. 1 ...

  9. Rocket - tilelink - BusWrapper

    https://mp.weixin.qq.com/s/03BvgTNQtD75Guco6gUGQg   简单介绍BusWrapper的实现.   1. HasTLBusParams   定义SoC的挂 ...

随机推荐

  1. 聊聊算法——BFS和DFS

    如果面试字节跳动和腾讯,上来就是先撕算法,阿里就是会突然给你电话,而且不太在意是周末还是深夜, 别问我怎么知道的,想确认的可以亲自去试试.说到算法,直接力扣hard三百题也是可以的,但似乎会比较伤脑, ...

  2. NetCore项目实战篇05---添加Ocelot网关并集成identity server4认证

    今天来给我们的项目增加API网关,使用Ocelot. 它是系统暴露在外部的一个访问入口,这个有点像代理访问的家伙,就像一个公司的门卫承担着寻址.限制进入.安全检查.位置引导.等等功能.同时我们还要在网 ...

  3. LeetCode--Squares of a Sorted Array && Robot Return to Origin (Easy)

    977. Squares of a Sorted Array (Easy)# Given an array of integers A sorted in non-decreasing order, ...

  4. 【带着canvas去流浪(15)】threejs fundamentals翻译系列1-scene graph

    示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址:<大史住在大前端>原创博文目录 华为云社区地址:[你要的前端打怪升级指南] 目录 ...

  5. 错误提示 Table '.***_ecms_news_data_' doesn't exist select keyid,dokey,newstempid,closepl,info

    错误提示:Table '**.***_ecms_news_data_' doesn't exist select keyid,dokey,newstempid,closepl,infotags,wri ...

  6. 《学习笔记》.NET Core API搭建

    1.创建 ASP.NET Core Web程序,记住取消HTTPS配置 2.此时一个简单的.NET Core API 架子搭建好了,细心的人可以发现Properties下面不是CS文件,确是launc ...

  7. (Redis基础教程之六)如何使用Redis中的List

    如何在ubuntu18.04上安装和保护redis 如何连接到Redis数据库 如何管理Redis数据库和Keys 如何在Redis中管理副本和客户端 如何在Redis中管理字符串 如何在Redis中 ...

  8. spark机器学习从0到1聚类算法 (十)

      一.概念 1.1.定义 按照某一个特定的标准(比如距离),把一个数据集分割成不同的类或簇,使得同一个簇内的数据对象的相似性尽可能大,同时不再同一个簇内的数据对象的差异性也尽可能的大. 聚类属于典型 ...

  9. Django之内置分页器(paginator)

    django分页: from django.shortcutsimportrender from django.core.paginator import Paginator,EmptyPage, P ...

  10. VMware 安装 CentOS 7

    下载并安装 VMware 访问 VMware 官方网站下载 VMware 安装包程序.博主使用的是 12.5.5 版本,下载完之后点击安装包程序进入 VMware 的安装向导,然后点击"下一 ...