Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 什么是数据缓存和指令缓存?_Assembly_Arm_Cpu Architecture_Cpu Cache - Fatal编程技术网

Assembly 什么是数据缓存和指令缓存?

Assembly 什么是数据缓存和指令缓存?,assembly,arm,cpu-architecture,cpu-cache,Assembly,Arm,Cpu Architecture,Cpu Cache,发件人: 指令和数据具有不同的访问模式,访问 不同的记忆区域。因此,两者都有相同的缓存 说明和数据可能并不总是有效 因此,通常有两个缓存:一个指令缓存 仅存储指令和仅存储数据的数据缓存 知道指令和数据之间的区别是很直观的,但现在我不确定在这个上下文中的区别是什么?什么构成数据并放入数据缓存,什么构成指令并放入指令缓存 我知道手臂装配。任何需要STR、LDR、LDMF或STMFD的东西都会使用数据缓存吗?但从技术上讲,STR、LDR、LDMF和STMFD都是指令,所以我感到困惑。“数据”必须始终与

发件人:

指令和数据具有不同的访问模式,访问 不同的记忆区域。因此,两者都有相同的缓存 说明和数据可能并不总是有效

因此,通常有两个缓存:一个指令缓存 仅存储指令和仅存储数据的数据缓存

知道指令和数据之间的区别是很直观的,但现在我不确定在这个上下文中的区别是什么?什么构成数据并放入数据缓存,什么构成指令并放入指令缓存

我知道手臂装配。任何需要
STR
LDR
LDMF
STMFD
的东西都会使用数据缓存吗?但从技术上讲,
STR
LDR
LDMF
STMFD
都是指令,所以我感到困惑。“数据”必须始终与“指令”一起存在吗?在
.data
部分中是否考虑了数据

例如,
ldrr1,=myVar
那么LDR是否会进入指令缓存,myVar的内容是否会进入数据缓存?或者它不是这样工作的

指令和数据具有不同的访问模式 有人能详细说明一下吗

我在一篇有用的帖子上发表的这一评论突出了我理解的困难:

“这个想法是,如果一条指令是从内存加载的,它是 可能很快会再次使用“但知道下一个的唯一方法 指示是阅读它。这意味着一个记忆读取(你不能说 它已经在缓存中,因为一条新指令正在刷新)。所以我 还是不明白重点?假设刚刚发生了一个LDR指令,那么现在 LDR在数据缓存中。可能会发生另一个LDR指令, 也许不会,我们不能确定,所以我们必须阅读下一篇 指令-因此无法达到缓存的目的


指令缓存将包括从内存中提取以执行的缓存线。数据缓存将包括从内存中提取的缓存线,以便作为数据加载到寄存器中。

指令提取可以分块进行,前提是大部分时间您将在一行中运行多条指令。因此,指令回迁可能更有效,每个事务可能会有少量或更多的时钟开销,然后是内存准备好数据的延迟,然后是每个总线宽度的时钟,用于事务的大小。例如,8个字或指令可能是5+n+8个时钟,这比一次一条指令(5+1+1)*8更有效

另一方面,如果假设数据在大部分时间内都是按顺序读取的,那么额外的周期可能会造成伤害,那么只获取所需的数据(u p到内存或总线的宽度,因为这是免费的)

在手臂上,我知道一级缓存I和D是分开的,二级缓存I和D是组合的。L1不在axi/amba总线上,访问效率可能比L2更高,超过L2的是amba/axi(每个事务的开销加上时间加上每个总线数据宽度一个时钟的几个周期)

对于标记为可缓存的地址空间(如果mmu处于打开状态),L1和L2将获取缓存线,而不是数据的单个项,并且可能超过指令获取的I数据量

ldr和ldm指令中的每一条都将导致数据周期,如果地址是可缓存的,则这些数据周期可以进入L2和L1缓存(如果还没有)。如果位于可缓存地址,指令本身也将进入L2和L1缓存(如果还没有)。(是的,有很多旋钮来控制哪些是可缓存的,哪些不是,我不想讨论这些细微差别,为了便于讨论,假设所有这些指令获取和数据访问都是可缓存的)

您可能希望保存刚在缓存中执行的指令,以防出现循环或再次运行该代码。此外,缓存线中的后续指令将受益于节省的更高效访问开销。但是,如果您只通过缓存线的一小部分执行,那么总体而言,这些周期是一种浪费,如果这种情况发生得太多,那么缓存会使事情变慢

一旦某个内容在缓存中,那么下一次读取(或写入,具体取决于设置)时,将使用缓存副本,而不是慢内存中的副本。最终(取决于设置),如果由于写入(str、stm)而修改了某些项的缓存副本,并且需要在缓存中保存一些新的访问,则旧的访问将被逐回慢速内存,并从缓存写入慢速内存。指令没有这个问题,指令基本上是只读的,因此不必将它们写回慢速内存,理论上高速缓存拷贝和慢速内存拷贝是相同的

ldr r1,=myvar
将导致pc的相对负载

ldr r1,something
...
something: .word myvar
ldr指令将是缓存线提取的一部分,一个指令提取(以及一堆更多的指令)。这些将保存在arm上一级缓存的I部分和二级缓存的共享部分(如果启用,等等)。当该指令最终执行时,某个对象的地址将经历一次数据读取,如果在该区域为该读取启用了缓存,那么它也将进入二级和一级缓存(D部分),如果还没有。 如果您循环并立即再次运行该指令,则理想情况下,该指令将位于一级缓存中,获取该指令的访问时间非常快,总共需要几个时钟。数据也将在一级缓存中,并且将有少量时钟需要读取

我上面提到的5+n+8,一些开销的时钟数(5只是一种可能性,它可以根据设计和其他并行情况而变化)。N取决于较慢的内存sp