你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

言简意赅介绍M7内核Cache工作流程, 摸爬滚打半年的经验总结

[复制链接]
baiyongbin2009 发布时间:2018-11-6 01:01
本帖最后由 baiyongbin2009 于 2018-11-6 01:01 编辑
0 ]7 i8 N( {5 _6 s% {0 H
, R/ |* z5 i5 Y* I9 i, E- N说明:4 F2 [" \! Z7 @) }
    初学M7的Cache时,经常是ARM的手册和ST的手册看了一遍又一遍,虽然每次看,每次都有收获,但是一直无法形成系统的认识,说到某一个知识点也明白,但是具体到读写操作的时候是怎么个流程,就懵逼了,也是心里烦躁,最近脑子开窍了些,特此分享下经验。
1 D0 X9 i' S& J: W
2 \4 b0 [  J$ E; I  E当前的认识能力有限,有不对的地方,欢迎批评指正。4 Q' n5 G; P8 }& H! M9 |

: N: ~# h$ t# Q& u一、引出问题:. J7 f! K7 A5 O- ?# L: \- c
    当前芯片厂商出的M7内核芯片基本都做了一级Cache支持,Cache又分数据缓存D-Cache和指令缓冲I-Cache,对于指令缓冲,用户不用管,这里主要说的是数据缓存D-Cache。以STM32H7为例,主频是400MHz,除了TCM和Cache以400MHz工作,其它AXI SRAM,SRAM1,SRAM2等都是以200MHz工作。数据缓存D-Cache就是解决CPU加速访问SRAM。
8 ]8 t3 q0 W% y- W. V0 p
  m3 C. Y1 j% W* Z2 e2 `2 X. ~    如果每次CPU要读写SRAM区的数据,都能够在Cache里面进行,自然是最好的,实现了200MHz到400MHz的飞跃,实际是做不到的,因为数据Cache只有16KB大小,总有用完的时候。4 O4 P9 Q- X# M& [) }- t) {7 j" m

6 ?  o0 R$ I3 E! |3 p0 |7 f5 g对于使能了Cache的SRAM区,要分读写两种情况考虑。
$ j- u/ T" }) b读操作:9 n! B' D- U* j# I
如果CPU要读取的SRAM区数据在Cache中已经加载好,这就叫读命中(Cache hit),如果Cache里面没有怎么办,这就是所谓的读Cache Miss。
6 ^$ {, k# l4 l9 v4 D" }+ O. a( Y5 ^% k# Z2 T- j' E
写操作:
6 e- x6 Z2 K4 I# L/ f* B如果CPU要写的SRAM区数据在Cache中已经开辟了对应的区域(专业词汇叫Cache Line,以32字节为单位),这就叫写命中(Cache hit),如果Cache里面没有开辟对应的区域怎么办,这就是所谓的写Cache Miss。
! r1 e! v# I( C8 Y$ P+ a4 P+ C2 }; F% x, Z5 b( ~2 O: l0 b
% D8 G" I2 H& d
2 ]1 y5 G" h& F0 @

+ a4 q. o6 C" h) p% i1 U! U$ k二、支持的Cache配置:. k& ^. L+ a$ K7 C
Cache的配置是通过MPU来设置的,通常只用到下几种方式。6 B9 L3 i0 t9 Q) M
/ X2 k, j" `) ?# ?8 s

4 y& \8 X) C" U( t/ N& _其中的TEX是用来设置Cache策略的,C是Cache,B是缓冲用来配合Cache设置的,而S是共享,用来解决多总线或者多核访问时的同步问题。MPU配置的时候,最主要的也是配置这几个参数。
0 y* w+ S7 {% T+ e* p2 ]9 [9 s. z/ ]/ Z+ ^8 A8 q; K, E
Cache支持的策略有如下四种:
0 M+ i! e: c. T2 ^4 u4 _ ! C+ J! j/ y: f0 m% X8 |; o) Y

( c: ^9 v  s- G, Q' {' E0 v: G有了这四种方式,就可以在正式进入本帖的主题,Cache的读写操作是如何工作的,下面分这四种情况做一 一介绍。
: Y. j4 @  y3 e2 \# f
+ i& U' I5 k! S7 s$ H1 a三、四种Cache(MPU)配置的读写操作流程说明
+ N0 [; b& s& M) q. s1、 Non-cacheable" |6 v8 V, e: _, J3 K
这个最好理解,就是正常的读写操作,无Cache。. G# ~, t5 B" u" @) U' _& q

+ q# M' {0 N5 q(1)对应四种MPU配置如下:
+ |9 |% K' X( C  k1 c9 @TEX = 000 C=0 B=0  S=忽略此位,强制为共享
5 i/ r7 @/ J5 dTEX = 000 C=0 B=1  S=忽略此位,强制为共享
2 [2 U" c# ]- t; f* ?& l' k. YTEX = 001 C=0 B=0  S=0/ W9 M. l* U5 V/ [6 z
TEX = 001 C=0 B=0  S=1
5 P( E/ Y# B1 v0 {1 M9 G& ]% @1 e( W( ~
2、Write through, read allocate,no write allocate
- B+ l$ C- V7 p注意,M7内核只要开启了Cache,read allocate就是开启的。
3 S4 w: V! I" D: n1 t( e
. Y7 j: O. v$ z. e(1)使能了此配置的SRAM缓冲区写操作
6 Z; d. z8 f* o2 }: `4 g    如果CPU要写的SRAM区数据在Cache中已经开辟了对应的区域,那么会同时写到Cache里面和SRAM里面;如果没有,就用到配置no write allocate了,意思就是CPU会直接往SRAM里面写数据,而不再需要在Cache里面开辟空间了。
  |7 f, F4 ~$ b, R- d
5 M, N9 Z. J: e5 t% i1 D    在写Cache命中的情况下,这个方式的优点是Cache和SRAM的数据同步更新了,没有多总线访问造成的数据一致性问题。缺点也明显,Cache在写操作上无法有效发挥性能。/ |4 [, R) D6 y+ {% w- W
8 S8 H5 }" l. Y( i$ v% v& u
(2)使能了此配置的SRAM缓冲区读操作  I0 e* ]3 z" Y, _$ l5 A, g* _' a
    如果CPU要读取的SRAM区数据在Cache中已经加载好,就可以直接从Cache里面读取。如果没有,就用到配置read allocate了,意思就是在Cache里面开辟区域,将SRAM区数据加载进来,后续的操作,CPU可以直接从Cache里面读取,从而时间加速。; N+ z0 A$ r3 F3 y+ B! w7 @- |
. n2 B0 A. L% F4 [
    安全隐患,如果Cache命中的情况下,DMA写操作也更新了SRAM区的数据,CPU直接从Cache里面读取的数据就是错误的。
- E5 y3 o( s, ?- ~
3 q  X+ a. N  |' y  f(3)对应两种MPU配置如下:
4 s7 l+ m3 C% h+ x0 p, ATEX = 000 C=1 B=0  S=1
+ A1 L) K0 F' h) O( R3 GTEX = 000 C=1 B=0  S=0
  o- K0 K2 ^' P, ~8 t0 b5 ^6 q0 r/ ]+ {( Y% q
3、Write back, read allocate,no write allocate  O! k, F8 t, f4 ^+ W* u( M  x
注意,M7内核只要开启了Cache,read allocate就是开启的。
+ Y) P0 d0 B# v6 Z4 [: w% n5 W: t) Q
(1)使能了此配置的SRAM缓冲区写操作
# X6 d' o. P/ Q$ B    如果CPU要写的SRAM区数据在Cache中已经开辟了对应的区域,那么会写到Cache里面,而不会立即更新SRAM;如果没有,就用到配置no write allocate了,意思就是CPU会直接往SRAM里面写数据,而不再需要在Cache里面开辟空间了。6 V+ d+ R0 C+ c% M) Y

: F3 H+ _$ F1 |+ J5 _2 P9 ?    安全隐患,如果Cache命中的情况下,此时仅Cache更新了,而SRAM没有更新,那么DMA直接从SRAM里面读出来的就是错误的。# b/ E& Q- z9 E
  g, I, V2 z. y, Q# N
(2)使能了此配置的SRAM缓冲区读操作3 W" }: |+ I, R& ^  @/ T: o
   如果CPU要读取的SRAM区数据在Cache中已经加载好,就可以直接从Cache里面读取。如果没有,就用到配置read allocate了,意思就是在Cache里面开辟区域,将SRAM区数据加载进来,后续的操作,CPU可以直接从Cache里面读取,从而时间加速。
0 A( P$ K* I/ x- ~( t+ r9 F8 u) H, K8 X  }1 @1 ]. \% b2 b8 V
    安全隐患,如果Cache命中的情况下,DMA写操作也更新了SRAM区的数据,CPU直接从Cache里面读取的数据就是错误的。
; c) q( ?+ ]; e) G* H5 R4 ^# m
8 k. X" k9 ?8 w6 X* D& i  e8 G(3)对应两种MPU配置如下:! S- ^* @' T/ }9 Y$ g
TEX = 000 C=1 B=1  S=1/ L, ~5 X1 X& G) p/ u1 j! ~8 W
TEX = 000 C=1 B=1  S=05 T  ]7 A/ {7 i6 U( T* C) B
: J2 i! r4 U' R
4、Write back, read allocate,write allocate
/ m1 q& h; V+ T注意,M7内核只要开启了Cache,read allocate就是开启的。2 M) X- X1 z; m9 y# ]
7 e2 `+ l- Q" T1 m$ g& t  u1 l
(1)使能了此配置的SRAM缓冲区写操作
. r. w+ m/ D6 J8 `8 L& I    如果CPU要写的SRAM区数据在Cache中已经开辟了对应的区域,那么会写到Cache里面,而不会立即更新SRAM;如果没有,就用到配置write allocate了,意思就是CPU写到往SRAM里面的数据,会同步在Cache里面开辟一个空间将SRAM中写入的数据加载进来,如果此时立即读此SRAM区,那么就会有很大的速度优势。* ~) g. M$ U- i/ ?

& ]6 n9 v4 V3 O" c    安全隐患,如果Cache命中的情况下,此时仅Cache更新了,而SRAM没有更新,那么DMA直接从SRAM里面读出来的就是错误的。
6 u' H( Z  u2 f7 z! k# p7 W, c1 q1 s+ S7 J2 O
(2)使能了此配置的SRAM缓冲区读操作
, m, v( F) F1 L5 V" L7 f2 I. x    如果CPU要读取的SRAM区数据在Cache中已经加载好,就可以直接从Cache里面读取。如果没有,就用到配置read allocate了,意思就是在Cache里面开辟区域,将SRAM区数据加载进来,后续的操作,CPU可以直接从Cache里面读取,从而时间加速。
9 \$ E; i9 W2 C9 k7 M( T8 P( t8 Z/ ^6 R6 Y0 g! a+ l8 j
    安全隐患,如果Cache命中的情况下,DMA写操作也更新了SRAM区的数据,CPU直接从Cache里面读取的数据就是错误的。' H' d- [. B4 [6 q

2 h. }2 V# P9 x. \7 w# r    这个配置被誉可以最大程度发挥Cache性能,不过具体应用仍需具体分析。
  m2 y* ~7 d: o! `! _* B1 t
" R" @$ b$ z, S+ _, R(3)对应两种MPU配置如下:
, {2 {$ T  Y+ S. nTEX = 001 C=1 B=1  S=1
, g! t6 m1 _! S6 t: U9 ]TEX = 001 C=1 B=1  S=0; u9 P( }5 G) D$ m' v7 z) {4 ~) w8 M9 I
7 \+ V0 ], c9 E. V
5、共享配置是个隐形的大坑
5 n& B8 r' }$ C5 q: n& e3 d这里以STM32H7为例进行说明,STM32H7编程手册对其的描述是多核共享。" ~4 ^/ i3 P/ `* `; M& T

8 u. @* \  X0 m$ C& `. d
+ m2 b2 b% A2 ^1 f  Z8 B! r而H7的应用笔记对齐的描述是开启共享基本等同于关闭Cache。
; N- y9 R0 M+ ^" _4 i9 G9 L9 ?
7 m) y) D# N$ N
/ H" j* O5 e5 a' n- `9 X( Y实际测试下面四种开Cache的情况,开关共享对缓冲区的大批量数据的读操作影响很大,基本差出两倍,而写操作基本没有影响,也许这就是所谓的多总线同步读造成的。" n# B# u9 G! X0 a7 j& d5 B
另外共享开关仅对开启了Cache的情况下有影响,而对于关闭了Cache的情况是没有影响的,开不开没关系。" k* L: I8 L) u4 C8 \

) T9 q8 M) A+ G5 B* p1 I5 }6 L6、总结这几种方式的几个关键知识点7 v) Z0 J+ n1 t; |* s4 o! Y
(1)Cortex-M7内核的L1 Cache由多行内存区组成,每行有32字节,每行都配有一个地址标签。数据缓冲DCache是每4行为一组,称为4-way set associative。而指令缓冲区ICache是2行为一组,这样节省地址标签,不用每个行都标记一个地址。6 g7 W1 S5 `3 D& A( \/ ]& _, v  i
- ~8 A- \0 f/ o. P4 w3 \4 N' c
(2)对于读操作,只有在第1次访问指定地址时才会加载到Cache,而写操作的话,可以直接写到内存中(write-through模式)或者放到Cache里面,后面再写入(write-back模式)。* p* D' R/ L* B" }" z  g! y

+ ?& Q9 c/ P! L(3)如果采用的是Write back,Cache line会被标为dirty,等到此行被evicted时,才会执行实际的写操作,将Cache Line里面的数据写入到相应的存储区。5 _, [; s* I7 x+ h. x

/ N9 p) E8 g9 w(4)Cache命中是访问的地址落在了给定的Cache Line里面,所以硬件需要做少量的地址比较工作,以检查此地址是否被缓存。如果命中了,将用于缓存读操作或者写操作。如果没有命中,则分配和标记新行,填充新的读写操作。如果所有行都分配完毕了,Cache控制器将支持eviction操作。根据Cache Line替换算法,一行将被清除Clean,无效化Invalid或者重新配置。数据缓存和指令缓存是采用的伪随机替换算法。* a) @: z( x& ~3 D

$ x) Q. _* u2 d- U) d(5)Cache支持的4种基本操作,使能,禁止,清空和无效化。Clean清空操作是将Cache Line中标记为dirty的数据写入到内存里面,而无效化Invalid是将Cache Line标记为无效,即删除操作。6 T) r% i# n' Q) }
3 l! X2 W* D8 U+ J! m; Y; K

( S' M7 }2 A4 [, G/ z+ p! v' X四、面对这种繁冗复杂的Cache配置,推荐方式和安全隐患解决如下(以H7为例):
1 J1 v) y! i8 L8 T+ j(1)推荐使用128KB的TCM作为主RAM区,其它的专门用于大缓冲和DMA操作等。
% p! Q! H% |# B; X(2)Cache问题主要是CPU和DMA都操作这个缓冲区时容易出现,使用时要注意。
1 _$ h! F% V, x% G9 x8 B  E(3)Cache配置的选择,优先考虑的是WB,然后是WT和关闭Cache,其中WB和WT的使用中可以配合ARM提供的如下几个函数解决上面说到的隐患问题。但不是万能的,在不起作用的时候,直接暴力选择函数SCB_CleanInvlaidateDCache解决。关于这个问题,在分别配置以太网MAC的描述符缓冲区,发送缓冲区和接收缓冲区时尤其突出。
# Z/ N; J% ?* ^9 l" I2 p
8 v2 v  F' h, Q+ o  Y- k6 u* b9 M* N) J) A3 W$ o- Z  Y
收藏 6 评论8 发布时间:2018-11-6 01:01

举报

8个回答
myccl 回答时间:2018-11-6 08:55:28
总结的很好,通俗易懂,但是中间有一段重复了
西点钟灵毓秀 回答时间:2018-11-6 09:03:16
非常不错,好好学习
baobo 回答时间:2018-11-6 09:52:25
好资料,学习了,谢谢。
baiyongbin2009 回答时间:2018-11-6 11:48:51
myccl 发表于 2018-11-6 08:553 E! T5 `7 G5 `
总结的很好,通俗易懂,但是中间有一段重复了
8 x5 ~' E. L3 c
2,3,4的读是一样的
baiyongbin2009 回答时间:2018-11-7 11:25:04
zts329547875 发表于 2018-11-6 09:03
" R% f) `" l7 \  Z5 h1 \( r* ?0 R非常不错,好好学习
/ H  u) ~$ h+ G) j
3111272 回答时间:2019-3-5 17:08:39
学习了
lwg8458 回答时间:2019-3-6 09:39:06
学习
jinling 回答时间:2022-12-15 11:05:07
您好,看不到图片,有点不好理解。能重新上传下图片吗。
" D, o- J: Y& O2 K+ g& P1 ~$ i' e8 o# |+ Z" s$ i, ~) t

所属标签

相似分享

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版