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

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

[复制链接]
baiyongbin2009 发布时间:2018-11-6 01:01
本帖最后由 baiyongbin2009 于 2018-11-6 01:01 编辑 ( I/ P7 @7 ?" h
# Q  @1 A9 v, \# @
说明:1 H2 {/ m: A/ i5 T+ I
    初学M7的Cache时,经常是ARM的手册和ST的手册看了一遍又一遍,虽然每次看,每次都有收获,但是一直无法形成系统的认识,说到某一个知识点也明白,但是具体到读写操作的时候是怎么个流程,就懵逼了,也是心里烦躁,最近脑子开窍了些,特此分享下经验。
, y' y/ ^/ m1 `3 d8 }2 @2 L9 {1 M3 W- g  U; a7 |
当前的认识能力有限,有不对的地方,欢迎批评指正。
2 Z1 L8 Q6 j5 r9 r) u! C
) a: D! G. q7 [+ D一、引出问题:  d6 O4 s% W% X" w% F0 ~
    当前芯片厂商出的M7内核芯片基本都做了一级Cache支持,Cache又分数据缓存D-Cache和指令缓冲I-Cache,对于指令缓冲,用户不用管,这里主要说的是数据缓存D-Cache。以STM32H7为例,主频是400MHz,除了TCM和Cache以400MHz工作,其它AXI SRAM,SRAM1,SRAM2等都是以200MHz工作。数据缓存D-Cache就是解决CPU加速访问SRAM。; V" @1 n9 x% A, m; e* F; z

/ C* ?: v! G5 E, r0 K    如果每次CPU要读写SRAM区的数据,都能够在Cache里面进行,自然是最好的,实现了200MHz到400MHz的飞跃,实际是做不到的,因为数据Cache只有16KB大小,总有用完的时候。2 O" w2 G" T: E) I  `' p
7 M3 y, F0 s2 R+ H7 C6 Q( i
对于使能了Cache的SRAM区,要分读写两种情况考虑。
0 l3 u% w' S% p, b# T; `9 s; G读操作:. c4 Z! T& M$ G! J0 d. F1 D( {
如果CPU要读取的SRAM区数据在Cache中已经加载好,这就叫读命中(Cache hit),如果Cache里面没有怎么办,这就是所谓的读Cache Miss。
) l: V2 W* g, j8 C/ m1 q$ q
! |+ g5 u) H% R写操作:
' i5 E8 P! {8 q  a( l" m如果CPU要写的SRAM区数据在Cache中已经开辟了对应的区域(专业词汇叫Cache Line,以32字节为单位),这就叫写命中(Cache hit),如果Cache里面没有开辟对应的区域怎么办,这就是所谓的写Cache Miss。
, H8 M! m( Z* R- J) ^9 ^0 ]* S4 b% }# l8 e* F' h6 {
( I( o. x/ k3 K$ D( S. l
& z6 k$ `2 J. |! P

6 _8 m3 E6 k: A: G' t0 {% L" R! ]二、支持的Cache配置:
% U) i3 F2 k( }0 ~3 a1 _Cache的配置是通过MPU来设置的,通常只用到下几种方式。
- l! a7 s0 U9 f; X/ L0 c % z# }! N5 W7 N& o+ S

1 K$ Y" {- Z) b0 O% w其中的TEX是用来设置Cache策略的,C是Cache,B是缓冲用来配合Cache设置的,而S是共享,用来解决多总线或者多核访问时的同步问题。MPU配置的时候,最主要的也是配置这几个参数。( G) J; |+ y8 B. m( h1 ~

- t+ R- T4 g1 X$ pCache支持的策略有如下四种:
4 g, T5 g- ]6 ^- q' Q0 w , J9 q9 ~2 L1 I8 ]# }% m

: q$ y& `: p4 \- b$ y* o有了这四种方式,就可以在正式进入本帖的主题,Cache的读写操作是如何工作的,下面分这四种情况做一 一介绍。
4 }9 D; H7 t/ F( d' m# D; S3 m
5 d/ c3 s, i0 Q三、四种Cache(MPU)配置的读写操作流程说明6 L3 o" G0 X; n8 o9 @+ H
1、 Non-cacheable5 p, |! ^3 w. ^. g
这个最好理解,就是正常的读写操作,无Cache。7 T: G: [% _8 F$ N' b
$ U- `2 a6 k" g6 _
(1)对应四种MPU配置如下:
  Z1 x, J# v/ u' R! b* iTEX = 000 C=0 B=0  S=忽略此位,强制为共享
- ?) U2 D! J' E: JTEX = 000 C=0 B=1  S=忽略此位,强制为共享
& ]0 p7 F4 ~' d% M6 F: STEX = 001 C=0 B=0  S=0
! p4 M4 U1 V$ p+ Q, i8 z- ITEX = 001 C=0 B=0  S=19 |# P! p# L$ y6 o& T. k1 d
, a# \$ v# @" @7 J" _: `
2、Write through, read allocate,no write allocate
5 x! Y/ X0 d' o- X  Y; @: f注意,M7内核只要开启了Cache,read allocate就是开启的。4 U& H8 h1 a* ]; x7 a% j
# @* i; f" Y9 d& o  a: N+ @
(1)使能了此配置的SRAM缓冲区写操作
0 l" y% \0 {9 H: E9 q    如果CPU要写的SRAM区数据在Cache中已经开辟了对应的区域,那么会同时写到Cache里面和SRAM里面;如果没有,就用到配置no write allocate了,意思就是CPU会直接往SRAM里面写数据,而不再需要在Cache里面开辟空间了。0 |1 P, e6 ~, A6 T  p
) `- }% c7 x! j
    在写Cache命中的情况下,这个方式的优点是Cache和SRAM的数据同步更新了,没有多总线访问造成的数据一致性问题。缺点也明显,Cache在写操作上无法有效发挥性能。$ E1 d' U; g. b3 D

  v; l2 K$ w) {(2)使能了此配置的SRAM缓冲区读操作+ ?# Y* g( ^7 U5 H' b
    如果CPU要读取的SRAM区数据在Cache中已经加载好,就可以直接从Cache里面读取。如果没有,就用到配置read allocate了,意思就是在Cache里面开辟区域,将SRAM区数据加载进来,后续的操作,CPU可以直接从Cache里面读取,从而时间加速。4 ^) }# H; f4 B3 U
' l& o9 {/ g/ Z! n! B
    安全隐患,如果Cache命中的情况下,DMA写操作也更新了SRAM区的数据,CPU直接从Cache里面读取的数据就是错误的。
3 j. ]) D" q: w( J4 B2 x+ ^" F" ~7 x+ a* u" P
(3)对应两种MPU配置如下:/ Y1 ~# E5 B7 X$ M% a
TEX = 000 C=1 B=0  S=1- ^& j' i# G9 g+ c- J) R
TEX = 000 C=1 B=0  S=0% Z+ A' {" _; i4 m9 E4 Q
0 M! Z7 R8 `* q
3、Write back, read allocate,no write allocate
/ M3 Y/ n1 ~# w8 r) H) r5 d: y注意,M7内核只要开启了Cache,read allocate就是开启的。
; t9 E- L/ F! ^; }2 V9 ?/ }) H" Z5 ^, v! M
(1)使能了此配置的SRAM缓冲区写操作
* m1 v# ^( J: V( f5 ~+ Q    如果CPU要写的SRAM区数据在Cache中已经开辟了对应的区域,那么会写到Cache里面,而不会立即更新SRAM;如果没有,就用到配置no write allocate了,意思就是CPU会直接往SRAM里面写数据,而不再需要在Cache里面开辟空间了。
4 e7 `% c5 m6 R' T5 ~4 B8 A( {1 W5 m0 Q" r
    安全隐患,如果Cache命中的情况下,此时仅Cache更新了,而SRAM没有更新,那么DMA直接从SRAM里面读出来的就是错误的。
4 a' u2 Y: r! ]  {+ s8 T% P4 X' C$ F3 P% ]9 y" p: @  r
(2)使能了此配置的SRAM缓冲区读操作
% N* F8 ^, v6 U   如果CPU要读取的SRAM区数据在Cache中已经加载好,就可以直接从Cache里面读取。如果没有,就用到配置read allocate了,意思就是在Cache里面开辟区域,将SRAM区数据加载进来,后续的操作,CPU可以直接从Cache里面读取,从而时间加速。
7 ?, D3 e8 T9 ~3 B* r/ ^$ X/ w. \7 M! a  o: E, B4 \: F
    安全隐患,如果Cache命中的情况下,DMA写操作也更新了SRAM区的数据,CPU直接从Cache里面读取的数据就是错误的。2 {, P3 N) @  T) E0 p% z! ]! g
# \0 U- U( |" A+ s0 s1 ^! a
(3)对应两种MPU配置如下:
/ U/ T$ L4 e" U! ^/ Q0 s) \TEX = 000 C=1 B=1  S=1" W% t( y+ k2 \' p% R; [
TEX = 000 C=1 B=1  S=0
5 @, y& q6 `: Y
- u1 @3 ?& `) ?( `7 V4、Write back, read allocate,write allocate0 Q9 ]7 x3 A5 `) O. F7 Q$ q
注意,M7内核只要开启了Cache,read allocate就是开启的。
, j) y- X9 ], f0 f- q) f; D) l+ F, ~8 @7 y2 c
(1)使能了此配置的SRAM缓冲区写操作6 f$ t) @0 y# H3 O
    如果CPU要写的SRAM区数据在Cache中已经开辟了对应的区域,那么会写到Cache里面,而不会立即更新SRAM;如果没有,就用到配置write allocate了,意思就是CPU写到往SRAM里面的数据,会同步在Cache里面开辟一个空间将SRAM中写入的数据加载进来,如果此时立即读此SRAM区,那么就会有很大的速度优势。
6 D, Z7 Y! g1 |! t+ H( L4 q
8 J& d  Q! ]4 }1 [9 u. b5 V    安全隐患,如果Cache命中的情况下,此时仅Cache更新了,而SRAM没有更新,那么DMA直接从SRAM里面读出来的就是错误的。7 F  O$ E7 s; L/ U$ J0 _( N

9 ?3 s8 k5 \( k2 G  ^+ e(2)使能了此配置的SRAM缓冲区读操作1 a3 t" q" @; I: i8 P, I8 C; y! T
    如果CPU要读取的SRAM区数据在Cache中已经加载好,就可以直接从Cache里面读取。如果没有,就用到配置read allocate了,意思就是在Cache里面开辟区域,将SRAM区数据加载进来,后续的操作,CPU可以直接从Cache里面读取,从而时间加速。) n1 T4 Y" @9 r
6 N8 I: M, `7 p5 P5 o: t
    安全隐患,如果Cache命中的情况下,DMA写操作也更新了SRAM区的数据,CPU直接从Cache里面读取的数据就是错误的。* w7 r( @; ]0 ?2 P2 D+ {

2 C8 U* ]0 l) l$ b    这个配置被誉可以最大程度发挥Cache性能,不过具体应用仍需具体分析。
$ O! Y7 o/ O/ r/ }( g! d: s% J* b. W( d+ U: {, M, V
(3)对应两种MPU配置如下:! z% f) ~7 y2 [. N4 i3 @+ @
TEX = 001 C=1 B=1  S=19 Z# t. C6 g1 h; [
TEX = 001 C=1 B=1  S=0
$ |$ ?% o" U1 X0 n6 Q& v5 x; e3 _  D: w: h9 g5 Z% y  Z
5、共享配置是个隐形的大坑
  W2 f  y8 r5 Z这里以STM32H7为例进行说明,STM32H7编程手册对其的描述是多核共享。
# M" a. t$ `/ | / Y! n( K( c) C
& G5 X1 f3 S9 M( ^! [9 _
而H7的应用笔记对齐的描述是开启共享基本等同于关闭Cache。% ~: Q0 p) Q) r( N
. o- G) R+ q! j8 |0 Z
1 P- Y' w5 @5 _# C1 }  q8 t
实际测试下面四种开Cache的情况,开关共享对缓冲区的大批量数据的读操作影响很大,基本差出两倍,而写操作基本没有影响,也许这就是所谓的多总线同步读造成的。
2 G2 M7 n6 U8 `8 g$ u# f另外共享开关仅对开启了Cache的情况下有影响,而对于关闭了Cache的情况是没有影响的,开不开没关系。
0 q  [7 F7 z! a* a) h
) C- a. T/ y2 f: s6、总结这几种方式的几个关键知识点! V9 {; O: n: x4 a4 G, J& L, M
(1)Cortex-M7内核的L1 Cache由多行内存区组成,每行有32字节,每行都配有一个地址标签。数据缓冲DCache是每4行为一组,称为4-way set associative。而指令缓冲区ICache是2行为一组,这样节省地址标签,不用每个行都标记一个地址。
; x% A8 Y! y2 C% b: X/ ?
' U! j6 G' B8 _1 i& E) b" r, L(2)对于读操作,只有在第1次访问指定地址时才会加载到Cache,而写操作的话,可以直接写到内存中(write-through模式)或者放到Cache里面,后面再写入(write-back模式)。& i0 |$ H0 X5 ]% |. |' E9 A. O
9 @$ }9 G" e" {9 O' y
(3)如果采用的是Write back,Cache line会被标为dirty,等到此行被evicted时,才会执行实际的写操作,将Cache Line里面的数据写入到相应的存储区。
) E' |" s3 n4 |2 H" x3 `; Q5 y1 n9 j
(4)Cache命中是访问的地址落在了给定的Cache Line里面,所以硬件需要做少量的地址比较工作,以检查此地址是否被缓存。如果命中了,将用于缓存读操作或者写操作。如果没有命中,则分配和标记新行,填充新的读写操作。如果所有行都分配完毕了,Cache控制器将支持eviction操作。根据Cache Line替换算法,一行将被清除Clean,无效化Invalid或者重新配置。数据缓存和指令缓存是采用的伪随机替换算法。
* v- |( H* W9 @. A  V6 N3 t# D4 J8 z
(5)Cache支持的4种基本操作,使能,禁止,清空和无效化。Clean清空操作是将Cache Line中标记为dirty的数据写入到内存里面,而无效化Invalid是将Cache Line标记为无效,即删除操作。
4 s9 }+ h0 |  h. D
$ F4 f3 }: J. m1 r: U9 G. i; C" p  s1 t" _6 \! c: e
四、面对这种繁冗复杂的Cache配置,推荐方式和安全隐患解决如下(以H7为例):! n; k- j1 j( s$ l% n
(1)推荐使用128KB的TCM作为主RAM区,其它的专门用于大缓冲和DMA操作等。5 H2 [1 _1 {4 H, ?0 ~0 P: W9 z
(2)Cache问题主要是CPU和DMA都操作这个缓冲区时容易出现,使用时要注意。
: U: x9 M# e7 l(3)Cache配置的选择,优先考虑的是WB,然后是WT和关闭Cache,其中WB和WT的使用中可以配合ARM提供的如下几个函数解决上面说到的隐患问题。但不是万能的,在不起作用的时候,直接暴力选择函数SCB_CleanInvlaidateDCache解决。关于这个问题,在分别配置以太网MAC的描述符缓冲区,发送缓冲区和接收缓冲区时尤其突出。! q1 l  F7 g! L
7 B$ J9 l6 S4 g3 R$ u: x1 L8 C" R

/ A2 J- ^+ r3 J; H
收藏 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  q+ F, y: E9 _" s0 v. s; ^+ H9 N
总结的很好,通俗易懂,但是中间有一段重复了
( t- V- r1 ^9 J7 `! ~% G  T) B
2,3,4的读是一样的
baiyongbin2009 回答时间:2018-11-7 11:25:04
zts329547875 发表于 2018-11-6 09:03- E" j& @/ F* b. l4 h" e* H+ X! u" D$ W
非常不错,好好学习
: k4 ~3 C3 }5 j! d5 w
3111272 回答时间:2019-3-5 17:08:39
学习了
lwg8458 回答时间:2019-3-6 09:39:06
学习
jinling 回答时间:2022-12-15 11:05:07
您好,看不到图片,有点不好理解。能重新上传下图片吗。
4 g  I, A. ]& V5 B+ y6 B
# S- A3 X( k3 E; a2 s

所属标签

相似分享

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