AI SoC入门-10数据一致性
原创 thatway1989 那路谈OS与SoC嵌入式软件 2024-11-18 18:28
上一篇文章:AI SoC入门-9访存接口
,讲了各种存储,但是Core访问数据的时候都会遇到数据一致性问题,其已经成功软件中常见的错误根源,特别是异构核之间看到的数据不一致,多核看到的数据不一致等,导致业务逻辑错误,甚至会直接把OS搞崩。
上图可以看到从CPU开始,一级一级的去获取信息,且速度越来越快
,这么多级别中有很多缓存
,就存在一致性问题。
从SoC视角,如上图。数据一致性问题就是在同一时刻,不同的主体看到的数据不一致
,导致逻辑错误。导致数据不一致的主要原因就是各种cache和时序错乱
等。本文对SoC中的这些问题进行一个大致说明。
1. 多核cache一致性
提高CPU的运算能力,一方面提高CPU的频率,另一方面对运算过程中的瓶颈:DDR跟CPU的数据交换耗时进行优化。这时就需要在CPU和DDR之间添加cache,减少CPU的盲等时间。
CPU Cache 通常分为三级缓存:L1 Cache、L2 Cache、L3 Cache,级别越低的离 CPU 核心越近,访问速度也快,但是存储容量相对就会越小。其中,在多核心的 CPU 里,每个核心都有各自的 L1/L2 Cache,而 L3 Cache 是所有核心共享使用的。
1.1 为什么cache不一致
为什么cache不一致?
数据不光是只有读操作,还有写操作,那么如果数据写入 Cache 之后,内存与 Cache 相对应的数据将会不同,这种情况下 Cache 和内存数据都不一致了,于是我们肯定是要把 Cache 中的数据同步到内存里的。
怎么解决两个核的cache不一致?下面介绍几种逻辑:
写直达
cache替换时写回
写直达:写数据时同时更新cache和内存,这种没问题,但是效率不行。
cache替换时写回:
如果当发生写操作时,数据已经在 CPU Cache 里的话,则把数据更新到 CPU Cache 里,同时标记 CPU Cache 里的这个 Cache Block 为脏(Dirty)的,这个脏的标记代表这个时候,我们 CPU Cache 里面的这个 Cache Block 的数据和内存是不一致的,这种情况是不用把数据写到内存里的;
如果当发生写操作时,数据不存在 CPU Cache 里的话,就要检查这个 Cache Block 里的数据有没有被标记为脏的:
a. 如果是脏的话,我们就要把这个 Cache Block 里的数据写回到内存,然后再把当前要写入的数据,先从内存读入到 Cache Block 里,然后再把当前要写入的数据写入到 Cache Block,最后也把它标记为脏的;
b. 如果不是脏的话,把当前要写入的数据先从内存读入到 Cache Block 里,接着将数据写入到这个 Cache Block 里,然后再把这个 Cache Block 标记为脏的就好了
cache替换时写回是有问题的,
只有在 A 号核心中的这个 Cache Block 要被替换的时候,数据才会写入到内存里。
如果这时旁边的 B 号核心尝试从内存读取 i 变量的值,则读到的将会是错误的值,因为刚才 A 号核心更新 i 值还没写入到内存中,内存中的值还依然是 0。这个就是所谓的缓存一致性问题,A 号核心和 B 号核心的缓存,在这个时候是不一致,从而会导致执行结果的错误。
1.2 怎么解决多核Cache不一致
要解决这一问题,就需要一种机制,来同步两个不同核心里面的缓存数据。要实现的这个机制的话,要保证做到下面这 2 点:
某个 CPU 核心里的 Cache 数据更新时,必须要传播到其他核心的 Cache,这个称为写传播;
某个 CPU 核心里对数据的操作顺序,必须在其他核心看起来顺序是一样的,这个称为事务的串行化。简单的说就是对该数据的修改,在每个核心中的操作都要求做到FIFO,不能先后面的修改再前面的修改
于是就有了总线嗅探法:当 A 号 CPU 核心修改了 L1 Cache 中 i 变量的值,通过总线把这个事件广播通知给其他所有的核心,然后每个 CPU 核心都会监听总线上的广播事件,并检查是否有相同的数据在自己的 L1 Cache 里面,如果 B 号 CPU 核心的 L1 Cache 中有该数据,那么也需要把该数据更新到自己的 L1 Cache。这样的总线就是:一致性总线(Coherent Bus),总线在维护cache一致性时,通知相关cache的操作称为snoop。
问题:
CPU 要每时每刻监听总线上的一切活动,不管别的核心的 Cache 是否缓存相同的数据,都需要发出广播事件,会加重总线的负载。
总线嗅探只是保证了某个 CPU 核心的 Cache 更新数据这个事件能被其他 CPU 核心知道,但是并不能保证事务串行化。
有一个协议基于总线嗅探机制实现了事务串行化,也用状态机机制降低了总线带宽压力,这个协议就是 MESI 协议,这个协议就做到了 CPU 缓存一致性。
MESI 协议其实是4个状态单词的开头字母缩写,分别是:
MESI协议的优点:
可以发现当 Cache Line 状态是「已修改」或者「独占」状态时,修改更新其数据不需要发送广播给其他 CPU 核心,这在一定程度上减少了总线带宽压力。
当一个处理器要读取或修改一个缓存行时,MESI协议会根据当前缓存行的状态以及其他处理器的缓存行状态进行协调。例如,如果一个处理器要修改一个处于Shared状态的缓存行时,协议会先将该缓存行的状态设置为Modified,并通过相应的操作将其他处理器的缓存行置为Invalid状态,确保了该缓存行只能被当前处理器访问,从而实现了事务的串行化执行。
1.3 CHI协议
一致性总线通过snoop filter来记录各个cache中的cache line状态,在总线的视角中,cache中每个cache line的状态都在掌握之中。而常用的cache一致性协议包含两种:MESI和MOESI。
MESI协议的不便之处在于:假设CPU A有个一个M态的cache line,而此时CPU B想获取此cache line,那么总线必须通知CPU A将cache line同步到主存中。在这个过程中,总线与主存的交互会消耗较长的时间,如果可以在不将数据同步回主存的情况,将CPU A的数据通过总线发送给CPU B,将会节省时间,提高效率。
MOESI协议就优化了这一不便之处。MOESI协议允许cache之间共享dirty cache line。Dirty是指cache line相对于主存而言已经发生变化,这样就可以节省与主存交互的时间成本,在cache line不需要写回主存之前,一直在cache之间传输。
MOESI相较于MESI多一个O态,O态代表该cache line与主存中的值不同,至少存在于两个cache中,并由该cache在需要的时刻将cache line刷新到主存中。此外MESI和MOESI的S态有所不同,MESI的S态中的cache line与主存保持一致;而MOESI的S态中的cache line不一定与主存保持一致,可能是共享了dirty cache line,但是没有向主存刷新cache line的义务。
目前常采用CHI协议来实现一致性总线上各个组件的通信,该协议就是采用了MOESI来管理相应的cache line 状态。CHI灵活用于设计基于一致性总线的芯片系统,支持构建小型、中型或大型芯片系统。系统包含多个组件,从CPU、GPU、DDR到外设接口,以及互连本身。
为了提高CPU存取数据的速率,通常会在一致性总线上加入一级cache,也就是LLC(Last Level Cache)。LLC是一个独占cache,是低于CPU cache的一级cache,用于缓存从总线中经过的cache line,它增加了芯片上总cache容量。当总线无法从CPU的cache中获取需要的数据时,可以先查询LLC是否含有对应的数据,如果命中,就可以在不访问主存或外设的情况下,为CPU提供数据。这种多级cache结构有效减少了芯片访问主存或外设的次数,为高性能CPU提供了相应数据搬运能力。
CHI协议 CHI 的全称是
Coherent Hub Interface。CHI 协议是 AMBA的第五代协议,可以说是 ACE 协议的进化版,将所有的信息传输采用包(packet)的形式来完成。但是从接口的角度看,CHI 和 ACE,AXI 这些协议完全不一样了
AMBA CHI协议演进如下:
AMBA 1只有ASB和APB协议;
到了AMBA 2引入AHB协议用于高速数据传输;
发展到AMBA 3,为适应高吞吐量传输和调试引入AXI和ATB,而AHB协议缩减为AHB-lite,APB协议增加了PREADY和PSLVERR,ASB由于设计复杂而不再使用;
到了AMBA 4,AXI得到了增强,引入QOS和long burst的支持,根据应用不同可选AXI4,AXI4-lite,AXI4-stream,同时为满足复杂SOC的操作一致性引入ACE和ACE-lite协议,APB和ATB也同时得到增强,比如APB加入了PPROT和PSTRB,另外为改善总线数据传输引入QVN协议;
最近,为了适应更加复杂的高速NOC设计,引入环形总线协议,推出的AMBA CHI协议。
主要有三种类型的节点:请求节点(RN)、home节点(HN)和从节点(SN)。此外还有杂项节点(MN)。
RN生成事务,如读和写请求,这些事务发送到HN。HN负责对请求进行排序,向SN生成事务,并可以发出监听或处理DVM操作。
这些节点类型可以进一步分为以下几类:
RN节点是完全一致的、I/O一致的或具有DVM支持的I/O一致的:
完全一致的请求节点(RN-F),包含一致的缓存并将接受和响应监听;
I/O一致的请求节点(RN-I),没有一致的缓存,不能接受监听
具有DVM支持的I/O一致请求节点(RN-D),具有与RN-I相同的功能,还可以接受DVM消息
home节点可以是完全一致的、非一致的或杂项的:
完全一致的home节点(HN-F)对一致内存的所有请求进行排序并向RN-F发出监听
非一致的home节点(HN-I)对I/O子系统的请求进行排序
杂项节点(MN)处理请求节点发送的DVM事务。这些有时作为HN-D节点实现
适用于普通内存或外设和普通内存的从属节点(SN-F):
SN-F连接到支持一致内存空间的存储器设备。例如,内存控制器将连接到SN-F节点。
适用于外设或普通内存的SN-F连接到I/O外设或非一致内存
参考:https://blog.csdn.net/dajiao_zi/article/details/138194334
1.4 DSU
首先介绍部分核之间按簇进行cache一致性的IP:DSU,同时起提供按簇的L3 cache,之前的文章AI SoC入门-6CPU子系统
中2.2章节中有介绍。
成簇绑定使用:核心功能是控制CPU内核,使其成簇Cluster使用,簇内每一个核心可以单独开关、调整频率/电压,能效表现更佳,甚至制造商是可以将不同核心以不对等的数量放到一个簇内,兼顾成本与性能。
L3缓存的共**享**:DSU能够使用CCI、CCN或是CMN不同总线技术,把CPU与SoC里其它单元(GPU、Modem、内存)高速连接起来;假如它拥有4MB三级缓存,能以动态方式分配缓存给每个核心,比如说Cortex-A75×1+ Cortex-A55×7下,可以将3MB缓存分配给A75核心,剩下7个A55核心共享1MB缓存,甚至可将三级缓存交给GPU等单元使用,灵活性非常高;
冗余设计:设计DynamIQ之时ARM还考虑到冗余需求,比如相比智能手机,汽车对可靠性、冗余度要求高出不少,DynamIQ允许多个簇通过CCIX连接在一起,这样处理器就可以分布于汽车不同位置,当发生交通意外一个簇受损时,DynamIQ技术可以调用出备用处理器,保证汽车正常运转。
DynamIQ™共享单元(DSU)包括
L3内存系**统、控制逻辑和外部接口**,以支持DynamIQ™集群。DynamIQ™集群微体系结构整合了一个或多个核心与 DSU,形成一个按指定配置实现的集群。在宏单元实施过程中,可以选择和配置core。
可见其也使用了ACE或CHI协议,包含MOESI机制。DSU中的SCU(Snoop Control Unit)来维持处理核心和L3缓存之间的一致性。这确保了所有核心对共享数据的访问是同步和一致的,防止数据不一致的问题。
Snoop Control Unit(SCU)是多处理器系统中的一个关键组件,特别是在包含缓存一致性设计中,如对称多处理机群集(
SMP)或片上系统(SoC)中。其主要作用是维护缓存一致性,确保所有处理器核心对共享缓存的内容有统一的视图景,从而保证数据的一致性和正确性。SCU的工作机制通常包括以下方面:
监听(Snooping) : SCU监听所有处理器核心对共享缓存的访问请求,包括读取和写入操作。当一个核心试图修改缓存中的数据时,SCU介入以确保其他核心对该数据的缓存副本不会变得陈旧。
缓存更新: 如果一个核心请求的数据在另一个核心的缓存中是脏(已修改但未回写回主存),SCU会促使持有该脏数据的核心将其写回到共享缓存或主存,然后更新请求核心的缓存,保证数据最新。
一致性协议: SCU遵循一定的缓存一致性协议,如MESI(Modified, Exclusive, Shared, Invalid)、MOESI(Modified, Owner, Exclusive, Shared, Invalid)或其他协议,来决定如何响应缓存访问并维护一致性。
广播与仲裁: 在多核系统中,SCU可能需要广播某些缓存操作,比如写操作,给所有核心,或仲裁缓存访问冲突,决定哪个核心优先级次序。
目录管理: 在大型系统中,SCU可能配合缓存目录使用,目录存储哪个缓存行位于哪些地方,其状态,减少广播范围和提高效率。
综上所述,Snoop Control Unit是多处理器缓存一致性机制中的重要一环,通过
监听和协调处理器间的缓存操作,确保数据的一致性,从而支持高效、可靠并行计算。
1.5 CMN600ae一致性总线
之前的文章:AI SoC入门-6CPU子系统
中2.7章有对CMN600ae的介绍。这里再说明下。
ARM发展了一种介于
总线和NoC之间的连接系统,称之为
CMN(Coherent Mesh Network) ,主要用于连接CPU内核,也可以CPU内核和加速器之间的连接。采用
MESH网格结构,但没有路由功能,本质上还是总线,但MESH网格支持的单元很多,远比一般总线要多,最高可支持512核,支持512MB的L3缓存。
CoreLink
CMN600AE,一种支持
车规级安全功能的CoherentMeshNetwork,强调其功能安全合规性、高性能、可靠性以及低功耗特性。对外支持AMBA CHI/ACE-LITE等接口,内部改用路由结构转发数据,并提供
硬件一致性和系统缓存,还支持多芯片互联。
下图展示了一个3*4的互联Mesh,用于具有多个RNF实例的大型系统配置,包含的Node有HN-F、RN-D、SN-F和HN-D。每个互联的Mesh,以左下角的XP为坐标原点,建立二元坐标系(X,Y);每个XP有若干个Port,用来连接具体的设备;基于此,设备可以通过一个4元组(X, Y, Port, DeviceID) ,唯一标示,分别代表设备所在XP的坐标,Port,以及设备ID。
在mesh的架构中CMN600网络提高性能的方法:
1、mesh的架构层,通过
多级的cache,以及设计HNF node可以去snoop cluster中的cache,提高性能
2、协议层,CHI协议中支持
DMT、DCT、和prefetch功能提高性能
3、soc层,支持
qos机制来提高性能,qos的value一共有4bit,值为0-15,值越高优先级越高
CMN600AE的双chip方案如下:
参考:
https://blog.csdn.net/weixin_73077810/article/details/135979534
https://blog.csdn.net/tujiuguo3994/article/details/134676977
2. Noc一致性
上面CMN处理ARM A核的多核一致性问题,系统中的各种异构核,例如RISC-V,R,M等异构核之间的一致性问题的处理,就需要NoC去维护。
2.1 简介
片上网络(NoC)互连用于有效管理组件之间的数据流,提供可扩展的低延迟和高能效通信,从而实现 CPU、GPU、NPU 和其他加速器等功能的无缝集成。NoC 可减少数据瓶颈,提高系统性能,并适应 SoC 设计中日益增加的复杂性。
缓存一致性是 SoC 中各组件之间高效数据共享的核心。它是一种保证数据一致性的机制,可防止瓶颈和数据不一致,并最终维持整体系统性能。它确保系统在后台无缝运行。深入研究缓存一致性的工程师会发现自己处于硬件和软件的交叉点。
一致性互连可确保系统内的所有进程具有统一一致的内存视图。请考虑一个带有机器学习子系统的系统。在这样的设置中,机器学习处理器独立管理数据流,强加缓存一致性可能会带来不必要的开销。所以对独有资源的隔离,而不一定需要保证一致性互连。
Arteris产品线可分为Ncore和FlexNoC两类:
Ncore是缓存一致性互连IP,连接CPUs、加速器和内存子系统,是在2016年推出的针对异构计算芯片的IP;
FlexNoC则用于连接外围模块,包括D2D或C2C的并行接口以及一些扩展功能(如针对车规的安全扩展)
Ncore 的多种可配置监视过滤器能实现更有针对性和更简化的一致性管理,从而降低了设计的整体复杂性。这种方法确保了高效和量身定制的一致性解决方案,有助于提高整体效率。
参考:
2.2 CHI协议定义的NOC组件
请求结点RN 可以向NOC发送读/写等请求事务,有以下几种类型的RN:
1. RN-F 一般是处理器核或者核簇结点,包含了局部cache和一致性部件snoopee。与NOC上的一致性部件一起,维护“可缓存”数据的一致性(这种可缓存数据的地址一般是normal属性);RN-F可以发送所有请求事务类型;支持所有的snoop类型事务(这里不仅仅是指发送snoop类型事务,也包括了响应来自NOC的snoop类型事务)。RN-D 一般是支持SMMU的IO DMA请求点,不包含局部cache,也没有snoopee。能接收并响应来自RN-F的DVM类型事务(用于操作SMMU);主要负责发送DMA读/写主存时的数据一致性相关事务。RN-I 与RN-D类型,但不支持SMMU。一致性结点HN 隶属于NOC的功能部件,接收来自RN的事务请求,有以下几种类型的HN:
2. HN-F 包含了一个目录或者snoop filter来支持所有类型的事务请求,但不支持DVM类型的事务请求。HN-F管理所有RN-F的cache一致性,例如一个地址的最新数据究竟在哪几个RN-F的cache中,还是在NOC的L3 cache中;例如一个RN-F要写数据之前,首先就需要向HN-F拿到该地址的独占权(换句话说,HN-F协助RN-F获得地址的独占权);HN-F还可以用于管理内存请求之间的序,即HN-F是内存操作的保序点。我的理解:HN-F用于可缓存的normal属性地址范围。HN-I 支持部分类型的事务请求,不管理RN的数据一致性,用于针对外设的PIO操作的保序功能。我的理解:HN-I用于不可缓存的device属性地址范围。MN 专门用于接收DVM操作。从结点SN 只能接收来自HN的请求,完成相关操作,并返回响应消息。
3. SN-F 用于Normal属性内存,也可以处理非snoopable的读/写、原子操作请求和独占读写请求。SN-I 用于device属性的外设(或者Normal属性的内存),也可处理非snoopable的读/写,原子操作请求和独占读写请求。
注意:
这些节点都是可以配置的,在NoC中是硬件中配置,CMN可以在软件中进行配置。例如-F有cache可以保证一致性,-D没cache也不保证一致性。
参考:https://blog.csdn.net/lsshao/article/details/128969914
3. 软件角度
3.1 ARM内存一致性
首先就是ARM可以配置的内存属性,可以看ARM手册里面的描述。
1.**Normal memory类型属性适用于系统中的大多数内存。它表示架构允许硬件对这些位置执行推测数据读取访问(Speculative data read accesses),而不管这些位置的访问权限如何。为了确保访问Normal memory是的顺序性,有必要使用内存屏障指令:DMB**。
每个Inner共享域包含一组观察者(observers),这些观察者对于该组中的每个成员都是数据一致的,用于使用该组中的任何成员所创建的内部共享属性(Inner Shareable attribute)进行数据访问。
每个Outer共享域包含一组观察者,这些观察者对于该组的每个成员都是数据一致的,用于使用该组的任何成员所创建的外部共享属性(Outer Shareable attribute)进行数据访问。
Non-shareable Normal memory:不可共享的normal内存是
一块只能被单个CPU访问的Normal内存
每个Normal 内存还被分配了一个缓存属性:
Write-Through Cacheable.
Write-Back Cacheable.
Non-cacheable.
2. Device内存类型属性定义了内存位置,其中对该位置的访问可能导致副作用,或者加载返回的值可能根据执行的加载数量而变化。通常,Device内存属性用于内存映射的外设(memory-mapped peripherals)和类似的位置。
不允许对具有任何Device memory属性的任何内存位置进行推测性数据访问(Speculative data accesses)。这意味着对任何Device内存类型的每个内存访问都必须是由程序的简单顺序执行生成的。
对任何Device memory类型的内存位置的写入在有限时间内完成。
如果从Device memory类型的内存位置读取的返回值发生了变化,而观察者没有显式的内存写入影响,则该变化也必须在有限时间内对系统中的所有观察者进行全局观察。这样的更改可能发生在保存状态信息的外设(peripheral location that holds status information)。
对于系统中的所有观察者来说,对Device memory位置的数据访问都是一致的,并相应地被视为可外部共享的(Outer Shareable)。
具有任何Device memory属性的内存位置都不能分配到缓存中。
对于任何Device memory类型的访问,使用DMB指令,在对单个外设或指定大小的内存块的所有访问上引入一个Barrier-ordered-before关系。
如果内存位置不能支持未对齐的内存访问(unaligned memory accesses),那么对该内存位置的未对齐访问将在转换的第一阶段生成对齐错误(Alignment fault),该转换将该位置定义为Device。
硬件不会阻止从具有任何Device memory属性的内存位置进行推测性的指令获取,除非该内存位置也被标记为所有异常级别的execute-never。
Device type有四种子类型,分别对应不同的限制级别。以下是最宽松的几种子类型:
Device-GRE
Device-nGRE
Device-nGnRE
该子类型是最严格的:
- Device-nGnRnE
Device后面的字母表达的是属性的组合:
(1)Gathering(G,nG)。表示访问可以被合并(G)或不可以被合并(nG)。意思是可能会将对同一地址的多个访问合并为一个访问,或将多个小的访问合并为一个大的访问。
(2)Re-ordering(R,nR)。表示对同一外设的访问可以被乱序(R)或不可以被乱序(nR)
(译者:我觉得翻译成“乱序”或“重排”都行)。当允许乱序时,其乱序规则与Normal type一致。
(3)Early Write Acknowledgement(E,nE)。此属性决定一个 write 操作何时可以被认为是“已完成”的。如果允许Early Write Acknowledge(E)
(译者:early可以简单理解为“提前”,在事实生效之前,具体讨论见“9. 一次访问何时被认为是'已完成'”),则一旦一个write操作对其他观察者可见,即使该访问并未真正到达其目的地,该访问依然会被视为“已完成”。
Data Memory Barrier(DMB)用于防止指定的explicit数据访问会跨越屏障指令乱序。program order上在DMB之前的所有explicit数据load或store指令,会在program order上该DMB之后的数据访问之前被指定Shareability domain中的所有Observers观察到。
DSB内存屏障用于确保在此DSB之前的内存访问,必须在DSB指令执行完成之前完成。正因如此,其是一个比DMB约束更强的内存屏障。由指定参数的DMB所带来的保序,相同参数的DSB也可以做到。
DMB:只能达到保序,不能落盘
DSB:可以落盘
ISB:指令层面顺序保障
其他的一些内存类型:
- M核中有
strongly-ordered:和device基本一样但保序。A核中一般device属性中有GRE来达到类似的效果。
参考:
https://blog.csdn.net/luolaihua2018/article/details/128986147
https://vxworks.net/arm/1127-arm-architecture-memory-systems-ordering-and-barriers
3.2 MPU保障一致性
一般的ARM M核会选用MPU。
MPU(Memory Protection Unit) 内存保护单元。armv7-m 架构下是选配的,我们舒马赫的M4F是支持的。armv7-m 通常支持8个region。一个region 就代表一段连续的区域。
MPU可以用来定义内存空间的属性,比如特权指令和非特权指令以及 cache 是否可访问。增加系统的健壮性:
可以阻止用户去破坏操作系统需要使用的数据
可以防止一个任务去非法访问其他任务的数据,将任务完全隔离开
可以把关键数据区设为只读,从而不被破坏。
检测其他意外访问,比如,堆栈溢出,数组越界等。
MPU 可以定义某些特定的地址区域的属性,这个属性可以定义成很多类型,比如定义成非特权状态下不可以赋值
如果非特权指针不小心访问到这个地址区域并且尝试给该区域赋值修改,这个时候会触发 MemManage fault 或者 hardfault 中断,代表你的程序不被允许修改该区域。
其寄存器TEX、C、B可以决定内存类型,组合如下:
3.3 设备寄存器的一致性问题
有一些设备是挂在NoC总线里面的,那么CPU要去访问这些设备的寄存器,其实是需要DSU-》CMN-》NoC控制数据才能到设备去设置的。如果这中间出现了cache一致性,那么对设备寄存器的控制其实并未生效。
例如CPU去访问UFS的一致性问题,一般出现在UFS控制器和CPU的配合上面。例如CPU去操作了UFS的寄存器,然后UFS控制器去工作的时候发现寄存器的设置不对,从而报错。也就是说CPU去操作UFS寄存器并没有操作成功。
一般设备内存映射被ARM配置为Device属性。但是其也不是强保序落盘的,需要进一步配置Device-nGnRnE或使用strongly-ordered。另外non-cacheable的属性也有局限性,只是限制了A核,但是CMN、NoC也需要进行配置。
在CMN和NoC中,这些总线加速有提前回复的机制,如果对一致性高的系统,需要对其进行关闭才可以。具体的细节就是各种总线根据协议ACE/CHI等去同步这些数据的状态。常用的两个方法:
设置CMN或者NoC关闭提前回复
设置内存属性Device-nGnRnE或使用strongly-ordered
关于CMN600的在ARM官网的手册里面有设置:
bit8:ncdevcmo_mc_comp设置后就会关闭提前回复,但是这样会降低一部分的效率。
对于提前回复,其实是一个order的错乱,提前回复了,如果主体速度慢的去用,没问题。如果主体速度比较快里面就去用,那么末端还没生效,就导致时序的错乱。
3.4 SRAM一致性问题
SoC中会存在一些系统级别的SRAM,各个核都可以访问,有时也作为共享内存,或者固件运行的存储。但是涉及到异构多核访问SRAM的时候,就存在一致性问题。
首先就是初始化的时候SRAM硬件一定要上电完成后才使用,否则写入的数据一段时间读出来全是0,无效。硬件有相关的寄存器可以确保SRMA ready。
异构核之间访问,写入系统SRAM的内容后需要flash下。
在MCN和NoC中的端口例如HN-F和HN-I等属性是否配置正确
其他DDR和UFS、ramdisk等的一致性问题也是上面这些问题,另外遇到这些问题从三个方面进行排查:
内存类型配置是否正确(core、MPU、CMN、NoC等中的配置),内存类型的配置可以通过协议传播的,可以逐个尝试去配
提前回复、乱序执行等导致的order错乱
cache一致性,dsb刷cache等
另外遇到一些性能的问题,也可以从一致性入手,例如保障一致性有n个方法,使用某个方法性能最佳。甚至可以不保证完全的一致性,软件上做一些校验来容错也可以。
后记:
一致性问题从软硬件角度包含的东西比较多,本文算一个纲领进行了大致总结,具体细节需要分析软件代码和硬件的手册,十分庞杂。而且要利用trace32等dump手段去看某时刻内存值的状态,还有进行对比。
“啥都懂一点,啥都不精通,
干啥都能干,干啥啥不是,
专业入门劝退,堪称程序员杂家”。
欢迎各位有自己公众号的留言:申请转载!
纯干货持续更新,欢迎分享给朋友、点赞、收藏、在看、划线和评论交流!
彩蛋:
本公众号提供微信技术交流群,一起探讨汽车软件技术(先加微信:thatway1989,备注感兴趣的技术方向)。
有需要投放广告、商业合作的也可以联系博主。
赞赏1元钱交个朋友