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

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

[复制链接]
baiyongbin2009 发布时间:2018-11-6 01:01
本帖最后由 baiyongbin2009 于 2018-11-6 01:01 编辑 1 }1 ^  K( C) k) d" M
$ T8 ~3 H$ n) G
说明:% M7 c4 S" v; I3 |: u+ h  t
    初学M7的Cache时,经常是ARM的手册和ST的手册看了一遍又一遍,虽然每次看,每次都有收获,但是一直无法形成系统的认识,说到某一个知识点也明白,但是具体到读写操作的时候是怎么个流程,就懵逼了,也是心里烦躁,最近脑子开窍了些,特此分享下经验。& X; s# K% m8 ]) X2 @: V

( D5 y! {* Z! p$ P* R当前的认识能力有限,有不对的地方,欢迎批评指正。9 {! U2 }7 ~2 |6 T; S3 W

3 l8 ^$ r. |5 ]一、引出问题:, {/ _0 E" U# 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 f* `' P/ T- R
8 T& m* C/ ~% @  J+ B
    如果每次CPU要读写SRAM区的数据,都能够在Cache里面进行,自然是最好的,实现了200MHz到400MHz的飞跃,实际是做不到的,因为数据Cache只有16KB大小,总有用完的时候。# W/ ?; C. H* g3 i' K5 x

% c7 ^, v/ W: B# j4 G) y对于使能了Cache的SRAM区,要分读写两种情况考虑。8 }' s# ~3 W0 ]
读操作:
- n. v. u; ^+ U7 V如果CPU要读取的SRAM区数据在Cache中已经加载好,这就叫读命中(Cache hit),如果Cache里面没有怎么办,这就是所谓的读Cache Miss。
9 y3 ?% Y5 {& G/ W( X& }* i7 R4 t9 x# ]+ x& ]) ^9 ]# f
写操作:- o0 p: o6 S; o, L( G
如果CPU要写的SRAM区数据在Cache中已经开辟了对应的区域(专业词汇叫Cache Line,以32字节为单位),这就叫写命中(Cache hit),如果Cache里面没有开辟对应的区域怎么办,这就是所谓的写Cache Miss。
# Z$ G* Y# }1 T9 v2 B3 C, m+ s8 `% i' G+ U' d3 H+ p
2 G: ^9 Y, Q; h

# k; Q3 U. s5 o$ Y! ^- f  K6 f( d0 S+ K3 g) X( z6 q
二、支持的Cache配置:
% D; E9 _# S; j; n" ^  oCache的配置是通过MPU来设置的,通常只用到下几种方式。
/ ~8 l9 N% r5 |! A8 K+ `
3 ^3 \) V% W' _$ c. q
( b; I& i2 N/ W" X' K其中的TEX是用来设置Cache策略的,C是Cache,B是缓冲用来配合Cache设置的,而S是共享,用来解决多总线或者多核访问时的同步问题。MPU配置的时候,最主要的也是配置这几个参数。
4 F3 ]1 n1 ?- B3 n" g+ _
3 a3 M6 r" |0 g! kCache支持的策略有如下四种:4 ]7 d# w; J$ t. F

" u6 O( Z/ N3 }" J2 F' @  R8 K4 Z* I. p1 N, g5 \
有了这四种方式,就可以在正式进入本帖的主题,Cache的读写操作是如何工作的,下面分这四种情况做一 一介绍。
/ w+ r, V5 o% ~( c5 g" A' p3 N8 I2 J6 o8 n
三、四种Cache(MPU)配置的读写操作流程说明- g" U. }- j9 P/ j( M
1、 Non-cacheable
' m+ `- Q& g7 u) Q, Q5 k  C% ^这个最好理解,就是正常的读写操作,无Cache。
! i( C6 C/ X) k5 q7 M) {4 ]1 Z6 ~- F5 ~- o
(1)对应四种MPU配置如下:
  v8 _# W1 a/ w* ?' [TEX = 000 C=0 B=0  S=忽略此位,强制为共享" H  ^7 u, c- [: V# h
TEX = 000 C=0 B=1  S=忽略此位,强制为共享2 q7 W7 ]. k( F1 h: r
TEX = 001 C=0 B=0  S=0' H. o7 r( T; f% z5 \0 h
TEX = 001 C=0 B=0  S=1& U" d/ E  C1 b3 l2 J7 v
* v5 O9 T' X1 n2 e2 B: c
2、Write through, read allocate,no write allocate
7 Y: o" \! \: ]% J注意,M7内核只要开启了Cache,read allocate就是开启的。
: i% z) I- n! z/ d; _; ~& F7 u) V( x& V$ F# ]
(1)使能了此配置的SRAM缓冲区写操作% J  p4 ?0 @. o
    如果CPU要写的SRAM区数据在Cache中已经开辟了对应的区域,那么会同时写到Cache里面和SRAM里面;如果没有,就用到配置no write allocate了,意思就是CPU会直接往SRAM里面写数据,而不再需要在Cache里面开辟空间了。
* A+ f) \' @" S5 n
9 w& V* `- z2 n3 C; G    在写Cache命中的情况下,这个方式的优点是Cache和SRAM的数据同步更新了,没有多总线访问造成的数据一致性问题。缺点也明显,Cache在写操作上无法有效发挥性能。
7 W: Y/ s' Y& K% R* ?. m. r9 l% ]9 l4 e) y9 J# x
(2)使能了此配置的SRAM缓冲区读操作
2 W0 x) C- V$ w" W0 D# v/ O    如果CPU要读取的SRAM区数据在Cache中已经加载好,就可以直接从Cache里面读取。如果没有,就用到配置read allocate了,意思就是在Cache里面开辟区域,将SRAM区数据加载进来,后续的操作,CPU可以直接从Cache里面读取,从而时间加速。$ f9 r) ^; ]% U5 k

, C) i! H. @6 m7 c* u$ q3 \    安全隐患,如果Cache命中的情况下,DMA写操作也更新了SRAM区的数据,CPU直接从Cache里面读取的数据就是错误的。# D6 R- G& m6 a, ^( J

8 h1 [! D1 F5 O  g, B6 W(3)对应两种MPU配置如下:
1 w1 U% u( l3 [* ?( ^1 lTEX = 000 C=1 B=0  S=1
" J4 r$ `6 s$ L. p4 Y% E* B6 Z6 [  lTEX = 000 C=1 B=0  S=03 Q+ p1 J# |! g; e% r
/ J4 m7 J& R+ V  s
3、Write back, read allocate,no write allocate& O% F' m; b) e# X8 L
注意,M7内核只要开启了Cache,read allocate就是开启的。4 N3 ~: n4 P+ v8 ?' v

3 G) |/ s/ \6 |1 c(1)使能了此配置的SRAM缓冲区写操作7 Q7 r5 N& B, g
    如果CPU要写的SRAM区数据在Cache中已经开辟了对应的区域,那么会写到Cache里面,而不会立即更新SRAM;如果没有,就用到配置no write allocate了,意思就是CPU会直接往SRAM里面写数据,而不再需要在Cache里面开辟空间了。
( W' E$ K% A# p( _7 K0 Y. L* n
* \% j+ B8 \6 ]4 f: n# Z6 g    安全隐患,如果Cache命中的情况下,此时仅Cache更新了,而SRAM没有更新,那么DMA直接从SRAM里面读出来的就是错误的。" R/ z6 x; v# U( _
7 m- ^' J& j; ]* |, z& S' t& A
(2)使能了此配置的SRAM缓冲区读操作
+ P2 s- M& W* Z1 g1 ^9 b7 Y   如果CPU要读取的SRAM区数据在Cache中已经加载好,就可以直接从Cache里面读取。如果没有,就用到配置read allocate了,意思就是在Cache里面开辟区域,将SRAM区数据加载进来,后续的操作,CPU可以直接从Cache里面读取,从而时间加速。
1 ?& g  ?- R) B/ L! ]: d! E& M; d1 c% V) Y& P$ Y1 w
    安全隐患,如果Cache命中的情况下,DMA写操作也更新了SRAM区的数据,CPU直接从Cache里面读取的数据就是错误的。6 T+ {. G; d1 D  u  H
) |( `& _3 g* [
(3)对应两种MPU配置如下:1 `& q0 X  u0 L( j, b
TEX = 000 C=1 B=1  S=1
8 ~5 L: ^$ E. i8 L9 D/ |TEX = 000 C=1 B=1  S=0
: K" `3 Y+ |$ _1 q4 n: ]& z% P. j6 @
4、Write back, read allocate,write allocate0 B  _2 t& Y9 n+ W
注意,M7内核只要开启了Cache,read allocate就是开启的。
- {- Z7 u; a7 j1 F8 X6 z% G3 ]8 S4 K8 M6 X; g. J
(1)使能了此配置的SRAM缓冲区写操作
- H0 {  z3 h) h8 [4 s4 h    如果CPU要写的SRAM区数据在Cache中已经开辟了对应的区域,那么会写到Cache里面,而不会立即更新SRAM;如果没有,就用到配置write allocate了,意思就是CPU写到往SRAM里面的数据,会同步在Cache里面开辟一个空间将SRAM中写入的数据加载进来,如果此时立即读此SRAM区,那么就会有很大的速度优势。" M: Z" [) N" v1 ]% R8 X! U4 o
8 L' x) d. d/ U4 j
    安全隐患,如果Cache命中的情况下,此时仅Cache更新了,而SRAM没有更新,那么DMA直接从SRAM里面读出来的就是错误的。
. `1 ?8 L9 b8 O7 v+ P3 T; S. D+ M
% h: u; x4 ]7 k7 v/ J4 I% r(2)使能了此配置的SRAM缓冲区读操作6 Q* o0 t1 Q  \( b7 d  w7 }4 X4 g3 \2 o
    如果CPU要读取的SRAM区数据在Cache中已经加载好,就可以直接从Cache里面读取。如果没有,就用到配置read allocate了,意思就是在Cache里面开辟区域,将SRAM区数据加载进来,后续的操作,CPU可以直接从Cache里面读取,从而时间加速。1 I/ p' D" @9 |% D. j' J5 d8 d1 y
' s1 f% }1 O, ^7 F- c. v+ O
    安全隐患,如果Cache命中的情况下,DMA写操作也更新了SRAM区的数据,CPU直接从Cache里面读取的数据就是错误的。3 _* [* c% u9 {9 Y
6 z' [1 B- b4 h' `" S
    这个配置被誉可以最大程度发挥Cache性能,不过具体应用仍需具体分析。
. @9 T* g0 i  ^. U8 s9 J
- J- q5 e% R8 v) M# ~2 y(3)对应两种MPU配置如下:, A! E8 J% f+ F9 W, s, e) A
TEX = 001 C=1 B=1  S=16 t  u! N* V6 ?$ d) H
TEX = 001 C=1 B=1  S=0
1 {' H* e8 I" }9 a7 B! c" l" h
+ }! ^. |- J- J* R! k0 C5、共享配置是个隐形的大坑
$ @! J, O% {8 I/ B7 f这里以STM32H7为例进行说明,STM32H7编程手册对其的描述是多核共享。
( ]: b+ p% ]* `3 Q, h / f# O! p' f. A9 ?2 p

6 j; B( W. t* q: ~而H7的应用笔记对齐的描述是开启共享基本等同于关闭Cache。" v  M3 h/ \) H$ ]1 F

9 V; [0 f; ], E" H# P+ o( ]1 @) D' e1 p  W1 O8 z/ \$ u
实际测试下面四种开Cache的情况,开关共享对缓冲区的大批量数据的读操作影响很大,基本差出两倍,而写操作基本没有影响,也许这就是所谓的多总线同步读造成的。- c& B' N* ~1 l; s
另外共享开关仅对开启了Cache的情况下有影响,而对于关闭了Cache的情况是没有影响的,开不开没关系。' l+ q4 U; _. U/ p( i
3 ]. I2 [6 W0 I5 T: k
6、总结这几种方式的几个关键知识点
! [5 d) p7 W  u5 a) |(1)Cortex-M7内核的L1 Cache由多行内存区组成,每行有32字节,每行都配有一个地址标签。数据缓冲DCache是每4行为一组,称为4-way set associative。而指令缓冲区ICache是2行为一组,这样节省地址标签,不用每个行都标记一个地址。
  E# r- k8 h) V% F5 V+ x( Z. W, c. A1 h- B
(2)对于读操作,只有在第1次访问指定地址时才会加载到Cache,而写操作的话,可以直接写到内存中(write-through模式)或者放到Cache里面,后面再写入(write-back模式)。% r7 m& p" m: K4 z: P) l3 V
+ `. q( ]& a4 y- i* x
(3)如果采用的是Write back,Cache line会被标为dirty,等到此行被evicted时,才会执行实际的写操作,将Cache Line里面的数据写入到相应的存储区。8 p* c: L2 c6 ^" i/ D" @
7 t2 X" @* R' `1 _( |* q: q
(4)Cache命中是访问的地址落在了给定的Cache Line里面,所以硬件需要做少量的地址比较工作,以检查此地址是否被缓存。如果命中了,将用于缓存读操作或者写操作。如果没有命中,则分配和标记新行,填充新的读写操作。如果所有行都分配完毕了,Cache控制器将支持eviction操作。根据Cache Line替换算法,一行将被清除Clean,无效化Invalid或者重新配置。数据缓存和指令缓存是采用的伪随机替换算法。
7 n) _+ A" c1 R1 j. }
* Y6 C6 [1 ^& D% h& ~0 i$ v: V! ~(5)Cache支持的4种基本操作,使能,禁止,清空和无效化。Clean清空操作是将Cache Line中标记为dirty的数据写入到内存里面,而无效化Invalid是将Cache Line标记为无效,即删除操作。
) y, n8 a! `' i2 X' J7 G6 \& _" Z5 J9 z

1 k* o: h( R2 O3 J% O3 E  L四、面对这种繁冗复杂的Cache配置,推荐方式和安全隐患解决如下(以H7为例):
* V8 q* n( {# e& d) t4 E6 ?$ f(1)推荐使用128KB的TCM作为主RAM区,其它的专门用于大缓冲和DMA操作等。) Z; m! n; t5 c- v( k
(2)Cache问题主要是CPU和DMA都操作这个缓冲区时容易出现,使用时要注意。
9 w3 ?- W6 r2 f2 `(3)Cache配置的选择,优先考虑的是WB,然后是WT和关闭Cache,其中WB和WT的使用中可以配合ARM提供的如下几个函数解决上面说到的隐患问题。但不是万能的,在不起作用的时候,直接暴力选择函数SCB_CleanInvlaidateDCache解决。关于这个问题,在分别配置以太网MAC的描述符缓冲区,发送缓冲区和接收缓冲区时尤其突出。- p2 R" C5 [1 C4 _

4 e% p  z+ d5 g# l' t# Y
: ~  e. W- D. U5 g' g  V4 N
收藏 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:55* |$ P/ \! O1 n. v4 x
总结的很好,通俗易懂,但是中间有一段重复了

( x! I; ]2 F6 w/ \2,3,4的读是一样的
baiyongbin2009 回答时间:2018-11-7 11:25:04
zts329547875 发表于 2018-11-6 09:03
* v" G8 s0 {9 \" x2 u3 X: T; V非常不错,好好学习

9 D2 O5 t5 X6 _2 e
3111272 回答时间:2019-3-5 17:08:39
学习了
lwg8458 回答时间:2019-3-6 09:39:06
学习
jinling 回答时间:2022-12-15 11:05:07
您好,看不到图片,有点不好理解。能重新上传下图片吗。
8 `8 ]4 M; ]! D1 m0 L) g  l/ o! E( _% r' u; r. D4 C

所属标签

相似分享

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