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

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

相关文章

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程序四、

ShardingSphere之读写分离方式

《ShardingSphere之读写分离方式》:本文主要介绍ShardingSphere之读写分离方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录ShardingSphere-读写分离读写分离mysql主从集群创建 user 表主节点执行见表语句项目代码读写分

无法启动此程序因为计算机丢失api-ms-win-core-path-l1-1-0.dll修复方案

《无法启动此程序因为计算机丢失api-ms-win-core-path-l1-1-0.dll修复方案》:本文主要介绍了无法启动此程序,详细内容请阅读本文,希望能对你有所帮助... 在计算机使用过程中,我们经常会遇到一些错误提示,其中之一就是"api-ms-win-core-path-l1-1-0.dll丢失

spring security 超详细使用教程及如何接入springboot、前后端分离

《springsecurity超详细使用教程及如何接入springboot、前后端分离》SpringSecurity是一个强大且可扩展的框架,用于保护Java应用程序,尤其是基于Spring的应用... 目录1、准备工作1.1 引入依赖1.2 用户认证的配置1.3 基本的配置1.4 常用配置2、加密1. 密

SpringBoot后端实现小程序微信登录功能实现

《SpringBoot后端实现小程序微信登录功能实现》微信小程序登录是开发者通过微信提供的身份验证机制,获取用户唯一标识(openid)和会话密钥(session_key)的过程,这篇文章给大家介绍S... 目录SpringBoot实现微信小程序登录简介SpringBoot后端实现微信登录SpringBoo

uniapp小程序中实现无缝衔接滚动效果代码示例

《uniapp小程序中实现无缝衔接滚动效果代码示例》:本文主要介绍uniapp小程序中实现无缝衔接滚动效果的相关资料,该方法可以实现滚动内容中字的不同的颜色更改,并且可以根据需要进行艺术化更改和自... 组件滚动通知只能实现简单的滚动效果,不能实现滚动内容中的字进行不同颜色的更改,下面实现一个无缝衔接的滚动

Java使用WebView实现桌面程序的技术指南

《Java使用WebView实现桌面程序的技术指南》在现代软件开发中,许多应用需要在桌面程序中嵌入Web页面,例如,你可能需要在Java桌面应用中嵌入一部分Web前端,或者加载一个HTML5界面以增强... 目录1、简述2、WebView 特点3、搭建 WebView 示例3.1 添加 JavaFX 依赖3