直接映射的缓存如何返回数据?

时间:2018-12-15 23:47:00

标签: caching assembly mips cpu-architecture memory-address

我正在使用Patterson&Hennessey的《计算机组织与设计》课本来学习计算机体系结构和组装方面的第一堂课。我目前正在了解缓存。我知道CPU将检查缓存中的1.缓存块索引,2。该块中的有效位,3。有效标签。如果有效,则从那里将数据发送到处理器。

我很难将其描述为真实的东西。例如,也许我们想将单词从$ x加载到$ y。处理器得到一个说0x12345670的地址来表示$ x。因此,“ 0”将是偏移量,“ 67”将是索引,其余的将是标签。我们从缓存中获得了成功,但是数据在哪里?问题地址是数据吗?缓存中是否有更多空间可以容纳我们需要的数据?它会直接将您发送到内存中的该位置吗?假设有$ x,我们如何通过缓存从$ x获取数据。

还假设字长为32位,您是否将地址发送到高速缓存并返回完整的字,或者只是足够的位?

PS。从真实的示例中学习对我来说最有帮助,因此,如果您有足够的实践知识(以及mips编程特别是非叶子函数的编程),我也将不胜感激。

1 个答案:

答案 0 :(得分:0)

缓存不是编程的东西,如果您想看看openocores.org上的一些真实示例,那里至少有几个具有缓存的内核。 (您必须阅读vhdl / verilog)。不一定是在mips程序中看到的。

请注意,这本教科书是教科书中的佼佼者,其他人也没有使处理器遵循该确切模型,其设计完全像从未发生过或停顿了一段时间。许多人从那本书中学到了东西,所以我们经常使用这些术语来讲话。但是管道更深且不同,缓存几乎相同,但大小和宽度可能不同,并且在确定谁输谁被驱逐方面也必不可少。

通常将高速缓存描述为64 KB高速缓存具有一定数量的字节。这些是保存数据的字节。从速度较慢的一侧(DRAM /主存储器)读取的数据被缓存或存储在缓存中。那就是它的住所。

当您读取0x12345670处的一个字节,并且说高速缓存行为256个字节时,如果遗漏了,则从慢速/ dram端进行的读取等于0x12345600。如果您未命中,则高速缓存旨在确定该高速缓存将在其中将您的字节存储在高速缓存行中的位置。如果有人蹲在那里,则需要将他们的数据驱逐出去。如果该数据比dram中的数据新(发生了一些写操作),那么该数据会在将您的缓存行读取到缓存中之前写入dram中,然后最终将字节发送给您(总线宽度为32)或64位发送给您,处理器将与之隔离字节通道)。如果高速缓存行为空,或者不需要将其中的数据写回dram,则高速缓存只是从dram / slow内存一侧读取其中包含您的字节的行,并提供您的字节。

写入非常相似,但是如上所示,如果有命中,则将发生read-modify-write并完成。如果有未命中,则必须逐出某些东西,然后从慢速存储器中进行读取,然后发生读取-修改-写入。理想情况下 缓存在某处设置了某个位置,以便它知道该缓存行比dr​​am中的副本新,并且在被逐出时需要将其写入dram中,因此无法丢弃。

高速缓存还可以用作方便的存储并转发到较慢的dram。您想限制不必要的dram访问,如果您想向dram中写入一个字节,而又不想读取dram存储器/总线宽度,请修改该字节并以这些速度写回,那么您想在缓存中的sram中进行操作。高速缓存允许速度较慢的一侧将其所有事务都具有一个最佳大小。处理器核心和系统内存之间可能有多个缓存,因此并非所有缓存都可以这样做或必须这样做,但是理想情况下最后一个缓存可以做到。

如果我的高速缓存具有256字节的高速缓存行,则低8位是高速缓存行的偏移量,您将不会将其用于其余寻址。如果我有一个128Kbyte的缓存和256byte的缓存行,这意味着我可以容纳512个东西。我需要9位数据来从512项中进行选择。其中一些位来自其余的地址位(0x123456)。因此,我确切地知道这是存储空间中的哪个256字节,无论剩下的地址位都必须与我的缓存行一起存储。因此,超级简单的是4的低位,而0x56用于查找512行中的哪一行,剩下的0x1234减去lsbit 0b000100100011010必须作为查找的一部分存储在高速缓存中(实际标记) 。因此,标签本身需要512 * 15位的ram,再加上一些位来标记有效/无效和脏/干净。

在缓存行大小和开销之间存在微妙的平衡。就性能而言,缓存是一场赌博,您始终可以击败它们,并找到使该缓存比没有缓存更糟糕的基准。高速缓存行越小,如果您在内存中的随机位置读取单个字节,则每个事务的浪费就越少,这意味着高速缓存正在为您每个人读取256个字节,效率不是很高,因此您的每行64位8的痛苦要小得多。但是,如果您的程序更具线性,字符串副本,分支不多的程序,则较大的缓存行可能会很有用。高速缓存行越大,则您必须存储的标签越小,并且内存通常更少,开销也更少。

除了上面的方法(我的缓存中有512 256字节的缓存行)以外,您还可以有多种方法。我可能选择采用7个地址位而不是8个,并且有4种方法。如果我有一个程序每次读取跳0x100字节,那么一个高速缓存行将被占用,而另一个511 arent将被大量使用。但是我取而代之的是从地址中减去较少的位(7),并使用一些方法(关联性)。该地址有四个可能的着陆点之一,逻辑会在这四个位置寻找命中点,如果它们都未命中,则其中的任何一个都未被使用,如果没有,则存在一种算法来确定谁被驱逐(最后一个或随机数或轮循等)。如果我以0x100跳了一点,则至少使用了4行而不是1行。希望赌博能有所回报,并且程序会重新使用其中的一些行。

所有这些都应该以某种形式以某种语言出现在您的教科书中。

一个简化的示例,没有涵盖整个情况。您正在为某公司接听电话,老板发疯了,并指示您必须随身携带这些消息/注释,然后再将这些消息/注释携带给员工。您接听电话,写下员工姓名和信息。重复。在您达到16点或之前,您必须先将信息传达给员工。如果您的电话数达到16,您将无法接听任何电话,直到您提供至少一个电话并释放一个插槽。假设它就像过去一样,并且电话一直响,直到您拿起它(您是电话答录机)。如果在将笔记发送给该员工之前接到该员工的第二通电话,则可以将该第二条消息记在同一笔记上,但不算作两个。该注释是一个缓存行。员工名称是标签,消息是高速缓存行中的字节。我可以在此缓存中存储的缓存行总数为16。您的眼睛是看笔记的逻辑,以查看是否有命中或遗漏,就像您在时机确定驱逐时一样。您每次在办公桌上可以提供多个服务。因此,您需要设计电话缓存来确定是否要始终等到16张纸条后再发送一次/一些,以希望在某人收到多条消息时希望减少旅行次数,或者在收到消息后立即发送他们。或介于两者之间。您无法预测何时会打来电话,因此无法完美地设计解决方案,但目标是在某人(您)应答之前提高响铃次数,并改善向员工传递消息的能力。请注意,在这种幻想中,只要最终传递所有消息,员工就不会在乎从呼叫发生到收到消息之间的等待时间。不能涵盖实际的内存缓存问题和解决方案,但是如果抱歉的话,也许可以帮助您考虑一下,也许会使您的理解烦恼。

通常,作为程序员,缓存只是使您的计算机正常工作的内存系统的一部分,实际上并没有与之交谈,您通常是使用分配给程序的处理器的内存空间来做事。想要拥有一个字符串并对其进行操作,您可以这样做。您的程序本身最有可能在高速缓存上起作用,通常您不必费心对循环的位置或对齐方式。而且您可能没有考虑MMU,它可以/确实使操作系统认为的线性地址空间实际上分散在物理内存中,然后这些碎片如何进入缓存也不在您的直接控制之下。如果您通常编写要在Windows或Linux或Mac或iOS或Android上运行的程序,则不知道位于高级程序后面的MMU /缓存配置。裸机确保您处于控制之中,并且可以旋转旋钮(mmu,代码和数据对齐与分割)。有些系统/芯片可以读取缓存的尺寸,有些则可以弄乱参数。在那种情况下,您可能会很开心,要么显示缓存有很大帮助,或者显示缓存使代码运行缓慢。

编辑:

'67' would be the index

我会拒绝,但是如果您认为是正确的话。

but where is the data?

它在缓存中,用谷歌搜索“缓存”一词,或在字典中查找它。缓存保存数据。

Is the address in question the data?

有问题的地址全部或部分成为标签。

Is there more space in the cache that holds the data we need? 

数据在缓存中。

Does it send you directly to that location in memory?

如果未命中,那么将从主存储器中读取数据并将其存储在缓存中,然后至少将您要求的部分发送给您。

Also assuming 32bit word length, you send the address to the cache and get a full word back or just the bits that are enough?

由总线的设计和实现决定。读取成为32或64位这样的单元并处理器从中提取字节或所需内容的情况并不少见。这并不是低效率的,它在现代处理器上通常会以这种类型的单位执行尽可能多的工作,使用字节大小的变量可能会降低性能,从技术上讲它可以节省您的内存,但是1970年代早已结束了有足够的记忆力。通常,写是大小重要的写操作,通常有一个字节掩码(指示总线的哪些字节具有必须存储的实际数据)或大小,并且总线使用数据总线的位0至N-1。

PS. it is most helpful for me to learn from real examples, so if You have resources on practice for this (and mips programming particularly non leaf functions) I would really appreciate that as well.

Opencores.org有一些带有缓存的处理器。