https://mp.weixin.qq.com/s/-pjCLzzincJz0Z66orx8kg
介绍Broadcast的实现。

1. 基本介绍
TLBroadcast实现的是TL-C等级,支持Transfer操作。主要功能是根据输入的请求类型,广播Probe请求进行权限调整,维持缓存一致性(cache coherency)。
2. Tracker
跟踪为了实现缓存一致性而发出的Probe请求的过程。Tracker根据配置参数bufferless,决定是否保存上游节点下发的请求。
3. TLBroadcast
1) 类参数
a. lineBytes
每个Tracker支持的字节数:

限制条件:
i. 值大于0;
i. 值为2的幂;
i. 值大于数据带宽(beatBytes);

b. numTrackers
支持的Tracker的数量。
c. bufferless
是否保存上游节点下发的请求。
2) node
用于与其他diplomacy节点连接并协商传递参数的diplomacy节点。
A. clientFn
用于向下传递参数的方法:

因为要对source增加两位进行编码,所以这里乘以4。
B. managerFn
用于向上传递参数的方法:

a. endSinkId = numTrackers;
b. 限定下游节点不能支持Acquire操作,即下游节点不支持TL-C:

c. 只处理区域类型为UNCACHED的manager,把UNCACHED转换为TRACKED。即我们看到的下游节点的区间类型为UNCACHED,而上游节点看到的我们支持的这个区间的类型为TRACKED。因为我们做了TRACK的工作。

所谓UNCACHED区间类型,是指当前节点对该区间的支持不包含CACHE,但不妨碍上游节点为之添加缓存的功能。

这里not cached yet,不是指时间上,而是指结构上。
就时间上而言,一个区域是否缓存是一个动态的过程。而这里区域类型是一个静态的属性,不会随时间的变化而变化。即某个节点对某个区域的支持是否可缓存,不随时间的变化而变化。
但可以随结构的变化而变化。节点不是鼓励的节点,而是DAG中的一个节点。DAG中某个节点对某个区域的支持是不缓存,不代表其上游的节点不可以代为缓存。
所以可以理解几个区域类型的意义:

UNCACHED:当前节点没为之缓存,上游节点可为之缓存;
TRACKED:当前节点为下游节点增加了缓存的支持;
UNCACHEABLE:不可缓存,当前节点不缓存,上游节点也不可以缓存,因为内容会变(比如IO编址区间)。这样的区间每次使用都要重新读取;
CACHED:当前节点已为之缓存;
d. 支持的传输大小变化:

e. 响应不必FIFO顺序返回,也就是说先来的请求的响应可以后面才返回;
3) module
A. node.in & node.out

因为所有节点组成的是DAG,所以只有上游节点可以缓存下游节点的数据,兄弟节点不能缓存。所以当上游节点发起的请求触发权限相关的Probe操作时,只需要向上游节点(通过node.in)发出Probe请求即可。
B. clients/managers
取出这一条线上的clients/managers:

C. lineShift
用于处理地址,因为缓存的数据大小为lineBytes,所以地址相应的低位可以忽略:

D. caches
取出缓存数据的clients:

E. 创建Trackers
创建numTrackers个Trackers:

其中:log2Up(caches.size + 1)为记录probe个数所需要的比特数。
F. 处理channel e
channel e只有1种message,即GrantAck:

a. 一直接收channel e的输出;
b. 选择与in.e.bits.sink对应的tracker,输入e_last的值;
G. in.a:上游节点的请求
a. 请求类型

左侧列出了各种请求类型。
b. Acquire

Acquire操作请求提升权限:

i. NtoB:从None提升到Branch,Branch节点具有只读权限,所以向其他缓存了数据的节点发送Probe请求,把权限设定为Branch,即只读权限,超过的需要降权。

i. NtoT:从None提升到Trunk,Trunk节点可读,Trunk节点具有读权限,并且缓存了可能是脏数据的数据。所以如果一个节点要提升至Trunk节点,需要向其他节点发送Probe请求,把权限设定为None,以促使其把数据回写。

i. BtoT:同NtoT。
c. 其他操作

i. PutFullData:上游节点发来写数据请求,需要其他cache节点回写数据,若有需要之后再重新缓存。所以Probe其他cache节点的权限至None;
i. PutPartialData:同PutFullData;
i. ArithmeticData:需要先读、计算、再回写,同PutFullData;
i. LogicalData:同PutFullData;
i. Get:为了读取到最新数据,需要回写脏数据,如果没有脏数据则直接从缓存中返回即可。即如果是Trunk权限,则需要降权为Branch。如果是Branch权限,则无需再降权。
i. Hint:预读取和预写入与读取和写入同理;
d. selectTracker

其中:
i. freeTrackers:各个tracker是否空闲的标志;
i. freeTrack:是否存在空闲的Tracker;
i. matchTrackers:各个tracker跟踪的是否是当前访问的地址的标志;
i. matchTracker:是否有一个tracker跟踪者当前访问的地址;
i. allocTracker:从空闲的tracker中分配一个tracker用于跟踪当前访问的地址;
i. selectTracker:如果有tracker正在跟踪当前访问的地址,则仍然使用这个tracker。否则,使用重新分配的新tracker;
e. trackerReady
trackerReady是各个tracker是否可以接收输入的标志:

f. in.a.ready
是否接收channel a的请求,取决于如下条件:
i. 选中的tracker可以接收:(selectTracker & trackerReady).orR();
i. burst请求的后续beat(!a_first)或者已经全部probe完成;
g. 请求存入tracker

其中:t.probe表示要probe的client的个数。如果没有caches则为0。否则要看请求是否来自于某一个cache节点,如果是则为caches.size - 1,如果不是则为caches.size。

H. in.b
channel b用于向上游节点发送Probe请求:

其中:
i. probe_todo:待probe的cache节点;
i. probe_line:probe的address;
i. probe_perms:param中cap的权限;
i. probe_next:下一个要probe的对象;
i. probe_busy:是否probe完所有要probe的cache节点;
i. probe_target:当前要probe的对象;
i. in.b.fire()时切换下一个probe对象;

I. in.c
a. 消息类型
![]()
i. ProbeAck:我方发出Proe的响应消息,说明某client Probe完成。递减tracker中的Probe计数器。DROP是指收到ProbeAck无需其他动作。
i. ProbeAckData:除了递减计数器之外,还需要把返回的数据回写。即通过out.a发出PutFull消息。DROP是指无需再有其他动作。
i. ReleaseData:不同于ProbeAckData的地方在于,ReleaseData是上游节点发起,是一个请求消息,需要我方回复。回复的动作需要在PutFull完成之后,把PutFull的响应消息即AccessAck转换(transform)成为ReleaseAck返回给上游节点。
i. Release:直接使用in.d回复ReleaseAck即可。
b. 甄别消息类型

c. 消息与tracker的关系

d. releaseack
针对Release消息的回复ReleaseAck:

i. valid:channel c发送release时回复;
i. 使用in.c.bits组装releaseack;
通过in.d返回:

e. putfull
针对ProbeAckData和ReleaseData消息,需要把Data回写:

其中:
i. put_what:标识PutFull是为了ReleaseData还是为了ProbeAckData,如果是ReleaseData,就标识为TRANSFORM_B,如果是ProbeAckData就标识为DROP。
i. put_who:如果是ReleaseData消息,那么source在in.c.bits.source;如果是ProbeAckData,这里source使用的是tracker中存着的in.a中取的source,与ProbeAckData中的Source即Probe消息的目标不一样,后续并没有使用这个source,用意不做分析。
i. Cat(put_what, put_who):修改Put操作的source,以方便响应消息AccessAck返回时处理;因为put_what有四种可能(TRANS_B/TRANS_T/DROP/PASS)占两位,所以下游节点看到的client的endSourceId相比Broadcast节点看到的上游节点cliet的endSourceId,扩大了四倍。这就是diplomacy node的clientFn中cp.endSourceId乘以4的原因:

通过out.a发出:

f. probenack
如果in.c返回ProbeAck消息,则告诉tracker递减probe计数器:

J. out.d/in.d
如何根据out.d生成in.d要回复的消息。channel d支持的消息类型如下:

a. 取出编码在source中的信息:

b. 判断是否ProbeAckData消息衍生成出的Put消息的响应消息AccessAck:

有个assert限定:

如果是这个AccessAck消息,就允许发送:

然而这个消息不会被传往in.d:

c. d_hasData:是否包含数据:

d. d_normal:使用out.d生成的消息,发往in.d
a) 使用in.d克隆的Wire:

这意味着d_normal中各个域的位宽与in.d一致,而不是out.d。
实际上,out.d的source域比in.d的source域多两位,所以把out.d连接到d_normal时,会把这两位丢掉:

b) TRANSFORM
TRANSFORM的信息从out.d.bits.source中取出,即do_what。
这个信息从两处传入:
i. put_what:

- ReleaseData需要把Put的响应消息AccessAck变换为ReleaseAck;
- ProbeAckData需要把Put的响应消息AccessAck丢弃;
i. in.a的Acquire消息:

in.a发出的Acquire消息,会被转换为Get消息,从下游节点请求数据,然后返回给上游节点。
c) do_what(1):TRANSFORM_B/TRANSFORM_T

如果do_what(1)为真,那么编码在source中的信息是TRANSFORM_B/TRANSFORM_T:

进而表明tracker中跟踪的是一个Acquire消息或ReleaseData消息。
如果d_hasData为真,out.d返回的是Acquire变换成的Get消息的响应消息AccessAckData,应该被转换为GrantData消息返回;
如果d_hasData为假,out.d返回的是ReleaseData变换成的Put消息的响应消息AccessAck,应该被转换为ReleaseAck消息返回;
GrantData消息的param:

ReleaseAck消息的param为0:

d) probedack
标志着ProbeAckData处理完成:

如果ProbeAckData衍生的Put消息返回,则ProbeAckData消息处理完成。
e) d_last
响应消息是否发送完成:

d_normal.fire() && d_last代表d_normal发送完成。
d_response指除ProbeAckData的AccessAck消息和ReleaseData的ReleaseAck消息之外的其他消息。
为什么要排除这两个消息?
因为这两个消息的响应消息虽然都是从channel d返回,但他们都是从channel c发送的请求消息。而tracker跟踪的是channel a发出的请求消息。
4. TLBroadcastTracker

1) 参数
a. id:tracker的编号;
b. lineBytes:tracker缓存的字节数;
c. probeCountBites:需要probe的cache节点计数所需的比特位数;
d. bufferless:是否保存上游节点下发的请求;
2) io

其中:
a. in_a_first:是否in_a的第一个beat;
b. in_a:保存的channel a的输入;
c. out_a:向channel d输出的信号;
d. probe:要probe的cache节点的数目;
e. probenack:处理完成一个ProbeAck消息;
f. probedack:处理完成一个ProbeAckData消息;
g. d_last:是否channel d的最后一个beat;
h. e_last:是否channel e的最后一个beat;
i. source:提取in_a中的source域,输出用于比对;
j. line:提取in_a中的address域,处理后输出用于比对;
k. idle:表示该tracker是否空闲;
l. need_d:是否需要channel d;
3) 临时变量

其中:
a. idle = got_e && sent_d:表示已经完成全部消息交互:channel d已经发送完成,并收到了channel e的消息。
b. count:probe请求的计数器。
4) 存入channel a的请求消息

a. sent_d:假,刚收到in.a的消息,还没有返回响应消息;
b. got_e:只有Acquire/Grant/GrantAck交互需要用到channel e置为假,其他用不到的置为真。
c. count:值等于io.probe;
5) sent_d && need_d
当channel d的最后一个beat发出后,sent_d置为真:

channel d的响应消息已发出,则不再需要channel d:

6) e_last && got_e
当channel e的最后一个beat(实际上channel e有且只有一个beat)发出后,got_e置为真:

7) line
根据存的数据大小,地址的低若干位没有意义可以移除:

8) probe计数

a. 处理完一个ProbeAck减1;
b. 处理完一个ProbeAckData减1;
c. 同时处理完则减2;
9) probe_done:标志着probe已经完成:

10) Queue
创建一个队列用于输入、存储、输出数据:

11) 输入规则:

12) 输出规则:

其中:
a. Acquire消息被转换为Get消息,其余透传;
b. source进行编码,Acquire消息对应的source编入transform信息,其他的透传(PASS=0b00);
out_a输出到out.a:

5. Broadcast主动发出的消息
无。
6. Broadcast被动发出的消息
1) 向上游发出Probe请求消息;
2) 向上游直接回复ReleaseAck消息;
3) 向上游回复transform后的ReleaseAck消息;
4) 向下游发出transform后的Get消息;
5) 向下游发出transform后的Put消息;
7. Broadcast透传的消息
channel a支持的消息如下:

除Acquire需要transform外,其余的都会透传。
- Rocket - tilelink - RegisterRouter
https://mp.weixin.qq.com/s/DaJhf7hEoWsEi_AjwSrOfA 简单介绍RegisterRouter的实现. 1. 基本介绍 实现挂在Tile ...
- Rocket - tilelink - Nodes
https://mp.weixin.qq.com/s/KJ8pVH76rdxPOZ1vE3QlKA 简单介绍tilelink对Diplomacy Nodes的实现. 1. TLImp ...
- Rocket - tilelink - AsyncCrossing
https://mp.weixin.qq.com/s/v8plWCBD8vZkxykjJe4TCg 介绍AsyncCrossing的实现,主要介绍如何实现diplomacy Node和LazyMo ...
- Rocket - tilelink - mask
https://mp.weixin.qq.com/s/Gqv09RIgSSg5VKe-wb4aGg 讨论tilelink中使用MaskGen生成mask的用法. 1. tilelink中的ma ...
- Rocket - tilelink - Parameters
https://mp.weixin.qq.com/s/1I6DcONr0Mg7xiX8F1C7SQ 简单介绍TileLink相关的参数实现(具体问题暂时不展开,后续用到时再做分析). ...
- Rocket - tilelink - Bundles
https://mp.weixin.qq.com/s/jrqBg2AIpQogBrpwNXjmwg 简单介绍Bundles文件中对TileLink规范(1.7.1)的定义. 参考链接:https: ...
- Rocket - tilelink - TLBusWrapper.to
https://mp.weixin.qq.com/s/jSnhBzU5_ayQCg5fWAcx-g 简单介绍TLBusWrapper.to()的实现.主要介绍确定this{...}对应代码的过程. 1 ...
- Rocket - tilelink - BusWrapper
https://mp.weixin.qq.com/s/03BvgTNQtD75Guco6gUGQg 简单介绍BusWrapper的实现. 1. HasTLBusParams 定义SoC的挂 ...
- Rocket - tilelink - Xbar
https://mp.weixin.qq.com/s/UXFHYEQaYotWNEhshro68Q 简单介绍Xbar的实现. 1. 基本介绍 用于为Xbar的输入和输出连接生成内 ...
随机推荐
- Eugene and an array(边界麻烦的模拟)
一道看似小学生的题,搞了我几个小时...... 首先思路就有两种: \(Ⅰ.找和为0的bad子串,再用n*(n+1)/2-bad子串得到答案\) \(Ⅱ.找和不为0的good子串\) 如果你选择找ba ...
- php报错:strip_tags() expects parameter 1 to be string, array given
囧....... 这个表示参数需要字符串,而你传入了数组,所以出错了~ 检查下函数或者方法是否正确,还有参数
- 王颖奇 20171010129《面向对象程序设计(java)》第九周学习总结
实验九 异常.断言与日志 实验时间 2018-10-25 1.实验目的与要求 (1) 掌握java异常处理技术: (2) 了解断言的用法: (3) 了解日志的用途: (4) 掌握程序基础调试技巧: 2 ...
- HTTP接口测试
HTTP接口测试 1.1 get接口 请求URL http://api.nnzhp.cn/api/user/stu_info 请求方式 get 请求参数 参数名 必选 类型 说明 stu_name 是 ...
- 关于oracle怎么看清楚字段的一些实践
在oracle存储过程或者平时编码中会有很多时候对不上字段,这时候在字段逗号后面可以主动加上--数字. 还有的是应该注意尽量让每个字段都占有一行的空间.下面部分截图说明
- Print输出颜色字体方法
书写格式: 开头部分:\033[显示方式;前景色;背景色m + 结尾部分:\033[0m 注意:开头部分的三个参数:显示方式,前景色,背景色是可选参数,可以只写其中的某一个:另外由于 ...
- 手机网页,div内滚动条,以及div内部滚动条拉到底部之后触发事件
var gao = document.documentElement.clientHeight; var headHeight = parseInt($('.yhead').css('height') ...
- nginx default server
配合server_name _ 可以匹配所有的域名,在设置default server 可以轻松屏蔽一些非域名访问的请求. 配置如下 server { listen 80 default_server ...
- Tensorflow从0到1(一)之如何安装Tensorflow(Windows和Linux两种版本)
现在越来越多的人工智能和机器学习以及深度学习,强化学习出现了,然后自己也对这个产生了点兴趣,特别的进行了一点点学习,就通过这篇文章来简单介绍一下,关于如何搭建Tensorflow以及如何进行使用.建议 ...
- 微信小程序-视频弹幕的项目
1.视频播放器 2.选择弹幕颜色 3.弹幕来了... 一般微信小程序需要配置.wxml.wxss.js.json文件,所有接下来也是要配置这几个文件,请看下图: 第一: index.wxml < ...