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

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

[复制链接]
baiyongbin2009 发布时间:2018-11-6 01:01
本帖最后由 baiyongbin2009 于 2018-11-6 01:01 编辑
/ S4 H) b. a# x6 }" Y; {5 Y
4 t. R0 V  Q& t$ m- G! _说明:' j$ |( @) A6 b6 A
    初学M7的Cache时,经常是ARM的手册和ST的手册看了一遍又一遍,虽然每次看,每次都有收获,但是一直无法形成系统的认识,说到某一个知识点也明白,但是具体到读写操作的时候是怎么个流程,就懵逼了,也是心里烦躁,最近脑子开窍了些,特此分享下经验。' d; c+ `0 g- ^5 _
0 A7 ^) G# K1 |) }3 d0 a2 L1 \
当前的认识能力有限,有不对的地方,欢迎批评指正。8 d. X! N# [+ L: \
! {# j& P8 Y+ q& V- c$ O
一、引出问题:. Z4 l  C5 X2 L* m. _, N
    当前芯片厂商出的M7内核芯片基本都做了一级Cache支持,Cache又分数据缓存D-Cache和指令缓冲I-Cache,对于指令缓冲,用户不用管,这里主要说的是数据缓存D-Cache。以STM32H7为例,主频是400MHz,除了TCM和Cache以400MHz工作,其它AXI SRAM,SRAM1,SRAM2等都是以200MHz工作。数据缓存D-Cache就是解决CPU加速访问SRAM。% y$ i! v0 D) P
3 x; ?. K* L& [$ ~
    如果每次CPU要读写SRAM区的数据,都能够在Cache里面进行,自然是最好的,实现了200MHz到400MHz的飞跃,实际是做不到的,因为数据Cache只有16KB大小,总有用完的时候。0 w% g5 v' n1 P2 k

8 K, d6 K  R5 q% `$ _对于使能了Cache的SRAM区,要分读写两种情况考虑。
3 y# l  Q1 ~* {- W' t" Q" b读操作:6 O1 e4 S, a" m  l" I, j% A
如果CPU要读取的SRAM区数据在Cache中已经加载好,这就叫读命中(Cache hit),如果Cache里面没有怎么办,这就是所谓的读Cache Miss。
! \/ ?, y  U+ b8 q& v& e
) m' L5 O; y- V: A; a, }: j  _写操作:
% p, _8 Y/ J7 s, l' d如果CPU要写的SRAM区数据在Cache中已经开辟了对应的区域(专业词汇叫Cache Line,以32字节为单位),这就叫写命中(Cache hit),如果Cache里面没有开辟对应的区域怎么办,这就是所谓的写Cache Miss。) H/ F) G# H7 _$ f! y! S
: N2 z& u8 D8 s- ~. \: j

7 u8 s& U3 A4 z* k2 P+ M! T2 W/ f) n) e# \

% \. ?% t% s4 m, b二、支持的Cache配置:
) [' r: ?# p' G8 K+ }- }4 G& n( vCache的配置是通过MPU来设置的,通常只用到下几种方式。: c1 h* ^0 j" t2 K" F
# X# I' k) n+ [/ z' Q

* ]1 H" K8 \; d5 K8 s& F  r5 ]0 |' v其中的TEX是用来设置Cache策略的,C是Cache,B是缓冲用来配合Cache设置的,而S是共享,用来解决多总线或者多核访问时的同步问题。MPU配置的时候,最主要的也是配置这几个参数。
5 z1 Z3 r, N; P2 J# V0 q5 l( c
  l5 v- q: L9 U" c( ICache支持的策略有如下四种:
5 g: f2 l* U4 M" s. y" ~ 3 ]- V, z5 d, E1 P' Q2 e+ n
5 M  }2 i5 B+ @3 [% f
有了这四种方式,就可以在正式进入本帖的主题,Cache的读写操作是如何工作的,下面分这四种情况做一 一介绍。
1 ]& e1 U5 x' p2 Z, H8 J" Y# Y8 k2 w% h5 x, ^
三、四种Cache(MPU)配置的读写操作流程说明/ W9 s7 w4 z3 X
1、 Non-cacheable9 z* n2 M4 ^5 q/ L3 E7 j9 I# h* Q
这个最好理解,就是正常的读写操作,无Cache。
7 {2 b, X1 C& S9 u- {$ L
7 x0 [# V5 ^; o" k( d5 ?0 T/ h(1)对应四种MPU配置如下:& l& K% y. X2 y
TEX = 000 C=0 B=0  S=忽略此位,强制为共享
3 F3 k& t/ x+ j: K6 T$ TTEX = 000 C=0 B=1  S=忽略此位,强制为共享+ w) E, v) h- g  t) h; N! l$ a9 A
TEX = 001 C=0 B=0  S=0
% ?! x, Q3 B  g# }4 LTEX = 001 C=0 B=0  S=1
( g( |. C6 ]' u4 l( b% `1 T8 `1 D, J2 ?0 E* [4 K! y0 t
2、Write through, read allocate,no write allocate
4 U4 K3 E. @$ b注意,M7内核只要开启了Cache,read allocate就是开启的。
3 D6 v4 Y, Q2 L- L
" n, t# Q7 H# d# Z: ^(1)使能了此配置的SRAM缓冲区写操作# ]) N& ?* m/ x1 A
    如果CPU要写的SRAM区数据在Cache中已经开辟了对应的区域,那么会同时写到Cache里面和SRAM里面;如果没有,就用到配置no write allocate了,意思就是CPU会直接往SRAM里面写数据,而不再需要在Cache里面开辟空间了。) x1 x/ x" |6 t% X, {/ t
% ]  X0 S  a& P. q6 a, t
    在写Cache命中的情况下,这个方式的优点是Cache和SRAM的数据同步更新了,没有多总线访问造成的数据一致性问题。缺点也明显,Cache在写操作上无法有效发挥性能。
0 w9 A- R  P! w8 ~; ?: a4 P1 S! j" N- {& ?
(2)使能了此配置的SRAM缓冲区读操作3 _- Q/ Z* [2 c
    如果CPU要读取的SRAM区数据在Cache中已经加载好,就可以直接从Cache里面读取。如果没有,就用到配置read allocate了,意思就是在Cache里面开辟区域,将SRAM区数据加载进来,后续的操作,CPU可以直接从Cache里面读取,从而时间加速。
- R8 g$ u% G5 E2 `) T$ }# z1 s) U! I6 }$ U' d5 d* d
    安全隐患,如果Cache命中的情况下,DMA写操作也更新了SRAM区的数据,CPU直接从Cache里面读取的数据就是错误的。
+ C' {- A. s, Y3 [7 R1 Q3 N6 U1 {  D& z% C$ L
(3)对应两种MPU配置如下:
) @1 a0 M9 |7 V/ @TEX = 000 C=1 B=0  S=1) L, T6 p! R& l0 ?  f
TEX = 000 C=1 B=0  S=0
6 N1 z' g  O; U/ P( i- M# M, S: Z" W/ i7 o3 J
3、Write back, read allocate,no write allocate
8 x- \+ I9 `) ]8 |1 n注意,M7内核只要开启了Cache,read allocate就是开启的。# F0 M6 q  r: m1 p( a5 n
& T5 t" c$ L% E" ^
(1)使能了此配置的SRAM缓冲区写操作
# P+ P" k' K7 l1 |    如果CPU要写的SRAM区数据在Cache中已经开辟了对应的区域,那么会写到Cache里面,而不会立即更新SRAM;如果没有,就用到配置no write allocate了,意思就是CPU会直接往SRAM里面写数据,而不再需要在Cache里面开辟空间了。
9 _+ X/ E6 {% [$ |* s& w3 U% ?- _" ^
    安全隐患,如果Cache命中的情况下,此时仅Cache更新了,而SRAM没有更新,那么DMA直接从SRAM里面读出来的就是错误的。
# w' l- `5 g% @) |; E  }! f
  R* `$ }' m( q/ E& X2 y% e' e5 }# E  Q) P(2)使能了此配置的SRAM缓冲区读操作
, t/ L3 ?8 R  w4 b$ \   如果CPU要读取的SRAM区数据在Cache中已经加载好,就可以直接从Cache里面读取。如果没有,就用到配置read allocate了,意思就是在Cache里面开辟区域,将SRAM区数据加载进来,后续的操作,CPU可以直接从Cache里面读取,从而时间加速。
, h* V5 j$ I3 @: Z; B: o) U( G+ C( \8 Z2 T. |& v5 G
    安全隐患,如果Cache命中的情况下,DMA写操作也更新了SRAM区的数据,CPU直接从Cache里面读取的数据就是错误的。5 O" w0 P' I) V+ v8 O  D

4 t# F( t( w' U- f  o(3)对应两种MPU配置如下:, p) @) _  Z% C5 q1 v( r
TEX = 000 C=1 B=1  S=1' S9 b; M+ X  I# [! p, b
TEX = 000 C=1 B=1  S=07 z" z  q4 \. a) u6 d

# P9 _6 j& }# E5 B. R0 ]+ o4、Write back, read allocate,write allocate
( d! X. J! S1 d/ v. M% c" D. n注意,M7内核只要开启了Cache,read allocate就是开启的。6 s9 c& U/ o; R* B
1 L: H% D; z1 Y) q  W
(1)使能了此配置的SRAM缓冲区写操作6 _1 l% L; l* Y2 Y9 B7 V! K
    如果CPU要写的SRAM区数据在Cache中已经开辟了对应的区域,那么会写到Cache里面,而不会立即更新SRAM;如果没有,就用到配置write allocate了,意思就是CPU写到往SRAM里面的数据,会同步在Cache里面开辟一个空间将SRAM中写入的数据加载进来,如果此时立即读此SRAM区,那么就会有很大的速度优势。5 F% s+ B9 V) t2 d) a/ N

: I2 Y3 s2 D9 v! G& M    安全隐患,如果Cache命中的情况下,此时仅Cache更新了,而SRAM没有更新,那么DMA直接从SRAM里面读出来的就是错误的。3 [& p$ ?1 E' [+ p3 @& ^

0 `2 ~$ Y' W4 \(2)使能了此配置的SRAM缓冲区读操作; L$ g- j4 G+ }5 H  d; u9 E
    如果CPU要读取的SRAM区数据在Cache中已经加载好,就可以直接从Cache里面读取。如果没有,就用到配置read allocate了,意思就是在Cache里面开辟区域,将SRAM区数据加载进来,后续的操作,CPU可以直接从Cache里面读取,从而时间加速。+ k) c1 H$ K4 D  @2 p* z& }) b
, ^0 @$ z- z8 ^) A: Q: X/ J1 M
    安全隐患,如果Cache命中的情况下,DMA写操作也更新了SRAM区的数据,CPU直接从Cache里面读取的数据就是错误的。9 A6 Z! k8 R/ V6 O( v

- f% H# e7 ~3 I7 D    这个配置被誉可以最大程度发挥Cache性能,不过具体应用仍需具体分析。$ E# l1 M! Q9 j' V" r
( w7 n5 @3 ~5 w
(3)对应两种MPU配置如下:
  q/ i7 p2 x3 x3 ?TEX = 001 C=1 B=1  S=1
- ?+ q0 ]. _, `) J: c3 nTEX = 001 C=1 B=1  S=0& z' ~& u0 \1 ^  Q9 o9 S7 J
; x  K9 a) Y; L% U5 o
5、共享配置是个隐形的大坑* u) z! t/ h4 B6 d2 C/ T0 N, B
这里以STM32H7为例进行说明,STM32H7编程手册对其的描述是多核共享。
9 ~' r& u/ n% [$ n 5 X8 G! z( n1 i) h* P( i$ ]
8 M- U/ C' s+ J. `% F1 T8 R
而H7的应用笔记对齐的描述是开启共享基本等同于关闭Cache。
5 a$ L+ P' {1 B- f
7 X1 y- ]/ ]2 `9 ]' [- e# C6 {
; [7 q1 C1 G; |1 Y! ?实际测试下面四种开Cache的情况,开关共享对缓冲区的大批量数据的读操作影响很大,基本差出两倍,而写操作基本没有影响,也许这就是所谓的多总线同步读造成的。
+ h4 Q" f8 M0 t: @8 `# i& P) d另外共享开关仅对开启了Cache的情况下有影响,而对于关闭了Cache的情况是没有影响的,开不开没关系。( `0 i) d# K: y* L* R

0 |% P7 V. s! _" M6 I8 o& J7 ^6、总结这几种方式的几个关键知识点
6 i+ x( w) N& P' ?6 n(1)Cortex-M7内核的L1 Cache由多行内存区组成,每行有32字节,每行都配有一个地址标签。数据缓冲DCache是每4行为一组,称为4-way set associative。而指令缓冲区ICache是2行为一组,这样节省地址标签,不用每个行都标记一个地址。
9 q+ G* Z, l4 q1 X
+ W- y1 M  {: ]1 x(2)对于读操作,只有在第1次访问指定地址时才会加载到Cache,而写操作的话,可以直接写到内存中(write-through模式)或者放到Cache里面,后面再写入(write-back模式)。
0 z1 |! @/ X5 V9 K# e" ?, |+ d( |$ z7 |& q8 k/ B
(3)如果采用的是Write back,Cache line会被标为dirty,等到此行被evicted时,才会执行实际的写操作,将Cache Line里面的数据写入到相应的存储区。( R: k! X" M, }5 |( J) V* @3 R
, X) i" A+ P0 w! M# t( E
(4)Cache命中是访问的地址落在了给定的Cache Line里面,所以硬件需要做少量的地址比较工作,以检查此地址是否被缓存。如果命中了,将用于缓存读操作或者写操作。如果没有命中,则分配和标记新行,填充新的读写操作。如果所有行都分配完毕了,Cache控制器将支持eviction操作。根据Cache Line替换算法,一行将被清除Clean,无效化Invalid或者重新配置。数据缓存和指令缓存是采用的伪随机替换算法。
- W" ?1 l5 R% `0 Z' h
4 t& n9 W( b  U" p8 }(5)Cache支持的4种基本操作,使能,禁止,清空和无效化。Clean清空操作是将Cache Line中标记为dirty的数据写入到内存里面,而无效化Invalid是将Cache Line标记为无效,即删除操作。
% v- [: {+ Z% w0 q8 Z( E4 a3 ^' ^/ d' y
& X( G5 |0 U3 J" N9 s# ~3 Z
四、面对这种繁冗复杂的Cache配置,推荐方式和安全隐患解决如下(以H7为例):; Z  z  U) F. l9 ^6 i
(1)推荐使用128KB的TCM作为主RAM区,其它的专门用于大缓冲和DMA操作等。
0 m- n& j5 c2 Q8 k2 s* g3 U(2)Cache问题主要是CPU和DMA都操作这个缓冲区时容易出现,使用时要注意。
$ }7 G/ P1 v4 j: B) Q1 E(3)Cache配置的选择,优先考虑的是WB,然后是WT和关闭Cache,其中WB和WT的使用中可以配合ARM提供的如下几个函数解决上面说到的隐患问题。但不是万能的,在不起作用的时候,直接暴力选择函数SCB_CleanInvlaidateDCache解决。关于这个问题,在分别配置以太网MAC的描述符缓冲区,发送缓冲区和接收缓冲区时尤其突出。
2 ~- s) E  j. P* z) _% t  J
) e  ]5 M# W7 m3 a$ K! J# `. y
* ]+ O' r/ K7 R; R! ^& K& d
收藏 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:554 C* }- b, J0 i/ p" W
总结的很好,通俗易懂,但是中间有一段重复了
+ w& w, r5 e- H% w; `
2,3,4的读是一样的
baiyongbin2009 回答时间:2018-11-7 11:25:04
zts329547875 发表于 2018-11-6 09:035 N  H+ H$ G; T
非常不错,好好学习

* c. I9 Q$ T( i0 K; q) ?
3111272 回答时间:2019-3-5 17:08:39
学习了
lwg8458 回答时间:2019-3-6 09:39:06
学习
jinling 回答时间:2022-12-15 11:05:07
您好,看不到图片,有点不好理解。能重新上传下图片吗。- ^: x' T- D" Z4 |* D8 ^$ x

% w; s3 c6 o! S' j; I3 T

所属标签

相似分享

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