多线程伪共享FalseSharing
1. 伪共享产生:
在SMP架构的系统中,每个CPU核心都有自己的cache,当多个线程在不同的核心上,并且某线程修改了在同一个cache line中的数据时,由于cache一致性原则,其他核心cache中相同cache line会失效,从而产生cache miss,并重新从内存中读入数据到cache line,显然,这样多核心并没有实现真正的共享,称之为伪共享。
如下图:cpu0,cpu1中的Thread0和Thread1访问统一cache line中的不同数据,此时如果Thread1修改了cache line中块1的数据,则cpu0中的cache line同样也会失效,这时当Thread0读取cache line中的块0的数据时,就会产生cache miss,并更新cache line;

2. 测试:
1. 查看cacheline对齐字节数;
cat /proc/cpuinfo cache_alignment :
2. 测试代码:
#include <stdio.h>
#include <pthread.h> #define CACHE_LINE 64 struct num {
//使用attribute设置cacheline对齐
int number __attribute__ ((aligned(CACHE_LINE)));
//或者使用padding对cacheline进行补齐
//char padding[CACHE_LINE-sizeof(int)];
}; struct num arr_num[]; void *thread0(void *params)
{
arr_num[].number = ; for (unsigned int i = ; i < (unsigned int)-; i++) {
arr_num[].number++;
}
} void *thread1(void *params)
{
arr_num[].number = ; for (unsigned int i = ; i < (unsigned int)-; i++) {
arr_num[].number++;
}
} int main()
{
pthread_t tid[]; pthread_create(&tid[], NULL, thread0, NULL);
pthread_create(&tid[], NULL, thread1, NULL); pthread_join(tid[], NULL);
pthread_join(tid[], NULL); return ;
}
测试结果对比:
不使用cacheline对齐或者补齐
wanpengcoderMac-mini:~ Alex$ time ./false_sharing real 0m34.645s
user 1m8.875s
sys 0m0.079s
使用cacheline对齐或者补齐
wanpengcoderMac-mini:~ Alex$ time ./false_sharing real 0m10.193s
user 0m20.236s
sys 0m0.026s
多线程伪共享FalseSharing的更多相关文章
- 伪共享 FalseSharing (CacheLine,MESI) 浅析以及Java里的解决方案
起因 在阅读百度的发号器 uid-generator 源码的过程中,发现了一段很奇怪的代码: /** * Represents a padded {@link AtomicLong} to preve ...
- 多线程中的volatile和伪共享
伪共享 false sharing,顾名思义,“伪共享”就是“其实不是共享”.那什么是“共享”?多CPU同时访问同一块内存区域就是“共享”,就会产生冲突,需要控制协议来协调访问.会引起“共享”的最 ...
- 什么是多线程环境下的伪共享(false sharing)?
伪共享是多线程系统(每个处理器有自己的局部缓存)中一个众所周知的性能问 题.伪共享发生在不同处理器的上的线程对变量的修改依赖于相同的缓存行,如 下图所示: 伪共享问题很难被发现,因为线程可能访问完全不 ...
- 伪共享(false sharing),并发编程无声的性能杀手
在并发编程过程中,我们大部分的焦点都放在如何控制共享变量的访问控制上(代码层面),但是很少人会关注系统硬件及 JVM 底层相关的影响因素.前段时间学习了一个牛X的高性能异步处理框架 Disruptor ...
- Java8的伪共享和缓存行填充--@Contended注释
在我的前一篇文章<伪共享和缓存行填充,从Java 6, Java 7 到Java 8>中, 我们演示了在Java 8中,可以采用@Contended在类级别上的注释,来进行缓存行填充.这样 ...
- 伪共享和缓存行填充,从Java 6, Java 7 到Java 8
关于伪共享的文章已经很多了,对于多线程编程来说,特别是多线程处理列表和数组的时候,要非常注意伪共享的问题.否则不仅无法发挥多线程的优势,还可能比单线程性能还差.随着JAVA版本的更新,再各个版本上减少 ...
- java 伪共享
MESI协议及RFO请求典型的CPU微架构有3级缓存, 每个核都有自己私有的L1, L2缓存. 那么多线程编程时, 另外一个核的线程想要访问当前核内L1, L2 缓存行的数据, 该怎么办呢?有人说可以 ...
- java中伪共享问题
伪共享(False Sharing) 原文地址:http://ifeve.com/false-sharing/ 作者:Martin Thompson 译者:丁一 缓存系统中是以缓存行(cache l ...
- 并发性能的隐形杀手之伪共享(false sharing)
在并发编程过程中,我们大部分的焦点都放在如何控制共享变量的访问控制上(代码层面),但是很少人会关注系统硬件及 JVM 底层相关的影响因素.前段时间学习了一个牛X的高性能异步处理框架 Disruptor ...
随机推荐
- 只要访问的地址匹配cookie的地址时候 发送request请求时候 会携带上该cookie
只要访问的地址匹配cookie的地址时候 发送request请求时候 会携带上该cookie
- tcp协议的六个标识位
6个标识位: URG 紧急指针,告诉接收TCP模块紧要指针域指着紧要数据. ACK 置1时表示确认号(为合法,为0的时候表示数据段不包含确认信息,确认号被忽略. PSH 置1时请求的数据段在接收方得到 ...
- BZOJ4945 & 洛谷3825 & UOJ317:[NOI2017]游戏——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4945 https://www.luogu.org/problemnew/show/P3825 ht ...
- BZOJ2752:[HAOI2012]高速公路——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=2752 https://www.luogu.org/problemnew/show/P2221#sub ...
- BZOJ2697 特技飞行 【贪心】
题目链接 BZOJ2697 题解 好水好水的贪心... 容易发现每种特技只表演两次,多表演没有意义,而且差距越长收益越大 然后就可以贪,最大的放两端,次大的往里,然后是第三大....... 证明很简单 ...
- VC使用sqlite
SQLite可以到官方站点(http://www.sqlite.org/download.html)下载:Linux,Mac OS X, Windows下的已编译文件以及源代码.帮助文档. SQLit ...
- Android 自定义ListView实现底部分页刷新与顶部下拉刷新,androidlistview
在项目开发中,由于数据过大时,需要进行分页加载或下拉刷新,来缓解一次性加载的过长等待.本篇博文实例讲解通过自定义的ListView实现底部分页加载和顶部下拉刷新的效果. 其效果图: 一.ListVie ...
- javascript中不易分清的slice,splice和split三个函数
1.slice(数组) 用法:array.slice(start,end) 解释:该方法是对数组进行部分截取,并返回一个数组副本:参数start是截取的开始数组索引,end参数等于你要取的最后一个字符 ...
- 前端PHP入门-001-为什么学习PHP?
写在前面的话 可能不知道能坚持多久,现在的我喜欢纯文字的描述! 希望能坚持写完,也是对自己的一个鞭策! 总顾及别人,那谁来顾及你! 为什么学习PHP? PHP入门简单,学习入门易入手[呵呵,都这么说, ...
- springboot以jar包方式启动、关闭、重启脚本
springboot以jar包方式启动.关闭.重启脚本 启动 编写启动脚本startup.sh #!/bin/bash echo Starting application nohup java -ja ...