宋宝华:深入理解cache对写好代码至关重要

原创 Linux阅码场 2021-07-07 17:43
 

There are only two hard things in Computer Science: cache invalidation and naming things.

-- Phil Karlton

全文目录

CACHE基础

CACHE的组织

      TAG,INDEX

      VIVT,VIPT,PIPT

      Cache别名问题

CACHE一致性

      icache、dcache同步

      多CPU核cache同步

      CPU与设备cache同步

意识到CACHE的编程

      cache预取

      false sharing处理

     perf及topdown分析


CACHE基础

cache的掌握,对于Linux工程师(其他的非Linux工程师也一样)写出高效能代码,以及优化Linux系统的性能是至关重要的。简单来说,cache快,内存慢,硬盘更慢。在一个典型的现代CPU中比较接近改进的哈佛结构,cache的排布大概是这样的:


L1速度>  L2速度> L3速度> RAM

L1容量<  L2容量< L3容量< RAM

现代CPU,通常L1 cache的指令和数据是分离的。这样可以实现2条高速公路并行访问,CPU可以同时load指令和数据。当然,cache也不一定是一个core独享,现代很多CPU的典型分布是这样的,比如多个core共享一个L3。比如这台的Linux里面运行lstopo命令:

人们也常常称呼L2cacheMLCMiddleLevel Cache,L3cacheLLCLast LevelCache。这些Cache究竟有多块呢?我们来看看Intel的数据,具体配置:Intel i7-4770 (Haswell), 3.4 GHz (Turbo Boostoff), 22 nm. RAM: 32 GB (PC3-12800 cl11 cr2)

访问延迟

数据来源:https://www.7-cpu.com/cpu/Haswell.html

由此我们可以知道,我们应该尽可能追求cache的命中率高,以避免延迟,最好是低级cache的命中率越高越好。

CACHE的组织

现代的cache基本按照这个模式来组织:SETWAYTAGINDEX,这几个概念是理解Cache的关键。随便打开一个数据手册,就可以看到这样的字眼:

翻译成中文就是4路(way)组(set)相联,VIPT表现为(behave as)PIPT --这尼玛什么鬼?cacheline的长度是64字节。

下面我们来想象一个16KB大小的cache,假设是4路组相联,cacheline的长度是64字节。Cacheline的概念比较简单,cache的整个替换是以行为单位的,一行64个字节里面读了任何一个字节,其实整个64字节就进入了cache

比如下面两段程序,前者的计算量是后者的8倍:

但是它的执行时间,则远远不到后者的8倍:


16KBcache4way的话,每个set包括4*64B,则整个cache分为16KB/64B/4 = 64set,也即26次方。当CPUcache里面读数据的时候,它会用地址位的BIT6-BIT11来寻址setBIT0-BIT5cacheline内的offset

比如CPU访问地址

0 000000 XXXXXX

或者

1 000000 XXXXXX

或者

YYYY 000000 XXXXXX

由于它们红色的6位都相同,所以他们全部都会找到第0setcacheline。第0set里面有4way,之后硬件会用地址的高位如0,1YYYY作为tag,去检索这4waytag是否与地址的高位相同,而且cacheline是否有效,如果tag匹配且cacheline有效,则cache命中。

所以地址YYYYYY000000XXXXXX全部都是找第0setYYYYYY000001XXXXXX全部都是找第1setYYYYYY111111XXXXXX全部都是找第63set。每个set中的4way,都有可能命中。

中间红色的位就是INDEX,前面YYYY这些位就是TAG。具体的实现可以是用虚拟地址或者物理地址的相应位做TAG或者INDEX。如果用虚拟地址做TAG,我们叫VT;如果用物理地址做TAG,我们叫PT;如果用虚拟地址做INDEX,我们叫VI;如果用物理地址做TAG,我们叫PT。工程中碰到的cache可能有这么些组合:

VIVTVIPTPIPT

VIVT的硬件实现开销最低,但是软件维护成本高;PIPT的硬件实现开销最高,但是软件维护成本最低;VIPT介于二者之间,但是有些硬件是VIPT,但是behave as PIPT,这样对软件而言,维护成本与PIPT一样。

VIVT的情况下,CPU发出的虚拟地址,不需要经过MMU的转化,直接就可以去查cache

而在VIPTPIPT的场景下,都涉及到虚拟地址转换为物理地址后,再去比对cache的过程。VIPT如下:

PIPT如下:

从图上看起来,VIVT的硬件实现效率很高,不需要经过MMU就可以去查cache了。不过,对软件来说,这是个灾难。因为VIVT有严重的歧义和别名问题。

歧义:一个虚拟地址先后指向两个(或者多个)物理地址

别名:两个(或者多个)虚拟地址同时指向一个物理地址

这里我们重点看别名问题。比如2个虚拟地址对应同一个物理地址,基于VIVT的逻辑,无论是INDEX还是TAG2个虚拟地址都是可能不一样的(尽管他们的物理地址一样,但是物理地址在cache比对中完全不掺和),这样它们完全可能在2cacheline同时命中。

由于2个虚拟地址指向1个物理地址,这样CPU写过第一个虚拟地址后,写入cacheline1CPU读第2个虚拟地址,读到的是过时的cacheline2,这样就出现了不一致。所以,为了避免这种情况,软件必须写完虚拟地址1后,对虚拟地址1对应的cache执行clean,对虚拟地址2对应的cache执行invalidate

PIPT完全没有这样的问题,因为无论多少虚拟地址对应一个物理地址,由于物理地址一样,我们是基于物理地址去寻找和比对cache的,所以不可能出现这种别名问题。

那么VIPT有没有可能出现别名呢?答案是有可能,也有可能不能。如果VI恰好对于PI,就不可能,这个时候,VIPT对软件而言就是PIPT了:

VI=PI

PT=PT

那么什么时候VI会等于PI呢?这个时候我们来回忆下虚拟地址往物理地址的转换过程,它是以页为单位的。假设一页是4K,那么地址的低12位虚拟地址和物理地址是完全一样的。回忆我们前面的地址:

YYYYY000000XXXXXX

其中红色的000000INDEX。在我们的例子中,红色的6位和后面的XXXXXXcache内部偏移)加起来正好12位,所以这个000000经过虚实转换后,其实还是000000的,这个时候VI=PIVIPT没有别名问题。

我们原先假设的cache是:16KB大小的cache,假设是4路组相联,cacheline的长度是64字节,这样我们正好需要红色的6位来作为INDEX。但是如果我们把cache的大小增加为32KB,这样我们需要  32KB/4/64B=128=2^7,也即7位来做INDEX

YYYY0000000XXXXXX

这样VI就可能不等于PI了,因为红色的最高位超过了2^12的范围,完全可能出现如下2个虚拟地址,指向同一个物理地址:

这样就出现了别名问题,我们在工程里,可能可以通过一些办法避免这种别名问题,比如软件在建立虚实转换的时候,把虚实转换往2^13而不是2^12对齐,让物理地址的低13位而不是低12位与物理地址相同,这样强行绕开别名问题,下图中,2个虚拟地址指向了同一个物理地址,但是它们的INDEX是相同的,这样VI=PI,就绕开了别名问题。这通常是PAGE COLOURING技术中的一种技巧。

如果这种PAGE COLOURING的限制对软件仍然不可接受,而我们又想享受VIPTINDEX不需要经过MMU虚实转换的快捷?有没有什么硬件技术来解决VIPT别名问题呢?确实是存在的,现代CPU很多都是把L1 CACHE做成VIPT,但是表现地(behave as)像PIPT。这是怎么做到的呢?

这要求VIPTcache,硬件上具备alias detection的能力。比如,硬件知道YYYY0000000XXXXXX既有可能出现在第0000000,又可能出现在10000002set,然后硬件自动去比对这2set里面是否出现映射到相同物理地址的cacheline,并从硬件上解决好别名同步,那么软件就完全不用操心了。

下面我们记住一个简单的规则:

对于VIPT,如果cachesize除以WAY数,小于等于1page的大小,则天然VI=PI,无别名问题;

对于VIPT,如果cachesize除以WAY数,大于1page的大小,则天然VIPI,有别名问题;这个时候又分成2种情况:

  • 硬件不具备alias detection能力,软件需要pagecolouring

  • 硬件具备alias detection能力,软件把cache当成PIPT用。

比如cache大小64KB4WAYPAGE SIZE4K,显然有别名问题;这个时候,如果cache改为16WAY,或者PAGE SIZE改为16K,不再有别名问题。为什么?感觉小学数学知识也能算得清

Linux阅码场 专业的Linux技术社区和Linux操作系统学习平台,内容涉及Linux内核,Linux内存管理,Linux进程管理,Linux文件系统和IO,Linux性能调优,Linux设备驱动以及Linux虚拟化和云计算等各方各面.
评论
  • 故障现象 一辆2007款日产天籁车,搭载VQ23发动机(气缸编号如图1所示,点火顺序为1-2-3-4-5-6),累计行驶里程约为21万km。车主反映,该车起步加速时偶尔抖动,且行驶中加速无力。 图1 VQ23发动机的气缸编号 故障诊断接车后试车,发动机怠速运转平稳,但只要换挡起步,稍微踩下一点加速踏板,就能感觉到车身明显抖动。用故障检测仪检测,发动机控制模块(ECM)无故障代码存储,且无失火数据流。用虹科Pico汽车示波器测量气缸1点火信号(COP点火信号)和曲轴位置传感器信
    虹科Pico汽车示波器 2025-01-23 10:46 80浏览
  • 现在为止,我们已经完成了Purple Pi OH主板的串口调试和部分配件的连接,接下来,让我们趁热打铁,完成剩余配件的连接!注:配件连接前请断开主板所有供电,避免敏感电路损坏!1.1 耳机接口主板有一路OTMP 标准四节耳机座J6,具备进行音频输出及录音功能,接入耳机后声音将优先从耳机输出,如下图所示:1.21.2 相机接口MIPI CSI 接口如上图所示,支持OV5648 和OV8858 摄像头模组。接入摄像头模组后,使用系统相机软件打开相机拍照和录像,如下图所示:1.3 以太网接口主板有一路
    Industio_触觉智能 2025-01-20 11:04 195浏览
  • 临近春节,各方社交及应酬也变得多起来了,甚至一月份就排满了各式约见。有的是关系好的专业朋友的周末“恳谈会”,基本是关于2025年经济预判的话题,以及如何稳定工作等话题;但更多的预约是来自几个客户老板及副总裁们的见面,他们为今年的经济预判与企业发展焦虑而来。在聊天过程中,我发现今年的聊天有个很有意思的“点”,挺多人尤其关心我到底是怎么成长成现在的多领域风格的,还能掌握一些经济趋势的分析能力,到底学过哪些专业、在企业管过哪些具体事情?单单就这个一个月内,我就重复了数次“为什么”,再辅以我上次写的:《
    牛言喵语 2025-01-22 17:10 178浏览
  • 嘿,咱来聊聊RISC-V MCU技术哈。 这RISC-V MCU技术呢,简单来说就是基于一个叫RISC-V的指令集架构做出的微控制器技术。RISC-V这个啊,2010年的时候,是加州大学伯克利分校的研究团队弄出来的,目的就是想搞个新的、开放的指令集架构,能跟上现代计算的需要。到了2015年,专门成立了个RISC-V基金会,让这个架构更标准,也更好地推广开了。这几年啊,这个RISC-V的生态系统发展得可快了,好多公司和机构都加入了RISC-V International,还推出了不少RISC-V
    丙丁先生 2025-01-21 12:10 619浏览
  • Ubuntu20.04默认情况下为root账号自动登录,本文介绍如何取消root账号自动登录,改为通过输入账号密码登录,使用触觉智能EVB3568鸿蒙开发板演示,搭载瑞芯微RK3568,四核A55处理器,主频2.0Ghz,1T算力NPU;支持OpenHarmony5.0及Linux、Android等操作系统,接口丰富,开发评估快人一步!添加新账号1、使用adduser命令来添加新用户,用户名以industio为例,系统会提示设置密码以及其他信息,您可以根据需要填写或跳过,命令如下:root@id
    Industio_触觉智能 2025-01-17 14:14 145浏览
  •  万万没想到!科幻电影中的人形机器人,正在一步步走进我们人类的日常生活中来了。1月17日,乐聚将第100台全尺寸人形机器人交付北汽越野车,再次吹响了人形机器人疯狂进厂打工的号角。无独有尔,银河通用机器人作为一家成立不到两年时间的创业公司,在短短一年多时间内推出革命性的第一代产品Galbot G1,这是一款轮式、双臂、身体可折叠的人形机器人,得到了美团战投、经纬创投、IDG资本等众多投资方的认可。作为一家成立仅仅只有两年多时间的企业,智元机器人也把机器人从梦想带进了现实。2024年8月1
    刘旷 2025-01-21 11:15 666浏览
  • 高速先生成员--黄刚这不马上就要过年了嘛,高速先生就不打算给大家上难度了,整一篇简单但很实用的文章给大伙瞧瞧好了。相信这个标题一出来,尤其对于PCB设计工程师来说,心就立马凉了半截。他们辛辛苦苦进行PCB的过孔设计,高速先生居然说设计多大的过孔他们不关心!另外估计这时候就跳出很多“挑刺”的粉丝了哈,因为翻看很多以往的文章,高速先生都表达了过孔孔径对高速性能的影响是很大的哦!咋滴,今天居然说孔径不关心了?别,别急哈,听高速先生在这篇文章中娓娓道来。首先还是要对各位设计工程师的设计表示肯定,毕竟像我
    一博科技 2025-01-21 16:17 159浏览
  • 飞凌嵌入式基于瑞芯微RK3562系列处理器打造的FET3562J-C全国产核心板,是一款专为工业自动化及消费类电子设备设计的产品,凭借其强大的功能和灵活性,自上市以来得到了各行业客户的广泛关注。本文将详细介绍如何启动并测试RK3562J处理器的MCU,通过实际操作步骤,帮助各位工程师朋友更好地了解这款芯片。1、RK3562J处理器概述RK3562J处理器采用了4*Cortex-A53@1.8GHz+Cortex-M0@200MHz架构。其中,4个Cortex-A53核心作为主要核心,负责处理复杂
    飞凌嵌入式 2025-01-24 11:21 37浏览
  •     IPC-2581是基于ODB++标准、结合PCB行业特点而指定的PCB加工文件规范。    IPC-2581旨在替代CAM350格式,成为PCB加工行业的新的工业规范。    有一些免费软件,可以查看(不可修改)IPC-2581数据文件。这些软件典型用途是工艺校核。    1. Vu2581        出品:Downstream     
    电子知识打边炉 2025-01-22 11:12 134浏览
  • 2024年是很平淡的一年,能保住饭碗就是万幸了,公司业绩不好,跳槽又不敢跳,还有一个原因就是老板对我们这些员工还是很好的,碍于人情也不能在公司困难时去雪上加霜。在工作其间遇到的大问题没有,小问题还是有不少,这里就举一两个来说一下。第一个就是,先看下下面的这个封装,你能猜出它的引脚间距是多少吗?这种排线座比较常规的是0.6mm间距(即排线是0.3mm间距)的,而这个规格也是我们用得最多的,所以我们按惯性思维来看的话,就会认为这个座子就是0.6mm间距的,这样往往就不会去细看规格书了,所以这次的运气
    wuliangu 2025-01-21 00:15 324浏览
  • 数字隔离芯片是一种实现电气隔离功能的集成电路,在工业自动化、汽车电子、光伏储能与电力通信等领域的电气系统中发挥着至关重要的作用。其不仅可令高、低压系统之间相互独立,提高低压系统的抗干扰能力,同时还可确保高、低压系统之间的安全交互,使系统稳定工作,并避免操作者遭受来自高压系统的电击伤害。典型数字隔离芯片的简化原理图值得一提的是,数字隔离芯片历经多年发展,其应用范围已十分广泛,凡涉及到在高、低压系统之间进行信号传输的场景中基本都需要应用到此种芯片。那么,电气工程师在进行电路设计时到底该如何评估选择一
    华普微HOPERF 2025-01-20 16:50 123浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦