如何编写最能利用 CPU 缓存来提高性能的代码?

2023-12-04

这听起来像是一个主观问题,但我正在寻找的是特定的实例,您可能遇到过与此相关的实例。

  1. 如何使代码、缓存有效/缓存友好(更多的缓存命中,尽可能少的缓存未命中)?从两个角度来看,数据缓存&程序缓存(指令缓存), 即代码中与数据结构和代码构造相关的哪些内容应该注意以使其缓存有效。

  2. 是否存在必须使用/避免的任何特定数据结构,或者是否存在访问该结构的成员等的特定方法......以使代码缓存有效。

  3. 在这件事上是否有任何程序结构(if、for、switch、break、goto...)、代码流(for 内部 if、if 内部 for 等...)应该遵循/避免?

我期待听到与制作缓存高效代码相关的个人经验。它可以是任何编程语言(C、C++、汇编……)、任何硬件目标(ARM、Intel、PowerPC……)、任何操作系统(Windows、Linux、Symbian……)等。 。

多样性将有助于更好地深入理解它。


缓存的作用是减少 CPU 因等待内存请求而停止的次数(避免内存占用)latency),作为第二个效果,可能会减少需要传输的数据总量(保留内存带宽).

避免内存获取延迟的技术通常是首先要考虑的事情,有时会有很大帮助。有限的内存带宽也是一个限制因素,特别是对于许多线程想要使用内存总线的多核和多线程应用程序。一组不同的技术有助于解决后一个问题。

改善空间局部性意味着您确保每个缓存行在映射到缓存后都得到充分使用。当我们查看各种标准基准测试时,我们发现其中很大一部分在缓存行被逐出之前未能使用 100% 所获取的缓存行。

提高缓存线利用率有以下三个方面的帮助:

  • 它倾向于在缓存中容纳更多有用的数据,从本质上增加有效缓存大小。
  • 它倾向于在同一缓存行中容纳更多有用的数据,从而增加了在缓存中找到所请求数据的可能性。
  • 它降低了内存带宽要求,因为读取次数会减少。

常见的技术有:

  • 使用较小的数据类型
  • 组织数据以避免对齐漏洞(通过减小大小对结构成员进行排序是一种方法)
  • 请注意标准动态内存分配器,它可能会引入漏洞,并在内存预热时将数据分散在内存中。
  • 确保所有相邻数据实际上都在热循环中使用。否则,请考虑将数据结构分解为热组件和冷组件,以便热循环使用热数据。
  • 避免表现出不规则访问模式的算法和数据结构,并支持线性数据结构。

我们还应该注意到,除了使用缓存之外,还有其他方法可以隐藏内存延迟。

现代CPU:通常有一个或多个硬件预取器。他们对缓存中的未命中情况进行训练,并尝试发现规律。例如,在后续缓存行发生几次缺失后,硬件预取器将开始将缓存行提取到缓存中,以预测应用程序的需求。如果您有常规的访问模式,那么硬件预取器通常会做得很好。如果您的程序不显示常规访问模式,您可以通过添加来改进预取指令你自己。

以这样一种方式重新组合指令,使缓存中总是丢失的指令彼此靠近,CPU 有时可以重叠这些提取,以便应用程序仅承受一次延迟命中(内存级并行性).

为了减少整体内存总线压力,您必须开始解决所谓的问题时间局部性。这意味着您必须在数据尚未从缓存中清除时重用数据。

合并接触相同数据的循环(循环融合),并采用称为tiling or blocking所有人都努力避免那些额外的内存获取。

虽然此重写练习有一些经验规则,但您通常必须仔细考虑循环携带的数据依赖性,以确保不会影响程序的语义。

这些都是在多核世界中真正得到回报的东西,在添加第二个线程后,您通常不会看到太多吞吐量的改进。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何编写最能利用 CPU 缓存来提高性能的代码? 的相关文章

  • 从 winforms picturebox 中的 url 加载的图像是否存储在缓存中?

    在 winform 应用程序的表单中 我必须显示存储在网络服务器上的图像 多个图像 显示图像没有问题 因为我可以简单地将 URL 分配给图片框 picturebox1 ImageLocation http example com Image
  • 使用标准 php 库使多个 memcache 键失效的最佳方法?

    我有一个数据库 其中的文件可以搜索 浏览 并且在多个服务器上有多个副本 我缓存搜索 浏览页面和服务器位置 url 假设我删除了一个文件 有什么好方法可以使该文件的所有搜索 浏览数据和 URL 失效 或者 如果文件服务器出现故障 我需要使指向
  • MongoDB 的优点和缺点? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 访问三个静态数组比访问一个包含 3 倍数据的静态数组更快?

    我有 700 个项目 我循环遍历这 700 个项目 为每个项目获取项目的三个属性并执行一些基本计算 我使用两种技术实现了这一点 1 三个 700 元素的数组 三个属性各一个数组 所以 item0 a array1 0 item0 b arr
  • 为什么使用寄存器 R12 时 POP 速度很慢?

    在最新的 Intel CPU 上 POP指令通常每周期具有 2 条指令的吞吐量 但是 当使用寄存器时R12 or RSP 除了前缀之外具有相同的编码 如果指令通过传统解码器 吞吐量会下降到每个周期 1 如果微指令来自 DSB 则吞吐量保持在
  • 为什么嵌套权重对性能不利?备择方案?

    我写了几个布局文件 其中使用了layout weight属性来创建不同视图之间的比率 在某些时候 我开始收到有关嵌套权重的 lint 警告 所以 我想知道为什么嵌套权重对性能不利 以及是否有一种更有效的方法来创建视图尺寸之间的恒定比率 该比
  • 从性能角度来说,是每次调用给定数组的长度更好,还是将长度存储在变量中并每次调用该变量更好?

    我经常调用给定数组的长度 我想知道是否最好继续调用它多次 目前超过 50 次 但它一直在增长 还是将长度存储在整数中并使用每次都是那个整数 如果我不清楚我所说的内容 请考虑以下几点 我有一个字符串数组 String str new Stri
  • 视图和表在性能上的差异

    对于包含大量数据的表来说什么是最好的 我有一个存储过程 可以根据一些过滤器创建报告 在我的 SP 中 我读取表格并放入所有内部联接和公式 然后在放置过滤器的 where 条件中 谈论性能什么更好 创建一个包含所有联接的视图或读取表 就像我正
  • 编码/设计通用线程安全限制器(即将 X() 每秒执行多次)

    我计划设计一个类来将函数的执行限制在指定时间内的给定数量 例如 最大处理量1 秒内 5 个文件 它应该是线程安全的并且性能影响应该最小 你会如何设计这样一个类 我有几个想法 但对我来说 没有一个是正确的 是否有任何已知的设计模式可以完成此类
  • Chrome 和 Firefox 之间的差异:重新加载运行 Javascript 游戏的页面

    我对 Javascript 和 Web 编程总体来说是新手 所以这可能是一个愚蠢的错误 尽管如此 我在寻找相关信息时遇到了问题 我正在用 Javascript 开发一个游戏 玩家可以通过点击并让他们的化身走到不同的建筑物 物体来四处走动并从
  • 为什么未执行的语句会减慢我的函数速度?

    我创建了四个不同的函数 如下所示 var normal function return var control function return alert Hello world var withArguments function ret
  • 如何让浏览器或 PHP 缓存 fetch() 请求?

    这基本上是相反的fetch 如何发出非缓存请求 https stackoverflow com questions 29246444 fetch how do you make a non cached request 假设我们有客户端 d
  • Windows Azure 虚拟机在扩展时访问网络速度很慢

    我正在我的小型 azure VM 上运行一些启动脚本 cmd bat 其中包括从已安装的 VHD 进行文件传输操作 通常会在大约 3 分钟内完成 复制文件并使用命令行提取 500Mb zip 文件 7z 当我扩展到约 150 个实例时 相同
  • sprintf 与 String.Format 的性能[重复]

    这个问题在这里已经有答案了 我正在比较 sprintf 用法的性能 并对我所看到的感到有点困扰 我测试了以下 4 个方法 将 ClassWithToString 的实例传递给每个方法 PrintInt 除外 它接收实际的整数值 type C
  • 为什么linkedhashmap维护双向链表进行迭代

    因为任何线程都没有内部合理的解释 请给我确切的理由 对于插入顺序 用单链表维护就足够了 但为什么不呢 在这种情况下 双向链表如何提高性能 所有方法都是从 hashmap xpt 4 方法继承的 那么 hashmap 的迭代器不维护顺序 而
  • 具有曼哈顿距离启发式的 A* 算法

    我一直在用 C 语言开发一个 15 个谜题求解器 我的代码使用的大量内存给我带来了一些问题 我不会发布我的代码 因为它太长了 我已经实现了我正在使用的大部分库 它可能会给您带来困惑 让我们从基础开始 我现在正在使用的东西是 全部用C实现 斐
  • 高效滚动最大和最小窗口

    我想有效地计算滚动最大值和最小值 这意味着比每次窗口移动时从使用的所有值重新计算最大值 最小值更好 这里有一篇文章问了同样的问题 有人发布了一个涉及某种堆栈方法的解决方案 据说该方法是根据其评级来工作的 然而我这辈子都找不到它了 在寻找解决
  • C 中每 N 个元素中出现次数最多的元素

    我有一个大小为 0 8388608 的大数组 A 其中包含 相对较小 的整数 A i 0 131072 我想找到每个 N 32 个元素中最常出现的元素 什么会更快 A 创建一个大小为131072的关联数组B 迭代32个元素 递增B A i
  • 基准测试:PostgreSQL 上的 bigint 与 int

    我想提高数据库性能 在一个项目中 所有表都来自int to bigint 我认为这不仅在存储方面是一个糟糕的选择 因为int需要4 bytes and bigint需要8 bytes 但也与性能有关 所以我创建了一个小表1000万条目 其中
  • 如何实现具有LinkedHashMap类似功能的ConcurrentHashMap?

    我用过LinkedHashMap with accessOrdertrue 并同时允许最多 500 个条目作为数据的 LRU 缓存 但由于可扩展性问题 我想转向一些线程安全的替代方案 ConcurrentHashMap在这方面似乎不错 但缺

随机推荐

  • AssertionError:视图函数映射正在覆盖现有端点函数

    我不知道如何解决使用 Flask 时从 Python 代码中得到的这个问题 app route addEvent methods POST def addEvent app route deleteEvent methods POST de
  • 使用 R 中的 ggplot2 绘制带有单独椭圆的散点图中的点

    My dataset is formed by 4 columns as shown below 左边两列代表地理结构的坐标XY 左边两列代表 每个 地理单元的大小 南北直径和东西直径 我想以图形方式表示一个散点图 在其中绘制所有坐标并在每
  • vuejs3 I18n 和组合 API

    我现在正在 vueJS 中做一个前端界面 并且目前正在使用 vuejs 3 和 i18n i18n 的实现按正常方式工作得很好 但是当我想将它与组合 API 一起使用时 就会出现问题 所以我做了什么 我的 main js 看起来像这样 co
  • 图解分析器 - 如何将手臂添加到我的流程图中?

    对于我的流程图 我有一个详细说明数据流的垂直图表 然而 在向下的箭头上 我想添加侧箭头来描述丢失的数据的去向 我该怎么做呢 我在任何文档和示例中都看不到它 因为它往往涉及更复杂的事情 而且我知道这是一项非常基本的任务 library Dia
  • Maven循环依赖

    我有一个模块化的 Maven 项目 其中两个模块 BIZ 和 EJB 包含如下内容 PART OF BIZ Module public interface MyInterface public void foo public class I
  • 将参数传递给 JDBCPreparedStatement

    我正在尝试为我的程序制作验证类 我已经建立了与 MySQL 数据库的连接 并且已经将行插入到表中 该表包括firstName lastName and userID字段 现在我想通过构造函数的参数选择数据库中的特定行 import java
  • Swift 泛型函数无法将类型的值转换为预期的参数类型

    我尝试创建通用函数 func importArray
  • Pandas groupby 值与 bin

    这似乎是一个简单的问题 但我需要你的帮助 例如 我有 df x 1 2 3 4 5 6 7 8 9 10 y 2 1 3 1 8 9 6 7 4 6 如何将 x 在 1 到 5 和 6 到 10 的范围内分组 并计算这两个 bin 的平均值
  • JFreeChart:使用 java.time.LocalDate 或 java.time.LocalDateTime 创建图表

    java util Date非常容易出错 它死了 长命java time Given a Map
  • ASP.NET MVC4,视图将旧值返回到控制器

    我是 MVC 和 ASP NET 的新手 我的要求是 我必须第一次在我的视图中显示两条记录 并且我的视图包含一个 交换 按钮 当我按下此按钮时 应该执行控制器的后操作 并且它必须采用原始视图模型 并且需要交换两个记录并且应该呈现相同的视图
  • 在 url 中使用 # 打开模式

    我对这个可能是愚蠢的问题感到抱歉 但我想简单地在 url 中使用 打开模态 因此 如果我调用 www domain com modal1 它将打开已经弹出模式的页面 哦 我正在使用jquery 谢谢你 许多应用程序框架 我偏向backbon
  • 从一组观察结果创建队列式数据框[重复]

    这个问题在这里已经有答案了 我是 R 新手 有一个简单的问题 因为我仍在学习 R 数据操作 管理的风格 我有一段时间内基本临床特征 血压 胆固醇等 观察数据集 每个观察结果都有患者 ID 和日期 但作为单独的行项目输入 像这样的事情 Pat
  • VBA 查找和替换

    我正在使用 Excel VBA 从电子表格生成 Word 文档 作为最后一步的一部分 我想找到所有双段落并将其替换为单段落 基本代码 Dim objWord Dim objDoc Dim objSelection Set objWord C
  • 表视图中的单元格没有响应

    我正在开发一个待办事项列表应用程序 每当我在simulator并尝试打印我的项目array 其他单元格项目被打印 这是我的代码 import UIKit class TodoListViewController UITableViewCon
  • 递归时变量意外更改?

    Context 我目前正在尝试 Reddit 的 r 每日程序员挑战 这个想法是找到 ASCII 迷宫的解决方案 不幸的是 递归的工作方式与我的预期不同 程序检查是否有空间可以移动到当前空间的右侧 左侧 下方或上方 如果存在 则将空间移动到
  • Android 中平板电脑的布局

    我想在 Android 中为平板电脑和手机创建不同的布局 我应该将布局资源放在哪里才能实现这种差异化 我知道这是一个老问题 但为了它 根据文档 您应该像这样创建多个资产文件夹 res layout main activity xml For
  • 如何提高数据严重偏差的养猪工作的绩效?

    我正在运行一个 Pig 脚本 该脚本执行 GROUP BY 和嵌套 FOREACH 由于一两个减少任务 该脚本需要几个小时才能运行 例如 B GROUP A BY fld1 fld2 parallel 50 C FOREACH B U A
  • 像蜗牛一样在路径上进行 SVG 动画

    I have the following SVG and I would like to draw the circles pixel by pixel on the path after moveing It s like when th
  • 使用 JQuery 和 AJAX 刷新 div 以显示 Django 中的新评级

    我是 django 的新手 找不到仅刷新 div 的方法 并且 div 显示了当前的星级评级 我的想法是 用户可以通过单击星星来查看平均评分并对某些内容进行评分 点击后我希望星星显示新的平均评分 而无需刷新整个页面 这是div div di
  • 如何编写最能利用 CPU 缓存来提高性能的代码?

    这听起来像是一个主观问题 但我正在寻找的是特定的实例 您可能遇到过与此相关的实例 如何使代码 缓存有效 缓存友好 更多的缓存命中 尽可能少的缓存未命中 从两个角度来看 数据缓存 程序缓存 指令缓存 即代码中与数据结构和代码构造相关的哪些内容