冷热字段分离提升程序局部性

2023-12-17 19:15

本文主要是介绍冷热字段分离提升程序局部性,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

突然想起了上学期课堂上的一个提升程序局部性的案例,我觉得非常有意思,写篇博客记录一下。

1 场景

案例场景非常简单,就是遍历访问大结构体数组的某一字段。对应到下图,funcA要访问a[N]的fld3字段,funcB中要访问b[N]的fld5字段。

在这个场景中,程序要访问的结构体数组很大(单个结构体要占用600B内存),然而,要访问的字段却很小,大约1B-4B。总结来说,就是,大结构体数组,按行存储,按列访问。

这段程序的问题是,超过90%进入cache的数据不会被利用。在当前主流架构下,cache line的大小是64B,一次加载的粒度自然也是64B。那么,在这种场景下,缓存到cache的绝大部分数据是无效数据。一方面,这会对程序没有发挥出最好的性能;另一方面,无效的数据移动会带来很大的能量消耗,在嵌入式场景下,application对能耗还是很敏感的。

2 改进

其实,要解决这个问题,思路很简单,就是要把结构体数组中的热字段放在一块,冷字段放在一块。这样的话,cache命中率自然就提升上去了。

2.1 手工调整数据结构

这种方法简单粗暴,理论上没啥问题,就是有点费程序猿。具体来讲,有两种方法。

2.1.1 方法1

这种方法是在结构体内存调整字段顺序,将热字段靠拢放置。就比如,下图struct A中的fld3和fld5是热字段,把两者放在一块就好了。这样一次cache line加载就可以将两个字段同时放入cache。

  • 这种方法存在问题
    • 一个结构体中所有热字段可能不够64B,cache还是会加载很多的无效数据。
    • 结构体中可能会嵌有很多子结构体,不同子结构体的热字段无法并拢。
    • 调整后字段顺序后的代码可读性下降。
2.1.2 方法2

这种方法重构了结构体,将热字段单独成立一个结构体,冷字段成立成另外一个结构体。如下图,struct A被拆分为了struct A hotstruct A cold,这样的话,热字段fld3就可以放在一块了,cache line加载可以最大程度上避免冷数据放入cache。

  • 这种方法存在问题
    • 重构结构体,调整字段顺序,代码可读性大大下降。
    • 源代码改造涉及面广,人工修改工作量巨大,易错。

2.2 自动代码变形

另外一种思路是做自动化工具,也就是做一个编译器,这个编译器自动帮我们进行冷热字段分离,这比手工改的逼格高得多了。具体来讲,也有两种方法。

2.2.1 源到源编译器

这种方法其实就是把手工调整数据结构的方法2进行自动化实现:输入.h\.c源代码文件,输出优化后的.h\.c源代码文件。

  • 这种方法存在问题
    • 源代码中的程序写法千变万化,自动化工具要识别出所有的写法有点不大现实。
2.2.2 IR2IR编译器

这种方法的思路是,既然在源代码层不好做自动化工具,那就考虑改IR,毕竟IR要规整的多。如下图,自动化工具会先运行一遍程序,识别出热字段,然后,在IR层修改,输出优化后的二进制程序。

使用IR2IR编译器优化后的程序,运行时间由6.9ms提升至6.7ms,提速了3%。

这篇关于冷热字段分离提升程序局部性的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

在MySQL中实现冷热数据分离的方法及使用场景底层原理解析

《在MySQL中实现冷热数据分离的方法及使用场景底层原理解析》MySQL冷热数据分离通过分表/分区策略、数据归档和索引优化,将频繁访问的热数据与冷数据分开存储,提升查询效率并降低存储成本,适用于高并发... 目录实现冷热数据分离1. 分表策略2. 使用分区表3. 数据归档与迁移在mysql中实现冷热数据分

golang程序打包成脚本部署到Linux系统方式

《golang程序打包成脚本部署到Linux系统方式》Golang程序通过本地编译(设置GOOS为linux生成无后缀二进制文件),上传至Linux服务器后赋权执行,使用nohup命令实现后台运行,完... 目录本地编译golang程序上传Golang二进制文件到linux服务器总结本地编译Golang程序

PowerShell中15个提升运维效率关键命令实战指南

《PowerShell中15个提升运维效率关键命令实战指南》作为网络安全专业人员的必备技能,PowerShell在系统管理、日志分析、威胁检测和自动化响应方面展现出强大能力,下面我们就来看看15个提升... 目录一、PowerShell在网络安全中的战略价值二、网络安全关键场景命令实战1. 系统安全基线核查

使用Docker构建Python Flask程序的详细教程

《使用Docker构建PythonFlask程序的详细教程》在当今的软件开发领域,容器化技术正变得越来越流行,而Docker无疑是其中的佼佼者,本文我们就来聊聊如何使用Docker构建一个简单的Py... 目录引言一、准备工作二、创建 Flask 应用程序三、创建 dockerfile四、构建 Docker

Knife4j+Axios+Redis前后端分离架构下的 API 管理与会话方案(最新推荐)

《Knife4j+Axios+Redis前后端分离架构下的API管理与会话方案(最新推荐)》本文主要介绍了Swagger与Knife4j的配置要点、前后端对接方法以及分布式Session实现原理,... 目录一、Swagger 与 Knife4j 的深度理解及配置要点Knife4j 配置关键要点1.Spri

MySQL主从复制与读写分离的用法解读

《MySQL主从复制与读写分离的用法解读》:本文主要介绍MySQL主从复制与读写分离的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、主从复制mysql主从复制原理实验案例二、读写分离实验案例安装并配置mycat 软件设置mycat读写分离验证mycat读

python编写朋克风格的天气查询程序

《python编写朋克风格的天气查询程序》这篇文章主要为大家详细介绍了一个基于Python的桌面应用程序,使用了tkinter库来创建图形用户界面并通过requests库调用Open-MeteoAPI... 目录工具介绍工具使用说明python脚本内容如何运行脚本工具介绍这个天气查询工具是一个基于 Pyt

Ubuntu设置程序开机自启动的操作步骤

《Ubuntu设置程序开机自启动的操作步骤》在部署程序到边缘端时,我们总希望可以通电即启动我们写好的程序,本篇博客用以记录如何在ubuntu开机执行某条命令或者某个可执行程序,需要的朋友可以参考下... 目录1、概述2、图形界面设置3、设置为Systemd服务1、概述测试环境:Ubuntu22.04 带图

Python程序打包exe,单文件和多文件方式

《Python程序打包exe,单文件和多文件方式》:本文主要介绍Python程序打包exe,单文件和多文件方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录python 脚本打成exe文件安装Pyinstaller准备一个ico图标打包方式一(适用于文件较少的程

Python程序的文件头部声明小结

《Python程序的文件头部声明小结》在Python文件的顶部声明编码通常是必须的,尤其是在处理非ASCII字符时,下面就来介绍一下两种头部文件声明,具有一定的参考价值,感兴趣的可以了解一下... 目录一、# coding=utf-8二、#!/usr/bin/env python三、运行Python程序四、