讲师中心 微信公众号

工具推荐

视频效率加速
updream

一键生成高质量推广成片

Laper
Laper

剧本策划到成片协作

剧云
剧云

中文短剧剧本制作平台

立刻MV
立刻MV

低成本歌曲 MV、视频生成

C++多线程编程如何避免虚假共享 填充和内存对齐技术解析

夜明同学_9143

夜明同学_9143

发布时间:2025-08-11 12:06:02

|

294人浏览过

|

来源于php中文网

原创

虚假共享是多线程编程中因不同变量共处同一缓存行导致的性能问题。1.它发生在多个线程修改位于同一缓存行的不同变量时,引发频繁缓存失效;2.填充可通过插入多余字节使变量分布于不同缓存行,如定义占满64字节的结构体;3.内存对齐用alignas确保变量按缓存行大小对齐,避免紧凑排列;4.结合std::hardware_destructive_interference_size可提高代码可移植性;5.实际开发应避免过度填充、优先无共享设计、测试性能差异并分离结构体高频字段。

C++多线程编程如何避免虚假共享 填充和内存对齐技术解析

在C++多线程编程中,虚假共享(False Sharing)是一个容易被忽略但可能严重影响性能的问题。它发生在多个线程修改位于同一缓存行(cache line)中的不同变量时,即使这些变量之间毫无关系,也会导致缓存一致性协议频繁触发,从而降低程序效率。

C++多线程编程如何避免虚假共享 填充和内存对齐技术解析

要避免这个问题,填充(Padding)和内存对齐(Memory Alignment)是两个关键手段。

C++多线程编程如何避免虚假共享 填充和内存对齐技术解析

什么是虚假共享?

现代CPU为了提高访问速度,会将内存按缓存行(通常是64字节)为单位加载到高速缓存中。如果两个线程分别操作的是两个不同的变量,但这两个变量恰好位于同一个缓存行中,其中一个线程的写操作就会让另一个线程的缓存行失效。即使它们互不干扰,也得重新加载缓存,这就是“虚假共享”。

立即学习“C++免费学习笔记(深入)”;

举个例子:

C++多线程编程如何避免虚假共享 填充和内存对齐技术解析
struct Data {
    int a;
    int b;
};

Data data;

// 线程1
void thread1() {
    for (int i = 0; i < 1000000; ++i)
        ++data.a;
}

// 线程2
void thread2() {
    for (int i = 0; i < 1000000; ++i)
        ++data.b;
}

如果

a
和
b
刚好在同一个缓存行里,两个线程虽然操作的是不同变量,但每次自增都会使对方的缓存失效,性能大打折扣。


如何通过填充避免虚假共享?

一个直接的办法是:在变量之间插入足够的填充字段,确保它们分布在不同的缓存行中。

比如:

struct alignas(64) PaddedData {
    int value;
    char padding[64 - sizeof(int)]; // 填充到64字节
};

这样每个

PaddedData
对象都占满一个缓存行,彼此之间不会产生干扰。如果你有多个这样的结构体变量被多个线程分别访问,就不用担心它们被误放到同一个缓存行里了。

热点分析与爆款挖掘
热点分析与爆款挖掘

热点分析与爆款挖掘工具。当用户询问"全网最新话题"、"最近有什么热点"、"XX话题热度分析"、"XX有什么爆款内容"、"选题推荐"、"热点追踪"、"爆款挖掘"或"内容定位建议"时,必须使用本skill。自动挖掘抖音、小红书、公众号、快手、B站、微博、视频号、知乎、新闻门户等平台的爆款内容,聚合热门关键词,分析爆款规律,提供创作角度建议。适用于选题策

下载

实际应用中,常见做法是定义一个宏或者类型来统一处理:

#define CACHE_LINE_SIZE 64

template<typename T>
struct alignas(CACHE_LINE_SIZE) CachePadded {
    T value;
    char pad[CACHE_LINE_SIZE - sizeof(T)];
};

然后使用方式如下:

CachePadded<int> counter1;
CachePadded<int> counter2;

// 线程1操作counter1.value
// 线程2操作counter2.value

这样就能保证两者不在同一缓存行中。


内存对齐的作用和设置方法

除了填充,还需要注意结构体或变量的对齐方式。默认情况下,编译器可能会为了节省空间而紧凑排列结构体成员,这反而更容易造成虚假共享。

你可以使用

alignas
来强制某个结构体或变量以特定大小对齐:

struct alignas(64) MyStruct {
    int a;
    int b;
};

上面这个结构体虽然只有8字节,但会被分配到64字节对齐的位置,有助于减少跨缓存行访问带来的问题。

另外,在一些系统上还可以使用

std::hardware_destructive_interference_size
这个常量,它表示当前平台下可能导致虚假共享的最小间隔大小(通常是64字节),这样代码更具可移植性:

alignas(std::hardware_destructive_interference_size) int x, y;

这样可以确保

x
和
y
不在同一个缓存行中。


实际开发中的一些技巧

  • 不要过度填充:虽然填充能解决问题,但也会浪费内存。只在确实存在竞争的热点数据上使用。
  • 优先考虑无共享设计:比如使用线程本地存储(TLS)、原子操作等,从根本上避免共享。
  • 测试性能差异:虚假共享有时影响不大,有时却非常严重。最好用性能分析工具(如perf、VTune)确认是否存在瓶颈。
  • 结构体内部分离高频读写字段:如果一个结构体中有多个字段被不同线程频繁访问,把它们分开到不同的缓存行中。

基本上就这些。虚假共享是个细节问题,不容易发现,但一旦出现又会影响整体性能。用好填充和对齐技术,可以在多线程环境下提升程序的稳定性和执行效率。

相关文章

编程速学教程(入门课程)
编程速学教程(入门课程)

编程怎么学习?编程怎么入门?编程在哪学?编程怎么学才快?不用担心,这里为大家提供了编程速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

码上飞
码上飞 Hot

一款基于自然语言的AI应用开发平台,可根据用户描述自动生成应用程序,帮助个人和团队快速完成应用原型与开发。

创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

Flowith
Flowith Hot

Flowith是一款基于画布和智能体工作流的 AI 协作工作空间。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

小橡皮AI

一款AI工具,主要用于小橡皮一键去AI味,将机器味重的内容改得更有活人感,防止因为 AI 内容被平台打上 AI 标签,以及限流,适合需要提升相关任务效率的用户。

相关专题

更多
java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

6364

2023.10.24

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

5394

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

5571

2025.07.04

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

4798

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

1349

2025.12.24

java多线程相关教程合集
java多线程相关教程合集

本专题整合了java多线程相关教程,阅读专题下面的文章了解更多详细内容。

443

2026.01.21

C++多线程相关合集
C++多线程相关合集

本专题整合了C++多线程相关教程,阅读专题下面的的文章了解更多详细内容。

599

2026.01.21

C# 多线程与异步编程
C# 多线程与异步编程

本专题深入讲解 C# 中多线程与异步编程的核心概念与实战技巧,包括线程池管理、Task 类的使用、async/await 异步编程模式、并发控制与线程同步、死锁与竞态条件的解决方案。通过实际项目,帮助开发者掌握 如何在 C# 中构建高并发、低延迟的异步系统,提升应用性能和响应速度。

449

2026.02.06

Postman身份认证怎么配置
Postman身份认证怎么配置

本专题从实际API接口调试场景出发,讲解Postman身份认证的完整配置流程,包括常见认证协议介绍、授权参数设置、访问令牌填写、OAuth 2.0授权及认证失败排查,帮助用户正确完成接口授权与访问验证。

80

2026.11.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn