在现代多核处理器中,我们通常有一个本地L1缓存,但共享二级缓存。是否可以在仍然使用L2缓存的情况下绕过内存的某些部分的L1缓存?我想这样做是为了提高时序可预测性,但可能会牺牲性能。
答案 0 :(得分:0)
据我所知,没有办法绕过主流CPU上的L1缓存。
但是,为了实现您的目标(即避免可能导致时序陷阱变化的缓存未命中),您可以尝试让编译器将数据预取到缓存中。
如果您使用GCC或LLVM,请参阅__builtin_prefetch。
但是,您的问题很模糊,我不确定您的提案是否符合您的需求。
答案 1 :(得分:0)
<强>缓存强>
我强烈怀疑你误解了缓存的功能和用途。
从内存内容的角度来看,缓存是透明的。如果一个核心写入内存位置,那么其缓存(L1,L2,L3等)共享或不共享的其他核心恰好是缓存该位置也将更新。
请注意,不意味着核心无法竞争该值。你仍然可以有一个竞争条件,即一个核心在另一个核心读取位置之前将其写入“得到错误的值”。此外,无论您的CPU是否具有任何类型的缓存,都会发生这种情况。要解决这个“排序”问题,您必须在源代码中使用信号量或其他IPC原语。
某些缓存系统允许您“删除提示”。 Matthieu Rouget用__builtin_prefetch举了一个例子。这些事情允许程序员告诉缓存系统,提前获取一些数据可能是值得的。一些系统(例如PowerPC 7450)允许程序员使用部分缓存作为内存而不是缓存,这是程序员缓存控制的最终目的。
然而,这些事情都没有对所有缓存所具有的内存视图产生任何影响。如果一个缓存的内容得到更新,其余内容也会更新。
缓存和性能编程
最优秀的程序员可以通过编写缓存行为来从CPU中提取峰值性能。在这个领域,人们通常会发现自己希望缓存根本不存在。最终的实施例是PS3中的Cell处理器。其上的数学核心根本没有缓存。相反,您必须实际执行所有自己的数据提取并在源代码中回写自己,而不是将其留在某个缓存中,以便再次猜测程序要求的数据。做得对,性能仍然非常好。
Bus Snooping
某些CPU没有缓存总线侦听,这在编写设备驱动程序时可能是一个特殊问题。总线侦听是一种机制,通过该机制,CPU缓存通过除CPU核之外的其他东西(例如,通过DMA控制器从设备读取数据)来发现正在更新的存储器的内容。反之亦然 - 来自内存的DMA获取当前卡在缓存中的值。 AFAIK现在几乎所有的CPU都在做公共监听,所以这不太可能是一个问题。
在具有IO和内存地址空间的系统(例如Intel)上,我认为无论如何都不会缓存I / O地址空间。对于具有内存映射设备的系统,它们的内存通常也不会被缓存,并且OS会以这种方式设置CPU(请参阅this)。
时间可预测性
返回问题的原因 - 时间可预测性。您可能使用了错误的技术。如果你的系统有时序限制,问题是主存储器写入时间的变化,那么坦率地说使用多核CPU听起来就像是错误的东西。 @Griwes 在这一点上是完全正确的(事实上整个评论)。您更可能需要采用纯粹的硬件设计,这与FPGA类似(没有关于固件是否真的是软件的评论!)。
如果我怀疑你实际上是在尝试避免使用信号量和其他IPC原语来同步系统中的两个线程那么你就不会成功,共享缓存与否。您需要使用信号量等来使代码正常工作。