四、ARM各种Memory类型理解

读书笔记,源自谷公子 https://blog.csdn.net/W1Z1Q/article/details/104358385

在看ARM的各个文档时,经常出现很多memory属性相关的词汇,比如Device、Cacheable、Shareable之类,基于这段时间的学习理解和项目实践,把个人的一些理解记录下,仅供参考,有不当之处还望大家指正。
我们以CHI issueC P110 表2-12为例,介绍Device、Allocate、Cacheable、EWA(Bufferable)、Order以及SnpAttr如何影响ARM的memory类型。
在这里插入图片描述

1. MemAttr、Order和SnpAttr等属性分析

从MemAttr那一列的右边分析:
EWA
EWA和Bufferable是一个意思的,EWA指示的是一笔写请求的完成响应是否可以从中间节点返回。EWA=1,允许从中间节点返回;EWA=0,只能从写请求要到达的最终节点返回。

Cacheable
Cacheable指示一笔请求是否需要执行cache lookup,即查找cache内容。Cacheable=1,先进行cache查找,如果没有找到再去访问最终节点;Cacheable=0,必须访问最终节点。通常EWA=0的话,Cacheable肯定等于0,即不能提前返回响应的,那肯定也不能只查询cache就了事的。

Allocate
Allocate是是否需要cache分配的提示信号,也只是指示作用,具体要不要分配看情况。Allocate=1,为了性能考虑,推荐将数据分配到cache中;Allocate=0,为了性能考虑,推荐不要将数据分配到cache中。通常Cacheable=0的话,那Allocate肯定等于0的,因为不进行查找cache的话,也就没有必要分配cache给数据的。

Device
Device指示memory类型是Device,还是Normal,是决定访问memory类型的关键信号。Device=1,为Device memory type,该memory类型是由连带效应(side-effectts)的,即对一个地址的数据的操作可能会影响到另一个地址中的数据值。那些地址区间没有连带效应的也允许使用Device memory type,也就是说对一个地址的操作不影响到另一个地址的数据也可以用做Device空间,Device空间要求比较苛刻点,Device空间的数据是不允许被cache缓存,否则会导致系统功能紊乱,因此Cacheable和Allocate都为0,也就没有必要支持Snoop(SnpAttr必须等于0);Device=0,为Normal memory type,该memory类型是不具有连带效应的,即地址之间的操作互不干扰,Normal空间的数据可以被cache缓存,因此也支持Snoop(SnpAttr可以等于0,也可以等于1)。

Order
Order用于多笔访问操作之间的保序需求,Device和Normal地址空间都有保序需求,Order=0,不需要保序;Order!=0,需要保序。

SnpAttr
表示该笔操作是否需要snoop;SnpAttr=1,需要snoop;SnpAttr=0,不需要snoop。操作是否需要snoop跟本身的操作类型也有关系的。

2. ARM Memory Type分析

现在我们来看下上表中ARM Memory Type那一栏,以Memory类型讨论,分为Device type memory和Normal type memory。

2.1 Device Type Memory

Device memory也就是Device=1的地址区间。
Reordering, R and nR: The Reordering and non-Reordering attributes;
Early Write Acknowledgement, E and nE:The Early Write Acknowledgement and no Early Write Acknowl-edgement attributes;
其实还有G和nG属性(Gathering and non-Gathering attributes,即多笔命令能否合并成一条命令),不过在CHI文档里没有体现,这里就暂时不说了,以上组合起来可以得到如下各种Device属性。

1、Device nRnE:
顾名思义就是这种地址需要保序,且不能支持EWA,即从中间节点返回写响应。
2、Device nRE:
这种地址需要保序,但可以支持EWA,即从POS或POC点返回写响应就可以的。
3、Device RE:
这种地址不需要保序,支持EWA。
加上nG和G属性,上述各种可以组成如下各种Device类型及保序强度。
在这里插入图片描述

2.2 Normal Type Memory

Normal memory也就是Device=0的地址区间。Normal memory可以区分如下:
1、Non-cacheable Non-bufferable:
Non-cacheable Non-bufferable其实是AXI的memory类型,不是ARM的memory类型。该类型可以看出是不能cache缓存和allocate数据的,并且写响应要从最终节点返回。

2、Non-cacheable Bufferable:
该种类型是不能被cache缓存和allocate数据的,但写响应可以从中间节点(如POC或POS)返回的。

3、Non-snoopable WriteBack No-allocate:
这种类型不是Snoopable属性,但支持cache缓存数据的,不支持allocate,在写数据发生cache miss下,直接将数据写到下游去,不需要allocate到本级cache。

4、Non-snoopable WriteBack Allocate:
这种类型不是Snoopable属性,但支持cache缓存数据的,且也允许allocate数据,在写数据发生cache miss下,需要将下游数据读到本级cache中,然后再往cache中写入该数据。

5、Snoopable WriteBack No-allocate:
这种类型和第三种一样,只不过多了支持Snoopable。

6、Snoopable WriteBack Allocate:
这种类型和第四种一样,只不过多了支持Snoopable。

  1. 其它属性分析
    我们一定还经常看到Shareability属性,这个属性和其它memory的属性有什么关系呢?表1为ACE协议中的Shareability domains和其它属性的关系。
    在ACE协议中有四种级别的Shareability domain,如下:

Non-shareable:该domain只包含一个master;
Inner Shareable:该domain包含了几个master;
Outer Shareable:该domain包含了Inner domain和其它master;
System:该domain包含了系统中的所有domain;
其实在ARMv8中只定义了三种Shareability domain,没有System domain,但这也不影响。
表1 AxCACHE and AxDOMAIN signal combinations
在这里插入图片描述
由表1可以看出Device memory总是认为是Shareable的,Device memory只用于System domain,因为Device memory不会被任何cache缓存,所有没必要分配其它domain的。
对于Normal Non-cacheable memory通常也只属于System domain,因为大家都不缓存,也没有必要分配给其它domain的。有些情况例外,需要分配domain的,例如memory地址的数据会被缓存在domain级别的位置,而不是放在下游的Systemcache,那就需要去监听它们。
对于Normal Cacheable memory有WriteBack和Writethrough两种属性,支持三种Shareability domains(不支持System domain),因为该类型的memory会cache数据,所以需要去snoop其它master的。
仔细想想,其实Shareablility只和memory类型和Cacheable属性有关的,与EWA、Allocate、SnpAttr等不相关的。当然Snoopable的请求肯定是属于Inner Shareable domain或Outer Shareable domain的。Non-snoopable请求的话,如果是Device memory type,那么就是System Domain;如果是Normal memory type且是Non-cacheable属性的话,那可能会是四个中的任何一个;如果是Normal memory type且是Cacheable属性的话,那应该是Non-shareable domain的。

  1. 参考文献
    1、《IHI0050C_amba_5_chi_architecture_spec-3》
    2、《DDI0553B_j_armv8m_arm》
    3、《AMBA® AXI™ and ACE™ Protocol》
  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`osThreadAttr_t` 是一个结构体类型,用于描述嵌入式系统中的线程属性。在使用嵌入式系统的操作系统时,我们通常需要创建多个任务或线程来处理不同的任务,每个线程都需要有特定的属性和优先级等信息。`osThreadAttr_t` 结构体就是用来描述这些属性的。 `osThreadAttr_t` 结构体包含以下成员: - `name`: 线程名称,类型为 `const char *`。 - `attr_bits`: 线程属性,类型为 `uint32_t`。 - `cb_mem`: 线程控制块内存指针,类型为 `void *`。 - `cb_size`: 线程控制块内存大小,类型为 `uint32_t`。 - `stack_mem`: 线程栈内存指针,类型为 `void *`。 - `stack_size`: 线程栈内存大小,类型为 `uint32_t`。 - `priority`: 线程优先级,类型为 `osPriority_t`。 - `tz_module`: 安全模块指针,类型为 `osThreadAttr_t::tz_module_t *`。 - `reserved`: 保留字段,类型为 `uint32_t`。 通过设置 `osThreadAttr_t` 结构体的成员变量,我们可以指定线程的名称、属性、控制块内存、栈内存、优先级等信息。例如,以下代码片段演示了如何使用 `osThreadAttr_t` 结构体创建一个新的线程: ```c osThreadId_t tid_mythread; osThreadAttr_t mythread_attr = { .name = "mythread", .priority = osPriorityNormal, .stack_size = 1024 }; tid_mythread = osThreadNew(mythread, NULL, &mythread_attr); ``` 在这个例子中,我们使用 `osThreadAttr_t` 结构体定义了一个名为 `mythread` 的线程,该线程的优先级为 `osPriorityNormal`,栈大小为 1024 字节。然后,我们使用 `osThreadNew` 函数创建了一个新的线程,并将 `mythread` 函数作为其入口点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值