当前位置: 首页 > 知识库问答 >
问题:

CPU缓存:两个地址之间的距离是否需要小于8字节才能具有缓存优势?

杜哲彦
2023-03-14

这似乎是一个奇怪的问题...

假设缓存线的大小为64字节。此外,假设L1、L2、L3具有相同的缓存线大小(这篇文章说Intel Core i7就是这样)。

内存上有两个对象AB,它们的(物理)地址相隔N个字节。为简单起见,让我们假设A在缓存边界上,也就是说,它的地址是64的整数倍。

1) 如果N

2)如果N

我的问题是,如果N

改写-加载A时,让t表示获取B的时间,t(N=70)是否比t(N=999999)小得多或几乎等于t?

我问这个问题是因为我怀疑t(N=70)比t(N=999999)小得多,因为CPU缓存是分层的。

如果有定量研究就更好了。

共有2个答案

赏彭薄
2023-03-14

如果B的地址低于a,则即使它们相邻,也不会在同一缓存线中。所以你的N

既然您提到Intel i7:Sandybridge系列在二级缓存中有一个“空间”预取器,它(如果没有太多未命中的话)预取一对缓存线中的另一条缓存线,以完成自然对齐的128B缓存线对。

英特尔优化手册第2.3节桑迪桥:

2.3.5.4数据预取

>

  • 一些预取器取入L1。

    空间预取器:该预取器努力用一对线来完成每个二级缓存的缓存线,该对线将其完成为128字节对齐的块。

    ... 其他几个预取器尝试预取到L2

    IDK它多久能做到这一点;如果它在第一个缓存线到达之前不发出请求,那么对于指针跟踪的情况将没有多大帮助。依赖负载在缓存线到达L1D后只能执行几个周期,如果它实际上只是指针跟踪而没有大量计算延迟的话。但是,如果在第一次未命中(包含第二次加载的地址)后不久发出预取,则第二次加载可能会发现其数据已经在L1D缓存中,在第一次按需加载后的一两个周期内到达。

    无论如何,这使得128B边界与Intel CPU中的预取相关。

    有关其他因素,请参见保罗的优秀答案。

  • 全弘深
    2023-03-14

    至少有三个因素可以使a未命中后提取B更快。第一处理器可以推测性地获取下一个块(独立于任何基于步幅的预取引擎,这取决于在时间和位置上彼此相邻遇到的两次未命中,以确定步幅;单位步幅预取不需要确定步幅值[它是一个],并且可以在第一次未命中后启动)。由于这种预取会消耗内存带宽和片上存储,因此它通常会有一个节流机制(可以简单到拥有一个中等大小的预取缓冲区,并且只有在内存接口足够空闲时才执行高度推测性预取)。

    其次,因为DRAM被组织成行,改变行(在单个存储区内)会增加延迟,如果B和A在同一个DRAM行中,对B的访问可能会避免行预充电的延迟(关闭先前打开的行)并激活(以打开新行)。(这也可以提高内存带宽利用率。)

    第三,如果B与A位于同一地址转换页中,则可以避免TLB。(在许多设计中,由于分页结构可以缓存,因此分层分页表在邻近区域的移动速度也更快。例如,在x86-64中,如果B与A位于同一2MiB区域,则TLB未命中可能只需执行一次内存访问,因为页目录仍然可以缓存;此外,如果B的转换位于同一64字节缓存lin中e由于A的转换和A的TLB未命中是最近的,缓存线可能仍然存在。)

    在某些情况下,还可以通过将可能丢失的对象以固定的有序步幅排列在一起来利用步幅基预取引擎。这似乎是一个相当困难和有限的上下文优化。

    步幅增加延迟的一个明显方法是引入冲突错过。大多数缓存使用简单的模,即有限关联性的两个索引的幂,因此两个步长的幂(或对同一缓存集的其他映射)可以在有限数量的集合中放置不成比例的数据量。一旦超过了关联性,就会发生冲突失误。(歪斜关联性和非二次方模索引已经被提出来减少这个问题,但是这些技术还没有被广泛采用。)

    (顺便说一句,指针跟踪速度特别慢的原因不仅仅是空间位置低,而且在对A的访问完成之前无法启动对B的访问,因为存在数据依赖性,即,提取B的延迟不能与提取A的延迟重叠。)

     类似资料:
    • 我对缓存这件事很陌生,并为我的spring boot应用程序学习了一些不同的解决方案。我在看Spring缓存,它是一种比我看到的redis缓存更简单的缓存机制。还有很多像“spring redis cache”这样的资源。当我看一下简单用法时,我看不出有什么不同。即使注释是相同的(Cacheable、CacheEvict、CachePut等),除了额外的redis配置和redis docker容器

    • Serenity 提供一些缓存抽象和实用功能让你更容易地使用本地缓存。 术语 本地(local) 的意思是指在本地内存中缓存项目(因此没有涉及到序列化)。 当你的应用程序在网站群(web farm) 中部署时,本地缓存可能还不够或者有时合适。我们将在 分布式缓存 章节中讨论该场景。

    • 问题内容: 我有多个运行同一进程的线程,它们需要能够互相通知,在接下来的n秒钟内不应进行某些处理,如果可以的话,这不是世界末日。 我的目标是能够将字符串和TTL传递到缓存,并能够以列表的形式获取缓存中的所有字符串。缓存可以存在于内存中,而TTL不会超过20秒。 有人对如何实现这一目标有任何建议吗? 问题答案: 您可以使用以下模块: 库的核心是class,它是一个有序字典,具有用于缓存目的的自动过期

    • ES 内针对不同阶段,设计有不同的缓存。以此提升数据检索时的响应性能。主要包括节点层面的 filter cache 和分片层面的 request cache。下面分别讲述。 filter cache ES 的 query DSL 在 2.0 版本之前分为 query 和 filter 两种,很多检索语法,是同时存在 query 和 filter 里的。比如最常用的 term、prefix、rang

    • 问题内容: 我需要测量以字符串形式提供名称的两个地方之间的物理距离。由于有时名称的书写方式略有不同,因此我一直在寻找一个可以帮助我测量差异的库,然后将其与纬度和经度结合起来以选择正确的匹配项。首选语言:Java或PHP。 有什么建议? 问题答案: 看看Levenshtein距离。这是一种测量两个字符串彼此之间有多不同的方法。 希望我能正确理解你的问题;在与“经度”相同的句子中使用“距离”可能会造成

    • 我正在尝试创建一个可以 是否有办法要求或进行设置