为什么要做字节对齐 alignment?
下面这段 C++ 代码的输出是什么?定义的 Type 占用的字节数(下面简称为字节数)是多少呢?
#include <iostream>struct Type {char a;int b;
};int main(void) {std::cout << sizeof(Type) << '\n';
}
经过编译运行,在 x86-64 Linux 机器上输出的结果是 8。如果将成员变量的字节数相加求和,等于 1 + 4 = 5 字节。那多出来的 3 字节做什么了?
一般,我们会把多出的 3 字节用来做字节对齐。也就引出了文章标题提出的问题:为什么要做字节对齐呢?多占用的字节有什么用处?
首先,程序加载进内存后,需要将指令、数据读取到 CPU 中;CPU 读取数据的速度要远远超过内存的。为了缓解速度差异,引入了 Cache 机制。
而在读写 Cache 中的数据时,一般都是按照一定大小来操作的,这个概念被称为 “Cache line”。在因特尔芯片中,一次操作的大小是 64 个字节。假如现在类型 Type 的对象存储在 Cache 的地址分别为 [60, 61, 62, 63, 64]。如果现在 CPU 去读这个对象,你会发现,它正好分布在两个 Cache line 中(分别是 [0,63] 和 [64, 127]),因此要读两次。
为了尽可能让每次操作都能够访问到完成的数据,而不是分两次进行。编程语言都会引入字节对齐 Alignment 机制(也与 C++ 的处理机制差不多):
-
首先,设定每一个基础类型的 alignment 大小,都是 2 的幂。C++ 在 x86-64 Linux 机器上的 alignment 情况如下表(可以通过 alignof(Type) 函数查看):
类型 sizeof(Type) alignof(Type) char (unsigned char) 1 1 short (unsigned short) 2 2 int (unsigned int) 4 4 long (unsigned long) 8 8 float 4 4 double 8 8 long double 16 16 T* 8 8 -
要求某一类型的第一个字节的地址能被 alignment 整除。也就是说,存放
int值的地址必须是 4 的倍数。 -
如果是用户自定义类型,比如文章开头的 struct,它的 alignment 等于 max(所有成员变量的 alignment),也就是 int 类型的 4。
-
并且要求 sizeof(Type) 必须是 alignof(Type) 的倍数。
以 Type 为例,它的成员变量占用字节和为 5,不是 4 的倍数,所以要在 a 后面填充 3 个 byte 空闲字节,将 Type 字节数扩充为 8。你会发现 [8n, 8n+1,…, 8n+7] 总是会在一个 Cache line 里。
看到这有的朋友可能会问,这个真的一定会确保对象都在一个 Cache line 里吗?
答案是不能,比如将 Type 改写为下面的形式:
struct Type {char a;int b;int c;
};
首先,通过上面的讲解大家应该都能知道现在 sizeof(Type) == 12,但是 64 不能被 12 整除,也就无法保证对象一定在一次 Cache line 里。
也就是说,字节对齐只是尽可能减少对象需要 Cache line 的统计学次数。
关于不同字节数大小的类型,需要的访问 Cache line 预计次数,可以参考这篇文章。你会发现 9 和 12 字节的预计次数竟然是一样的!
总结
- 字节对齐的目的是尽可能减少对象需要 Cache line 的统计学次数。
- 而且,多占用的字节,无法直接访问。
相关文章:
为什么要做字节对齐 alignment?
下面这段 C 代码的输出是什么?定义的 Type 占用的字节数(下面简称为字节数)是多少呢? #include <iostream>struct Type {char a;int b; };int main(void) {std::cout << sizeof(Type) << \n; }经过编译运行&am…...
(零基础学习)Neo4j+Spring boot 自行定义属性
前置知识 1.Neo4j :属性 节点和关系都可以设置自己的属性。 属性是由Key-Value键值对组成,键名是字符串。属性值是要么是原始值,要么是原始值类型的一个数组。比如String,int和iint[]都是合法的。 注意 null不是一个合法的属性值。 Nulls能…...
【JavaEE】Java的文件IO
文件IO操作 Linux 下的文件操作讲解Java中的文件操作 -- 对文件的增删改查Java中对文件内容的操作 -- 读写操作使用案例 Linux 下的文件操作讲解 在我的Linux栏目下有, 如有需要, 点击下面进行跳转: 内存级文件系统语言级别的文教操作磁盘文件 Java中的文件操作 – 对文件的…...
域名解析与记录
域名解析是将域名转换为IP的过程,使得人们能够直接通过域名访问网站,而不用记繁琐的IP地址信息。而在域名解析中,CNAME记录和A记录是两个不同的记录类型。 A记录(Address Record,地址记录)是指将一个域名解…...
Android 13.0 第三方无源码apk授予QUERY_ALL_PACKAGES等其他权限的方法
1.概述 在13.0的系统产品中,对于内置第三方低版本app时,会有某些权限的冲突,导致在启动app时,崩溃掉,在查询相关日志发现是报权限的问题,所以就需要在安装解析app的时候,授予权限 2.第三方无源码apk授予QUERY_ALL_PACKAGES等其他权限的方法的核心类 /frameworks/base…...
【CSS】gird 网格
网格(Grid)是一种基于列数的布局系统,它可以帮助开发者创建具有水平和垂直分隔的页面布局。在CSS中,Grid是一种非常强大的布局工具,可以轻松地创建复杂的布局结构。Grid的主要属性包括: grid-template-col…...
(未完待续)【Netty专题】Netty实战与核心组件详解
目录 前言阅读对象阅读导航前置知识课程内容一、Netty简介1.1 Netty是什么1.2 Netty有什么优势 二、第一个Netty程序2.1 Netty简单使用示例2.2 代码解读2.3 Netty的特性2.3.1 Netty的事件 2.4 Netty线程模型 三、Netty核心组件详解(未完待续)3.1 EventLo…...
“第四十五天” 数据结构基本概念
目前看的有关数据结构的课,估计这周就看完了,但感觉差很多,还是和c一样,这样过一下吧。但可能比较急,目前是打算争取寒假回家之前把四大件都先大致过一遍。 数据结构里面有很多新的定义和概念,学到现在&am…...
《java 桌面软件开发》swing 以鼠标为中心放大缩小移动图片
swing 使用Graphic2D 绘制图片,要实现对图片进行缩放和自由拖动。 1.以鼠标所在的位置为中心,滚轮控制缩放 2.缩放后再支持鼠标拖动。 基本原理: 利用scale() 函数。进行缩放。但是要注意的地方是,如果是在 public void paintCom…...
浅析人脸活体检测技术的功能及几种分类
在日常生活工作中,出现了人脸验证、人脸支付、人脸乘梯、人脸门禁等等常见的应用场景。这说明人脸识别技术已经在门禁安防、金融行业、教育医疗等领域被广泛地应用,人脸识别技术的高速发展与应用同时也出现不少质疑。其中之一就是人脸识别很容易被照片、…...
【Java基础面试三十五】、谈谈你对面向接口编程的理解
文章底部有个人公众号:热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享? 踩过的坑没必要让别人在再踩,自己复盘也能加深记忆。利己利人、所谓双赢。 面试官:谈谈你对面向接口编程的…...
利用TreeMap来达成离散化的目的
假如有一些奶牛,他们有种类的区别,我们设黑色奶牛的id为1000010000,白色为1,诸如此类以此类推还有红色等各种颜色,接下来给你一群奶牛的颜色id让你统计每种颜色的奶牛有几头。 如过我们使用数组显然1000010000会爆空间…...
PG14安装_rpm方式
一、前期准备 发现生产环境有用rpm安装,故整理安装rpm安装步骤,目的是准备walminer恢复数据用的环境 二、安装包下载 https://download.postgresql.org/pub/repos/yum/ 含多个版本 https://download.postgresql.org/pub/repos/yum/14/redhat/rhel-7-x…...
水管安装过滤器笔记
文章目录 方案准备工具剪管钳热熔器软管接头及单向阀扳手 操作过程花洒 搬家后,水质不行,洗脸掉皮,洗头以前不掉头皮屑的,居然也掉头皮屑。有必要简单过滤下了。 水质情况,并不是脏脏的的那种水,看上去还比…...
【Objective-C】浅析Block及其捕获机制
目录 Block的基本使用Block的声明Block的实现Block的调用 Block作为形参使用Block作为属性使用给Block起别名Block的copy Block的捕获机制auto类型的局部变量__block浅析static类型的局部变量全局变量 其他问题 Block的基本使用 什么是Block? Block (块…...
GitHub和Gitee的区别以及具体使用
文章目录 GitHub和GiteeGitHub和Gitee区别GitHub的使用Gitee的使用 GitHub和Gitee GitHub和Gitee区别 速度不同:GitHub位于美国,而Gitee位于中国。这意味着在中国使用Gitee可能会有更快的访问速度和更好的稳定性。如果我们希望体验Git飞一般的速度&…...
使用Redis实现分布式锁解决商品超卖问题(接上篇文章)
1. RedLock(红锁)简介 RedLock是一种用于分布式系统的锁定算法,旨在提供分布式锁的高可用性和分布式容错性。它是由Redis的创建者Salvatore Sanfilippo提出的,用于克服Redis单实例的单点故障问题。RedLock的目标是确保在多个Redis…...
2001-2022年全国290+个地级市高铁开通数据
2001-2022年全国290个地级市高铁开通数据 1、时间:2001-2022年 2、范围:298地级市(293地级市数(其中莱芜市2019年撤市设区)4直辖市数 ) 3、来源:国家铁路局、铁路客货运输专刊及相关统计 国…...
【Java 进阶篇】深入浅出:Bootstrap 轮播图
在现代网页设计中,轮播图是一个常见的元素。它们可以用于展示图片、广告、新闻、产品或任何您希望吸引用户注意力的内容。要实现一个轮播图,您通常需要一些复杂的HTML、CSS和JavaScript代码,这对于初学者来说可能会感到困难。但幸运的是&…...
75. 颜色分类
75. 颜色分类 双指针——快慢指针 class Solution {public void sortColors(int[] nums) {int n nums.length;int p0 0;for(int i 0; i < n; i){if(nums[i] 0){swap(nums, p0, i);p0;}}int p1 p0;for(int i p0; i < n; i){if(nums[i] 1){swap(nums, p1, i);p1;}…...
照片拍歪了怎么扶正?2026年3招免费搞定!
周末出去玩,拍了一堆美美的照片,回来翻相册一看,血压瞬间上来了——地平面是斜的,塔是歪的,朋友的脑袋差点“出画”了。更气人的是,那张拍得最好看的合影,构图、表情、光线全对,偏偏…...
用GEE和Sentinel-5P数据,5分钟搞定城市空气质量变化趋势分析(以NO2、O3为例)
城市空气质量动态监测:基于GEE与Sentinel-5P的高效分析实战 清晨打开天气预报APP时,那些跳动的空气质量指数背后,其实隐藏着卫星每天扫描地球大气层产生的海量数据。作为环境研究者,我们完全可以通过Google Earth Engineÿ…...
Proteus 8.13 保姆级教程:从零开始用Arduino UNO模板创建你的第一个仿真项目
Proteus 8.13 零基础实战指南:Arduino UNO仿真项目全流程解析 引言:为什么选择Proteus进行Arduino仿真? 对于电子设计爱好者而言,硬件投入成本常常成为学习路上的第一道门槛。一块Arduino UNO开发板虽然价格亲民,但当需…...
Rescuezilla终极指南:简单快速的免费系统恢复与磁盘克隆工具
Rescuezilla终极指南:简单快速的免费系统恢复与磁盘克隆工具 【免费下载链接】rescuezilla The Swiss Army Knife of System Recovery 项目地址: https://gitcode.com/gh_mirrors/re/rescuezilla 当你的电脑系统崩溃、硬盘故障或需要升级存储设备时ÿ…...
Unity shader中TransformWorldToShadowCoord原理解析
TransformWorldToShadowCoord 的核心作用很简单:将你提供的世界坐标,转换到一个可以用于采样 Shadow Map 的坐标空间。它本质上是为你省去了手动编写矩阵乘法的繁琐步骤。🔍 核心原理:一个“三步走”的幕后过程函数内部主要执行了…...
OpenGL渲染与几何内核那点事-项目实践理论补充(一-3-(6):从“搬砖”到“无人仓”:一个CAD极客的OpenGL性能压榨史,连AI都看呆了——给图形学新手的VBO/VAO全攻略)
TOC 代码仓库入口: github源码地址。gitee源码地址。 系列文章规划: OpenGL渲染与几何内核那点事-项目实践理论补充(一-1-(8)-番外篇:当你的 CAD 遇上“活”的零件)OpenGL渲染与几何内核那点事-项目实践理论补充(一-2-(1)-当你的CAD想“联…...
如何快速掌握几何无衬线字体:开源字体完全指南
如何快速掌握几何无衬线字体:开源字体完全指南 【免费下载链接】Outfit-Fonts The most on-brand typeface 项目地址: https://gitcode.com/gh_mirrors/ou/Outfit-Fonts Outfit字体是一款专业的几何无衬线开源字体,专为品牌设计自动化而生。它提供…...
欧姆龙CP系列项目级PLC程序模板:即拿即用,地址分配明确,逻辑已验证
欧姆龙PLC程序 欧姆龙CP系列项目级PLC程序模板,拿过来可以直接做项目,逻辑关系很多项目验证过,只需要加进去工艺流程即可,各地址分配明确;有专用的CP系列地址分配表做参考;对欧姆龙PLC学习和提高有很大的帮…...
失业ing零零碎碎记一下unity相关的东西备忘
零零碎碎记一下unity相关的东西备忘 渲染: https://github.com/festivities/PrimoToon 仿原神的卡通渲染, 参照这种文档: Unity Built-in Shader转URP Shader 接口查询对照表之类的 自己强行改api到urp可用,改了三四天&…...
如何5分钟上手VOICEVOX:免费日语语音合成终极指南
如何5分钟上手VOICEVOX:免费日语语音合成终极指南 【免费下载链接】voicevox 無料で使える中品質なテキスト読み上げソフトウェア、VOICEVOXのエディター 项目地址: https://gitcode.com/gh_mirrors/vo/voicevox VOICEVOX是一款完全免费开源的日语语音合成软…...
