如何降低 Cache 失效率

2023-10-19 01:20
文章标签 cache 降低 失效率

本文主要是介绍如何降低 Cache 失效率,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

看了酷壳上 @我的上铺叫路遥 投稿的"七个示例科普CPU Cache",收获比较多。建议阅读。

另外,我重新翻阅了下《计算机系统结构》的书,把 Cache 那章再阅读了下!对这块知识点的理解有了新的感受。这里简单整理了部分降低 Cache 失效率的方法,也算复习下。

降低 Cache 失效率的方法

许多相关 Cache 的研究都致力于降低 Cache 的失效率。

按照产生失效的原因不同,可以把失效分为以下3类(简称为"3C"):

(1). 强制性失效 (Compulsory miss): 当第一次访问一个块时,该块不在 Cache 中,需从下一级存储中调入 Cache,这就是强制性失效。这种失效也称为冷启动失效,或首次访问失效。// 增加块大小,预取

(2). 容量失效(Capacity miss):如果程序执行时所需的块不能全部调入 Cache 中,则当某些块被替换后,若又重新被访问,就会发生失效。这种失效称为容量失效。// 增加容量,会有抖动现象。

(3). 冲突失效(Conflict miss):在组相联或直接映像 Cache 中,若太多的块映像到同一组(块)中,则会出现改组中某个块被别的块替换、然后又被重新访问的情况。这就是发生了冲突失效。这种失效也称为碰撞失效(collision)或干扰失效 (interference)。// 提高相联度

SPEC92 基础测试程序给出了这三种失效在不同容量不同相联度下的失效率情况略。总结的情况如下:

  1. 相联度越高,冲突失效就越少。
  2. 强制性失效和容量失效不受相联度的影响。
  3. 强制性生效不受 Cache 容量的影响,但容量失效却随着容量的增加而减少。
  4. 表中的数据符合 2:1 的 Cache 经验规则,即大小为N的直接映像 Cache 的失效率约等于大小为 N/2 的 2 路组相联 Cache 的失效率

编译器优化

前面所介绍的技术(增加块大小、增加 Cache 容量、提高相联度、伪相联、硬件预取以及预取指令等)都需要改变或者增加硬件。下面介绍的方法,无需对硬件做任何改动就可以降低失效率。或许,这也是能对我们的程序效率有帮助的地方

我们能很容易地重新组织程序而不影响程序的正确性。例如,把一个程序中的几个过程重新排序,就可能会减少冲突失效,从而降低指令失效率。McFarling 研究了如何使用记录信息来判断指令组之间可能发生的冲突,并将指令重新排序以减少失效。他发现,这样可将容量为 2KB、块大小为 4KB 的直接映像指令 Cache 的失效率降低 50%;对于容量为 8KB 的 Cache,可将失效率降低75%。他还发现当能够是某些指令根本就不进入 Cache 时,可以得到最佳性能。但即使不这么做,优化后的程序在直接映像 Cache 中的失效率也低于未优化程序在同样大小的 8 路组相联映像 Cache 中的失效率。

数据对存储位置的限制比指令对存储位置的限制还要少,因此更便于调整顺序。我们对数据进行变换的目的是改善数据的空间局部性和时间局部性。例如,可以把对数据的运算改为对存放在同一 Cache 块中的所有数据进行操作,而不是按照程序员原来随意书写的顺序访问数组元素。

1. 数组合并 ( merging arrays )

这种技术通过提高空间局部性来减少失效次数。有些程序同时用相同的索引来访问若干数组中的同一维。这些访问可能会相互干扰,导致冲突失效。我们可以这样来消除这种危险:将这些相互独立的数组合并成为一个复合数组,使得一个 Cache 块中能包含全部所需的元素。

/* 修改 */

/* 修改 */

这个例子有一个有趣的特点:如果程序员能正确地使用记录数组,他就能获得与本优化相同的益处。

2. 内外循环交换 ( loop interchange )

有些程序中含有嵌套循环,程序没有按照数据在存储器中存储的顺序进行访问。在这种情况下,只要简单地交换循环的嵌套关系,就能使程序按数据在存储器中存储的顺序进行访问。和前一个例子一样,这种技术也是通过提高空间局部性来减少失效次数,重新排列访问顺序使得在一个 Cache 块被替换之前,能最大限度地利用块中的数据。

/* 修改 */

/* 修改 */

修改前程序以100个字的跨距访问存储器,而修改后的程序顺序地访问一个 Cache 块中的元素,然后再访问下一块中的元素。这种优化技术在不改变执行的指令条数的前提下,提高了 Cache 的性能。

简单测试:

PS: 可以编译执行下,有 0.02 秒的差异。

3. 循环融合 ( loop fusion )

有些程序含有几部分独立的程序段,它们用相同的循环访问同样的数组,对相同的数据做不同的运算。通过将它们融合为单一的循环,能使读入 Cache 的数据在被替换出去之前,得到反复的使用。和前面的两种技术不同,这种优化的目标是通过改进时间局部性来减少失效次数

/* 修改前 */

/* 修改后 */

修改前的程序在两个地方访问数组 a 和 c,一次是在第一个循环里,另一次是在第二个循环里。两次循环分隔较远,可能会产生重复失效,即在第一个循环中访问某个元素失效之后,虽已将相应块调入 Cache,但在第二个循环中再次访问该元素时,还可能产生失效。而在修改后的程序中,第二条语句直接利用了第一条语句访问 Cache 的结果,无需再到存储器去取。

4. 分块

这种优化可能是 Cache 优化技术中最著名的一种,它也是通过改进时间局部性来减少时效。下面仍考虑对多个数组的访问,有些数组是按行访问,而有些规则是按列访问。无论数组是按行优先还是按列优先存储,都不能解决问题,因为在每一次循环中既有按行访问也有按列访问。这种正交的访问意味着前面的变换方法,如内外循环交换,对此均无能为力。

分块算法不是对数组的整行或整列进行访问,而是对子矩阵或块进行操作。其目的仍然是使一个 Cache 块在被替换之前,对它的访问次数达到最多。下面这个矩阵乘法程序有助于我们理解为什么要采用这种优化技术。(此略)

... More

这篇关于如何降低 Cache 失效率的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/236333

相关文章

使用Spring Cache时设置缓存键的注意事项详解

《使用SpringCache时设置缓存键的注意事项详解》在现代的Web应用中,缓存是提高系统性能和响应速度的重要手段之一,Spring框架提供了强大的缓存支持,通过​​@Cacheable​​、​​... 目录引言1. 缓存键的基本概念2. 默认缓存键生成器3. 自定义缓存键3.1 使用​​@Cacheab

word转PDF后mathtype公式乱码以及图片分辨率降低等一系列问题|完美解决

word转PDF后mathtype公式乱码以及图片分辨率降低等一系列问题|完美解决 问题描述 最近在投一篇期刊论文,直接提交word文档,当时没有查看提交预览,一审审稿意见全是:公式乱码、公式乱码、乱码啊!!!是我大意了,第二次提交,我就决定将word文档转成PDF后再提交,避免再次出现公式乱码的问题。接着问题又来了,我利用‘文件/导出’或‘文件/另存为’的方式将word转成PDF后,发现公式

降低安全违规行为发生率,节省人工监管成本的智慧园区开源了

智慧园区场景视频监控平台是一款功能强大且简单易用的实时算法视频监控系统。 它的愿景是最底层打通各大芯片厂商相互间的壁垒,省去繁琐重复的适配流程,实现芯片、算法、应用的全流程组合,从而大大减少企业级应用约95%的开发成本。充分利用现有的摄像头设备,无需大规模更换,降低成本同时提升系统的实施效率。用户只需在界面上进行简单的操作,就可以实现全视频的接入及布控。 项目搭建地址 基础项目搭建地址:

[项目][CMP][Thread Cache]详细讲解

目录 1.设计&结构2.申请内存3.释放内存4.框架 1.设计&结构 Thread Cache是哈希桶结构,每个桶是一个按桶位置映射大小的内存块对象的自由链表 每个线程都会有一个Thread Cache对象,这样每个线程在这里获取对象和释放对象时是无锁的 TLS – Thread Local Strorage Linux gcc下TLSWindows vs下TLS

[项目][CMP][Central Cache]详细讲解

目录 1.设计&结构2.申请内存3.释放内存4.框架 1.设计&结构 Central Cache也是一个哈希桶结构,它的哈希桶的映射关系跟Thread Cache是一样的不同的是它的每个哈希桶位置挂的是SpanList链表结构(带头双向循环链表),不过每个映射桶下面的span中的大内存块被按映射关系切成了一个个小内存块对象挂在span的自由链表中 8Byte映射位置下面挂的是

工作效率的提升——如何高效沟通,有效降低沟通成本

如果你的上班时间是9点到18点,除去午休时间1.5h,剩余7.5h,那么你真正的有效工作时间又为多少呢? 如果你是一个财政/公司流程管理的知识产权审核人或销售许可申请负责人/销售/运营,沟通就是你的主要工作内容,如何更加清晰有效,直白明了,让不明事件原委的申请人或者新人,快速的了解需要自己准备或者更改的点,进而提高自己的工作效率呢? 如果你是测试人员/产品经理/开发人员,如何尽快让大家同频道沟

OceanBase 4.x 存储引擎解析:如何让历史库场景成本降低50%+

据国际数据公司(IDC)的报告显示,预计到2025年,全球范围内每天将产生高达180ZB的庞大数据量,这一趋势预示着企业将面临着更加严峻的海量数据处理挑战。随着数据日渐庞大,一些存储系统会出现诸如存储空间扩展难、性能下降甚至卡顿的情况,影响业务系统的正常运转,增加企业的数据处理成本。众多企业已经开始积极寻求如何在保证处理效率的同时,进一步降低数据处理成本。特别是在历史库(冷数据)场景中,这种需求显

无需更换摄像头,无需施工改造,降低智能化升级成本的智慧工业开源了。

智慧工业视觉监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒,省去繁琐重复的适配流程,实现芯片、算法、应用的全流程组合,从而大大减少企业级应用约95%的开发成本。用户只需在界面上进行简单的操作,就可以实现全视频的接入及布控。 项目搭建地址 项目开源地址:yihecode-server 本项目基于ai场景而开发,提供算法模型管理、摄像头管

LRU算法 - LRU Cache

这个是比较经典的LRU(Least recently used,最近最少使用)算法,算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。 一般应用在缓存替换策略中。其中的”使用”包括访问get和更新set。 LRU算法 LRU是Least Recently Used 近期最少使用算法。内存管理的一种页面置换算法,对于在内存中但又不用的

Fast Image Cache

https://github.com/path/FastImageCache   Fast Image Cache is an efficient, persistent, and—above all—fast way to store and retrieve images in your iOS application. Part of any good iOS applica