在哪些应用程序中缓存没有任何优势?
我们的教授要求我们考虑一种嵌入式系统设计,其中缓存无法充分利用。我一直在寻找这样的设计,但目前还没有找到。如果你知道这样的设计,可以给一些建议吗?
Our professor asked us to think of an embedded system design where caches cannot be used to their full advantage. I have been trying to find such a design but could not find one yet. If you know such a design, can you give a few tips?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
评论(5)
在控制内存映射外设方面,缓存没有优势,实际上是一种障碍。协处理器、电机控制器和 UART 之类的东西通常只是处理器地址空间中的另一个内存位置。这些位置不是简单地存储值,而是在写入或读取时导致现实世界中发生某些事情。
缓存会给这些设备带来问题,因为当软件写入它们时,外设不会立即看到写入内容。如果缓存行永远不会被刷新,那么即使 CPU 发送了数百个命令,外设也可能永远不会真正接收到命令。如果将 0xf0 写入 0x5432 应该会导致#3 火花塞点火,或者右侧副翼向下倾斜 2 度,那么缓存将延迟或停止该信号并导致系统故障。
同样,缓存可以阻止 CPU 从传感器获取新数据。 CPU 会重复读取该地址,而缓存会不断发回第一次的值。在缓存的另一侧,传感器耐心地等待永远不会到来的查询,而 CPU 上的软件则疯狂地调整控件,但对纠正永远不会改变的仪表读数没有任何作用。
缓存利用事实数据(和代码)表现出局部性。
因此,不表现出局部性的嵌入式系统将无法从缓存中受益。
示例:
嵌入式系统有 1MB 内存和 1kB 缓存。
如果该嵌入式系统以短跳转方式访问内存,它将在同一 1kB 内存区域中停留较长时间,该区域可以成功缓存。
如果这个嵌入式系统在这 1MB 内频繁地在不同的遥远地方跳转,那么就没有局部性,缓存将被严重使用。
另请注意,根据体系结构,您可以为数据和代码使用不同的缓存,也可以使用单个缓存。
更具体的示例:
如果您的嵌入式系统将大部分时间都花在访问相同的数据上,并且(例如)在适合缓存的紧密循环中运行,那么您就可以充分利用缓存。
如果您的系统类似于数据库,将从任何内存范围中获取随机数据,则无法充分利用缓存。 (因为应用程序没有表现出数据/代码的局部性。)
另一个奇怪的例子
有时,如果您正在构建安全关键型或任务关键型系统,您会希望您的系统具有高度可预测性。缓存使您的代码执行变得非常不可预测,因为您无法预测某个内存是否被缓存,因此您不知道访问该内存需要多长时间。因此,如果禁用缓存,它可以让您更准确地判断程序的性能并计算最坏情况的执行时间。这就是为什么在此类系统中禁用缓存很常见。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
考虑一下缓存是如何工作的。例如,如果您想破坏缓存,根据缓存的不同,您可以尝试将经常访问的数据放在 0x10000000、0x20000000、0x30000000、0x40000000 等处。每个位置只需要很少的数据即可导致缓存抖动并显着影响性能损失。
另一种是高速缓存通常拉入“高速缓存行”,单个指令读取可能会导致读取 8 或 16 或更多字节或字。任何情况下,在被驱逐以引入另一个高速缓存行之前,平均使用一小部分高速缓存行的情况都会使高速缓存的性能下降。
一般来说,您必须首先了解您的缓存,然后想出阻止性能增益的方法,然后考虑可能导致这种情况的任何现实情况。并非所有缓存都是平等创建的,因此没有一种好或坏的习惯或攻击适用于所有缓存。对于后面具有不同存储器的相同高速缓存或者前面具有不同处理器或存储器接口或存储器周期的情况也是如此。您还需要将系统视为一个整体。
编辑:
也许我回答了错误的问题。没有...充分的优势。这是一个简单得多的问题。在什么情况下,嵌入式应用程序必须接触缓存之外的内存(在初始填充之后)?进入主存储器会删除“充分优势”中的“充分”一词。国际海事组织。
Think about how a cache works. For example if you want to defeat a cache, depending on the cache, you might try having your often accessed data at 0x10000000, 0x20000000, 0x30000000, 0x40000000, etc. It takes very little data at each location to cause cache thrashing and a significant performance loss.
Another one is that caches generally pull in a "cache line" A single instruction fetch may cause 8 or 16 or more bytes or words to be read. Any situation where on average you use a small percentage of the cache line before it is evicted to bring in another cache line, will make your performance with the cache on go down.
In general you have to first understand your cache, then come up with ways to defeat the performance gain, then think about any real world situations that would cause that. Not all caches are created equal so there is no one good or bad habit or attack that will work for all caches. Same goes for the same cache with different memories behind it or a different processor or memory interface or memory cycles in front of it. You also need to think of the system as a whole.
EDIT:
Perhaps I answered the wrong question. not...full advantage. that is a much simpler question. In what situations does the embedded application have to touch memory beyond the cache (after the initial fill)? Going to main memory wipes out the word full in "full advantage". IMO.