【C/C++】ARM处理器对齐_伪共享问题
文章目录
- 1 什么是伪共享?
- 2 为什么对齐?
- 3 伪共享的实际影响
- 4 为什么必须是 64 字节?
- 5 其他替代方案
- 6 验证对齐效果
- 总结
1 什么是伪共享?
伪共享是 多线程编程中的一种性能问题,其本质是:
- 缓存行(Cache Line):现代 CPU 的缓存以固定大小的块(缓存行)为单位管理数据,常见缓存行大小为 64 字节(如 x86/x64 CPU)。
- 共享缓存行:如果两个独立的变量(如
_bottom
和_top
)位于同一个缓存行中,即使它们被不同线程访问(如一个线程写_bottom
,另一个线程读_top
),也会导致缓存行被频繁标记为“无效”(Cache Invalidation)。 - 性能损失:频繁的缓存同步(从 L1/L2 缓存到主存)会显著降低程序性能。
避免伪共享(False Sharing),从而提升多线程程序的性能
2 为什么对齐?
以64字节对齐为例:
通过 alignas(64)
强制变量对齐到 64 字节边界,可以确保:
- 独占缓存行:每个变量(如
_bottom
和_top
)独占一个完整的缓存行(64 字节),避免与其他变量共享。 - 隔离修改:当一个线程修改
_bottom
时,不会触发其他线程中_top
所在缓存行的无效化,反之亦然。
示例内存布局:
// 未对齐时(伪共享)
Cache Line 0: | _bottom (8 bytes) | _top (8 bytes) | ...(剩余 48 字节)|// 对齐到 64 字节后(避免伪共享)
Cache Line 0: | _bottom (8 bytes) | padding (56 bytes) |
Cache Line 1: | _top (8 bytes) | padding (56 bytes) |
在 32 位 ARM 系统中,为了避免伪共享(False Sharing),通常建议的对齐大小为 32 字节或 64 字节,具体取决于目标处理器的缓存行(Cache Line)大小。
- ARM 系统的缓存行大小
32 位 ARM 处理器的缓存行大小因架构和型号而异:
- 较旧 ARMv6/ARMv7 处理器(如 Cortex-A8/A9)通常使用 32 字节 的缓存行。
- 较新 ARMv7/ARMv8 处理器(如 Cortex-A53/A72)可能采用 64 字节 的缓存行(与 x86/x64 对齐)。
具体需查阅目标 CPU 的文档(如 Technical Reference Manual)确认。
- 对齐建议
- 通用保守方案:32 字节对齐
若不确定目标处理器的缓存行大小,可保守对齐到 32 字节(覆盖旧型号的 32 字节缓存行):
alignas(32) std::atomic<size_t> _bottom;
alignas(32) std::atomic<size_t> _top;
- 针对新型号:64 字节对齐
若目标处理器为较新的 ARMv8 或已知缓存行为 64 字节(如部分 Cortex-A 系列),可直接对齐到 64 字节:
alignas(64) std::atomic<size_t> _bottom;
alignas(64) std::atomic<size_t> _top;
- C++17 自适应方案
若支持 C++17,使用std::hardware_destructive_interference_size
自动适配缓存行大小:
#include <new>
alignas(std::hardware_destructive_interference_size) std::atomic<size_t> _bottom;
alignas(std::hardware_destructive_interference_size) std::atomic<size_t> _top;
- 验证对齐效果
通过代码检查变量地址是否为对齐值的整数倍:
#include <iostream>
#include <cstdint>int main() {alignas(32) std::atomic<size_t> _bottom;alignas(32) std::atomic<size_t> _top;// 检查对齐是否成功auto check_alignment = [](const auto& var, size_t alignment) {uintptr_t addr = reinterpret_cast<uintptr_t>(&var);return (addr % alignment == 0) ? "Success" : "Failed";};std::cout << "_bottom 对齐 32: " << check_alignment(_bottom, 32) << "\n";std::cout << "_top 对齐 32: " << check_alignment(_top, 32) << "\n";return 0;
}
- 实际性能对比
场景 | 32 字节缓存行(对齐 32) | 64 字节缓存行(对齐 64) | 未对齐(伪共享) |
---|---|---|---|
线程竞争开销 | 低 | 低(若缓存行为 64) | 高(频繁缓存失效) |
内存占用 | 略高(填充空间) | 更高(填充空间) | 低 |
- 适用场景总结
- 嵌入式/IoT 设备(旧款 ARMv6/v7):优先对齐 32 字节。
- 高性能 ARM 处理器(如 Cortex-A72):对齐 64 字节。
- 跨平台代码:使用 C++17 的
std::hardware_destructive_interference_size
。
在 32 位 ARM 系统中,若无明确缓存行信息,默认对齐到 32 字节是安全选择。
若针对新型处理器或已知缓存行为 64 字节,则对齐到 64 字节。通过合理对齐,可显著减少伪共享带来的性能损失。
3 伪共享的实际影响
假设 _bottom
和 _top
是一个无锁队列的头尾指针:
- 线程 A 频繁修改
_bottom
(入队操作)。 - 线程 B 频繁修改
_top
(出队操作)。 - 如果它们共享同一个缓存行,每次修改都会导致对方线程的缓存失效,性能可能下降 数倍甚至数十倍。
通过对齐到 64 字节,两者的修改完全隔离,避免不必要的缓存同步。
4 为什么必须是 64 字节?
- 缓存行大小:x86/x64 CPU 的缓存行大小通常为 64 字节,ARM 架构也普遍采用 64 字节。对齐到缓存行大小是最直接的方法。
- 兼容性:即使某些 CPU 的缓存行更小(如 32 字节),对齐到 64 字节也能覆盖所有常见情况。
5 其他替代方案
- 填充字节(Padding)
手动在变量间插入填充数据,强制隔离:
struct AlignedData {std::atomic<size_t> _bottom;char padding[64 - sizeof(std::atomic<size_t>)];std::atomic<size_t> _top;
};
- 缺点:需手动计算填充大小,不够灵活。
- C++17
std::hardware_destructive_interference_size
C++17 提供了表示缓存行大小的常量:
#include <new>
alignas(std::hardware_destructive_interference_size) std::atomic<size_t> _bottom;
alignas(std::hardware_destructive_interference_size) std::atomic<size_t> _top;
- 优点:代码可移植,自动适配不同平台的缓存行大小。
- 缺点:需要 C++17 支持。
6 验证对齐效果
可以通过以下方式验证变量是否对齐到 64 字节:
#include <iostream>
#include <cstdint>int main() {alignas(64) std::atomic<size_t> _bottom;alignas(64) std::atomic<size_t> _top;// 检查地址是否为 64 的倍数std::cout << "Address of _bottom: " << &_bottom << " (aligned: "<< ((reinterpret_cast<uintptr_t>(&_bottom) % 64 == 0) << ")\n";std::cout << "Address of _top: " << &_top << " (aligned: "<< ((reinterpret_cast<uintptr_t>(&_top) % 64 == 0) << ")\n";return 0;
}
总结
- 对齐到 64 字节:通过独占缓存行,避免
_bottom
和_top
之间的伪共享。 - 适用场景:高频并发访问的原子变量(如无锁数据结构、计数器等)。
- 推荐方法:优先使用
alignas(64)
或 C++17 的std::hardware_destructive_interference_size
。
相关文章:
【C/C++】ARM处理器对齐_伪共享问题
文章目录 1 什么是伪共享?2 为什么对齐?3 伪共享的实际影响4 为什么必须是 64 字节?5 其他替代方案6 验证对齐效果总结 1 什么是伪共享? 伪共享是 多线程编程中的一种性能问题,其本质是: 缓存行ÿ…...
【优化策略】离散化
概念 离散化是算法设计中处理大数据范围时的关键技巧,它将大范围的数据映射到有较小的的离散空间中,同时保持数据的相对关系。 本质:将原始数据映射到紧凑的连续整数空间 数学表示:建立映射函数 f: ℝ → ℤ,满足 x…...
微粉助手 1.1.0 | 专为社交电商用户设计的一站式营销工具,集成了群发消息、智能加好友、清理僵尸粉等功能
微粉助手是一款专为社交电商用户设计的一站式营销工具。此会员版无需登录,去除了更新检测,并优化了启动速度。它集成了群发消息、智能添加好友、精准清理僵尸粉、自动跟圈以及短视频获客等核心功能,是企业实现社交媒体营销自动化的理想选择。…...
【代码优化篇】强缓存和协商缓存
强缓存和协商缓存 一、强缓存与协商缓存的区别二、Vue2 前端实现强缓存(静态资源)三、Spring Boot 后端实现协商缓存(动态接口)四、测试缓存效果五、注意事项 一、强缓存与协商缓存的区别 强缓存:浏览器直接读取本地缓…...
分区器(2)
2. 设置ReduceTask 在MapReduce框架中,Reducer的数量(即ReduceTask的数量)可以通过配置参数来设置。 设置方法 通过配置文件: 在mapred-site.xml文件中设置mapreduce.job.reduces参数: xml <property><nam…...
外包团队协作效率低,如何优化
外包团队协作效率低是许多公司面临的挑战,尤其是在跨地域、跨文化和远程工作环境下。 优化外包团队的协作效率需要从沟通方式、项目管理工具、文化差异及团队结构等多个方面入手。首先,明确的沟通与及时的反馈是提高团队效率的基础, 通过定期…...
2020年NCA CCF-C,改进灰狼算法RSMGWO+大规模函数优化,深度解析+性能实测
目录 1.摘要2.灰狼算法GWO原理3.改进策略4.结果展示5.参考文献6.代码获取7.读者交流 1.摘要 灰狼优化算法(GWO)是一种新型自然启发式算法,具备较强的局部搜索能力,但在处理大规模问题时全局搜索能力较弱。本文提出了改进灰狼算法…...
【EasyPan】saveShare代码分析
【EasyPan】项目常见问题解答(自用&持续更新中…)汇总版 保存分享文件到个人网盘代码分析 一、代码结构概览 该代码实现了一个将他人分享的文件保存到自己网盘的功能,主要分为三个部分: 控制器层(Controller&a…...
基于Django框架开发的B2C天天生鲜电商平台
天天生鲜 介绍 天天生鲜是一个基于Django框架开发的B2C(Business-to-Customer)电商平台,专注于生鲜食品的在线销售。该项目采用了主流的Python Web开发框架Django,结合MySQL数据库、Redis缓存等技术,实现了一个功能完整、界面友好的电商网站…...
[数据库之九] 数据库索引之顺序索引
1、什么是索引? 拿到一本书,想直接跳到感兴趣的章节,而不是从头看到尾,这时需要看书的目录,上面列出章节和对应的页码,这里的目录可以看成是书的索引,如果没有索引,要查找书中某块内…...
使用 Celery + Redis + Eventlet 实现 Python 异步编程(Windows 环境)
一、环境搭建与依赖安装 1. 安装依赖包 pip install celery redis eventletcelery:异步任务队列框架。redis:作为消息中间件(Broker)和结果存储(Backend)。eventlet:用于 Windows 环境下的协程…...
Selenium Web自动化测试学习笔记(二)--八大元素定位
前置设置及代码 目录结构如下,将驱动器chromedriver.exe复制粘贴到此目录下,具体环境配置参考笔记一: Selenium Web自动化测试学习笔记(一)-CSDN博客 首先和笔记(一)一样导入一些包用于设置谷…...
如何设置飞书多维表格,可以在扣子平台上使用
扣子可以链接到飞书多维表格,但很多人不知道具体如何操作,今天给大家分享下操作流程。 大家好,我是涛涛,欢迎来到我的空间。因为需要管理员审核,所以最好有管理员的手机就在旁边方便操作。 (一) 进入应用中心 https…...
C++初阶-string类的简单应用
目录 1.仅仅反转字母 2.字符串中第一个唯一字符 3.字符串最后一个单词的长度 4.验证回文串 5.字符串相加 6.总结 1.仅仅反转字母 题目链接:https://leetcode.cn/problems/reverse-only-letters/description/ 在数据结构中我们学了一种方法叫做前后指针法&…...
企业数字化转型第二课:接受不完美(1/2)
一.引言 先看一组中国企业数字化转型相关的数据: 战略认知层面:92%中国企业将数字化纳入战略核心(麦肯锡2023)执行困境层面:63%企业转型首年遭遇重大挫折(BCG 2024追踪)价值释放周期࿱…...
【MCP】function call与mcp若干问题整理
前言:大模型里agent 的 funcation call 是什么概念 在大模型中,Agent是一个能够理解目标、进行自主规划,并利用可用工具(包括Function Call)来执行任务以达成目标的系统或程序。Function Call是大型语言模型提供的一项…...
QT聊天项目DAY09
1. 安装Redis 直接从老师的网盘下载 链接: https://pan.baidu.com/s/1v_foHZLvBeJQMePSGnp4Ow?pwdyid3 提取码: yid3 启动Redis服务看一下,启动成功了 .\redis-server.exe .\redis.windows.conf 启动客户端看一下 2. 配置redis库,调用API 编译一下 …...
JAVA八股文
一、JAVA基础 1.面向对象: 面向对象编程是一种以对象为核心的编程,通过封装、继承、多态和抽象管理代码。 1.封装:将数据(属性)和行为(方法)绑定在一个对象中,隐藏内部细节&#…...
『深夜_MySQL』数据库操作 字符集与检验规则
2.库的操作 2.1 创建数据库 语法: CREATE DATABASE [IF NOT EXISTS] db_name [create_specification [,create_specification]….]create_spcification:[DEFAULT] CHARACTER SET charset_nam[DEFAULT] COLLATE collation_name说明: 大写的表示关键字 …...
1688拍立淘搜索相似商品API接口概述,json数据示例参考
1688拍立淘搜索相似商品API接口概述 1688拍立淘是阿里巴巴1688平台提供的以图搜图功能,允许开发者通过上传商品图片或图片URL,快速检索1688平台上的相似商品。该接口基于图像识别技术,结合1688的海量商品库,为商家、采购商或开发…...
使用 Java 11 的 HttpClient 处理 RESTful Web 服务
在现代 Web 开发中,与 RESTful Web 服务交互是一项核心任务。Java 作为一种广泛使用的编程语言,提供了多种处理 HTTP 请求的方法。在 Java 11 之前,开发者通常使用 HttpURLConnection 或第三方库(如 Apache HttpClient)。然而,这些方法要么过于底层,要么需要额外依赖。J…...
学习笔记:黑马程序员JavaWeb开发教程(2025.3.30)
11.6 案例-文件上传-阿里云OSS-集成 从程序中获取URL给前端,前端显示图片 拿到URL,但是在浏览器里面是直接下载,展示可以使用html中的<image>标签 Spring环境下,不建议再去new对象,将其交给IOC容器管理ÿ…...
【MySQL】-- 联合查询
文章目录 1. 简介1.1 为什么要使用联合查询1.2 多表联合查询时MySQL内部是如何进行计算的 2. 内连接2.1 语法2.2 示例 3. 外连接3.1 语法3.2 示例 4. 自连接4.1 应用场景4.2 示例4.3 表连接练习 5. 子查询5.1 语法5.2 单行子查询5.3 多行子查询5.4 多列子查询5.5 在from 子句中…...
《C++ Templates》:有关const、引用、指针的一些函数模板实参推导的例子
1.T按值传递 最简单的模板例子: template<typename T> void func(T x) {std::cout << typeid(T).name() << std::endl;x 20;cout << x; } 这种情况下,T永远不会被推导成带顶层const或引用的类型 【顶层const即变量本身不能…...
【算法】随机快速排序和随机选择算法
文章目录 1、随机快速排序1.1 什么是随机快排1.2 随机快排的好处 2、随机选择算法 前言: 快速排序就是每次划分前,通过一种方法将一个基准值的位置确定好,再进入不同的部分重复相同的工作以此确定好每个值的位置以达到有序。如果你之前并不了…...
si551x时钟芯片linux下调试总结
目录 前言一、依赖文档、工具二、让芯片工作的流程三、以上步骤的SOC下代码实现 前言 本文总结调试SKYWORKS芯片厂商Si5512时钟芯片时的笔记,基于linux5.10.xxx内核,在arm64架构的SOC上验证; 一、依赖文档、工具 文档名说明下载链接Si5518…...
5.6-DAE实现
解决问题: 随机缺失(实验室指标未检测)系统性噪声(设备测量误差)类别不平衡(健康/患病人群比例悬殊) 思路:引入可控噪声 → 重建原始数据 实现步骤 (1)…...
MCU怎么运行深度学习模型
Gitee仓库 git clone https://gitee.com/banana-peel-x/freedom-learn.git项目场景: 解决面试时遗留的问题,面试官提了两个问题:1.单片机能跑深度学习的模型吗? 2.为什么FreeRTOS要采用SVC去触发第一个任务,只用Pend…...
背单词软件开发英语app开发,超级单词表开发,河南数匠软件开发
在数字化教育浪潮席卷全球的当下,英语教育行业面临着教学模式创新与教学效率提升的双重挑战。如何借助技术力量,为学生提供更优质、更高效的英语学习体验,成为众多英语教育机构亟待解决的问题。河南数匠软件开发有限公司,作为专注…...
AI视觉质检的落地困境与突破路径
摘要 人工智能(AI)视觉质检技术凭借其在提升效率、降低成本和优化质量控制方面的巨大潜力,正成为现代制造业转型升级的关键驱动力。然而,尽管前景广阔,AI视觉质检在实际落地过程中仍面临诸多严峻挑战,主要…...
检测内存条好坏有工具,推荐几款内存检测工具
检测内存条的好坏其实很重要,这直接就关系到计算机是不是能够稳定的运行,也有一部分人就会关注内存检测的工具。你应该如何来选择的,不如看一下以下的这几个。 MemTest86是一个比较受到大家喜欢的内存检测工具,会支持各种类型&…...
认识tomcat(了解)
启动 1. windows版本 解压后,就能用,启动,是bin路径下的startup.bat , 关闭是ctrl C . 启动后,可以访问 http://127.0.0.1:8080。为什么是8080,因为如下这个配置文件 部署 将项目放置到webapps目录下,即…...
[20250507] AI边缘计算开发板行业调研报告 (2024年最新版)
[20250507] AI边缘计算开发板行业调研报告 (2024年最新版) 一、行业背景 随着物联网设备激增与AI模型轻量化,边缘计算成为AI落地核心场景。AI边缘计算开发板(Edge AI Board)作为硬件载体,需满足低延迟…...
前端实现文件下载
目录 1.说明 2.示例--excel 3.示例--csv 1.说明 在开发中经常会出现下载csv或者excel文件,可以通过后端下载,也可以通过前端下载,如果在前端页面中可以直接获取到要下载的数据,可以通过前端下载的方式,更加高效便捷…...
深入理解Redis缓存与数据库不一致问题及其解决方案
什么是Redis缓存数据与数据库不一致 在现代应用中,Redis作为一种高速缓存系统,被广泛用于提升系统性能。Redis缓存数据与数据库不一致,指的是缓存中的数据与数据库中的数据不匹配,导致读取缓存时得到的不是最新或正确的数据。 R…...
六级阅读———2024.12卷一 仔细阅读2
文章 An awakening has been taking place in the physical world against the beauty model that has been dictated to us for years.But in the digital arena,social media determines what is considered beautiful.(51) The two opposing struggles are taking place i…...
【Python】字符串 转为 JSON 格式的注意事项
1. 字符串转json 我们如果使用sql存储json格式,要将json转为字符串才能转。 存入sql前,字典格式转json字符串可以用这个: Table_ [{"id": 1,"name": "Alice","task": 25,"work": &quo…...
镜像和容器的管理
一、镜像的管理 获取镜像并生成相关容器 # 拉取镜像 docker pull alpine # 默认是latest,也就是最新版本,也可指定版本(在镜像名后边加“:版本号”) # 或者 # 从主机中导入镜像到docker中 docker image load -i /test#生成容器 …...
Scrapy框架之Scrapyd部署及Gerapy分布式爬虫管理框架的使用
Scrapyd Scrapyd 是一个用于部署和运行 Scrapy 爬虫的服务器。 1.安装 Scrapyd服务端:pip install scrapyd Scrapyd客户端:pip install scrapyd-client 运行scrapyd 浏览器输入http://127.0.0.1:6800/ 2.配置 安装完成后,需要对 Scra…...
【uniapp】errMsg: “navigateTo:fail timeout“
项目场景: 在点击编辑的时候不能跳转的编辑的页面,然后直接报错errMsg: "navigateTo:fail timeout" 解决方案: 看看是否是出现了盒子的冒泡事件导致了两次调用跳转路径 tap.stop...
亿级流量系统架构设计与实战(五)
高并发写场景方案 1 : 数据分片之数据库分库分表 数据分片思想:可以将资源拆开分为多份,拆分的多份小的资源一起构成完整资源。 分库和分表 分库: 分库指的是将数据库拆分为多个小数据库,原来存储在单个数据库中的数据被分开存储到各个小数据库中。 分表:分表指的是将…...
机器学习——逻辑回归ROC练习
一、 题目要求: 给定以下二分类模型的预测结果,手动绘制ROC曲线并计算AUC值: y_true [0, 1, 0, 1, 0, 1] # 真实标签(0负类,1正类) y_score [0.2, 0.7, 0.3, 0.6, 0.1, 0.8] # 模型预测得分 代码展示…...
Kubernetes学习笔记
云计算三层模型 IaaS(基础设施即服务):提供虚拟化计算资源(如虚拟机、存储、网络)。 PaaS(平台即服务):提供应用开发和部署环境(如数据库、中间件、运行时)。…...
【DB2】DB2启动失败报错SQL1042C
在本地某次启动db2时报错SQL1042C,具体报错如下 [db2inst1standby ~]$ db2start 05/07/2025 16:32:53 0 0 SQL1042C An unexpected system error occurred. SQL1032N No start database manager command was issued. SQLSTATE57019在网上百度到说是需要…...
Redis相关命令详解与原理
Redis是什么? Redis 是Remote Dictionary Server(Redis) 的缩写,是一个使用 C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型的Key-Value数据库,并提供多种语言的API。 它是一种 NoSQL(not-only sql,…...
[吾爱出品][Windows] 产品销售管理系统2.0
[Windows] 产品销售管理系统 链接:https://pan.xunlei.com/s/VOPej1bHMRCHy2np9w3TBOyKA1?pwdgjy7# 使用方法:1、先设置一下图片保存路径 2、维护产品。客户等基础信息。例如:销售类型:一次性 销售编码:RCX。 3、销…...
基于OpenTelemetry的分布式链路追踪Trace实现(PHP篇)
目录 引言一、OpenTelemetry是一套可观测性标准协议二、分布式追踪(Trace)是OpenTelemetry的核心功能之一三、OpenTelemetry的架构原理四、OpenTelemetry的分布式追踪(Trace)实践1、准备PHP环境2、下载SDK3、编写实例代码…...
电气工程中漏源电压Vds的平台电压是什么?
在MOSFET(金属 - 氧化物 - 半导体场效应晶体管)中,漏源电压 VDS 的平台电压是其输出特性曲线中的一个关键概念。 定义 在MOSFET的输出特性曲线里,当器件工作于饱和区时,漏源电流ID对漏源电压VDS的变化不太敏感&…...
第35周Zookkeeper+Dubbo Dubbo
Dubbo 详解 一、Dubbo 是什么 官网与定义 Dubbo 是一款高性能、轻量级的开源服务框架,其官网为 double.apache.org,提供中文版本(网址含 “zh”)。 核心能力 Dubbo 具备六大核心能力: 面向接口代理的高性能 RPC …...
allegro出gerber时,单击Artwork并没有弹窗的问题
使用allegro出gerber时,有时点击 Artwork图标并未如愿以偿的弹出窗口。。。 可按下面尝试恢复,注,删除前可先备份该两支文件。。。 看时间戳,删除最近的下面标红两支文件即可。...