内存避障fence(一)一个内存乱序实例
创始人
2025-05-29 05:02:24
0

借鉴网上的一个例子,分析一下到底什么是memory reordering内存乱序。

实例

源码 & 编译指令:g++ -lpthread -g -o fence fence.cpp

#include 
#include volatile int x, y, r1, r2;
void start()
{x = y = r1 = r2 = 0;
}
void end()
{assert(!(r1 == 0 && r2 == 0));
}
void run1()
{x = 1;r1 = y;
}
void run2()
{y = 1;r2 = x;
}static pthread_barrier_t barrier_start;
static pthread_barrier_t barrier_end;
static void *thread1(void *)
{while (1){pthread_barrier_wait(&barrier_start);run1();pthread_barrier_wait(&barrier_end);}return NULL;
}
static void *thread2(void *)
{while (1){pthread_barrier_wait(&barrier_start);run2();pthread_barrier_wait(&barrier_end);}return NULL;
}
int main()
{pthread_t t1;pthread_t t2;cpu_set_t cs;assert(pthread_barrier_init(&barrier_start, NULL, 3) == 0);assert(pthread_barrier_init(&barrier_end, NULL, 3) == 0);assert(pthread_create(&t1, NULL, thread1, NULL) == 0);assert(pthread_create(&t2, NULL, thread2, NULL) == 0);CPU_ZERO(&cs);CPU_SET(0, &cs);assert(pthread_setaffinity_np(t1, sizeof(cs), &cs) == 0);CPU_ZERO(&cs);CPU_SET(1, &cs);assert(pthread_setaffinity_np(t2, sizeof(cs), &cs) == 0);while (1){start();pthread_barrier_wait(&barrier_start);pthread_barrier_wait(&barrier_end);end();}return 0;
}
  • pthread_barrier_wait会block直到3个并发ready,这样起到同步运行的效果。
  • 真正并发的是run1、run2,两个线程会配置亲和性,分配到两个CPU上运行。

期望结果

假设两个并发的执行情况

void run1()
{x = 1;     // A1r1 = y;    // A2
}
void run2()
{y = 1;     // B1r2 = x;    // B2
}/* ********** 初始状态 ********** */
x = y = r1 = r2 = 0;// 无乱序run1和run2如何并发,会出现下述六种情况,无论哪种情况,r1、r2不会出现同时为零。
/* ********** 情况一:A1 A2 B1 B2   ********** */
x = 1; 
r1 = y;           // r1 = 0;y = 1; 
r2 = x;           // r2 = 1;
/* ********** 情况二:B1 A1 A2 B2   ********** */
y = 1;x = 1; 
r1 = y;           // r1 = 1;r2 = x;           // r2 = 1;
/* ********** 情况三:B1 B2 A1 A2   ********** */
y = 1;
r2 = x;           // r2 = 0;x = 1; 
r1 = y;           // r1 = 1;
/* ********** 情况四:A1 B1 B2 A2   ********** */
x = 1; y = 1; 
r2 = x;           // r2 = 1;r1 = y;           // r1 = 1;/* ********** 情况五:A1 B1 A2 B2   ********** */
x = 1;
y = 1;
r1 = y;
r2 = x;/* ********** 情况五:B1 A1 B2 A2   ********** */
y = 1;
x = 1;
r2 = x;
r1 = y;

可以看到无论哪种情况,都不应该出现r1 == 0 && r2 == 0

运行结果

但是实际上会发生r1、r2同时为零:

$ ll
total 316
-rw------- 1 x root 17412096 Mar 15 22:12 core.1229   <<----<<----
-rwxr-xr-x 1 x root    17088 Mar 15 22:16 fence
-rw-r--r-- 1 x root     1361 Mar 15 22:16 fence.cpp

core内容:

#0  0x00007fa1910853d7 in raise () from /lib64/libc.so.6
#1  0x00007fa191086ac8 in abort () from /lib64/libc.so.6
#2  0x00007fa19107e1a6 in __assert_fail_base () from /lib64/libc.so.6
#3  0x00007fa19107e252 in __assert_fail () from /lib64/libc.so.6
#4  0x00000000004011cb in end () at fence.cpp:12
#5  0x00000000004014a7 in main () at fence.cpp:67

结果分析

发生了执行时乱序的情况:

void run1()
{x = 1;r1 = y;
}
void run2()
{y = 1;r2 = x;
}
/* ********** 乱序情况 逻辑上不应该发生  ********** */
r1 = y     // r1 == 0
r2 = x     // r2 == 0
x = 1
y = 1

如何解决

1 内存fence:成功

在X86架构下,使用mfence指令即可解决。不再core。


void run1()
{x = 1;__asm__ __volatile__("mfence" : : : "memory");r1 = y;
}
void run2()
{y = 1;__asm__ __volatile__("mfence" : : : "memory");r2 = x;
}

2 编译fence:失败

问题:只使用编译器fence可行吗,例如:


void run1()
{x = 1;__asm__ __volatile__("" : : : "memory");r1 = y;
}
void run2()
{y = 1;__asm__ __volatile__("" : : : "memory");r2 = x;
}

结果:还是会core,不带mfence指令只能保证无编译乱序,无法解决内存乱序。

相关内容

热门资讯

重磅!一线城市房地产调控全面松... 一线城市房地产调控全面松绑,释放购房新信号2025 年,房地产市场风云突变,一则重磅消息如惊雷般响彻...
晶科能源携多款创新光储方案亮相... 转自:证券日报网    本报记者 曹琦    6月11日至13日,第十八届(2025)国际太阳能光伏...
“山有木兮卿有意,昨夜星辰恰似... “山有木兮卿有意,昨夜星辰恰似你”是什么意思?“山有木兮卿有意,昨夜星辰恰似你”的意思是“我对你有意...
股权转让+增资 日联科技拿下... 转自:证券日报网    本报记者 李亚男    6月13日晚间,日联科技集团股份有限公司(以下简称“...
一个人开什么店好,两万块开什么... "劳动人民、劳动灵魂和劳动都是人."这在去年开始流行,所有工作的人都拿他们的工作开玩笑。经过几十年的...
杭州市城区周边哪里有菜地(旱地... 杭州市城区周边哪里有菜地(旱地)或山地租?我想租个几亩种种?若有,大概要多少钱一亩?杭州市城北郊区就...
西湖不欢迎“粗暴的手” 转自:中国环境网近日,“杭州西湖石刻有人拔断松鼠尾巴”一事引起了网友们的关心和讨论。对此,西湖水域管...
吕姓股民向普利退发起索赔 许峰...   受损股民可至Hehson股民维权平台登记该公司维权:http://wq.finance.sina...
家里有几个多事的大姑姐怎么办 家里有几个多事的大姑姐怎么办其实只要心态放平一点就好了,家里的大姑姐平常也没有什么事情做,所以只能聊...
贝尔计划赛季末重返皇马,贝尔重... 贝尔计划赛季末重返皇马,贝尔重回皇马的主要原因有哪些?齐达内让他进入首发,不是信任,而是希望在今年夏...
名侦探柯南为什么会有快兰的说法 名侦探柯南为什么会有快兰的说法你可以去看剧场版十四天空中的遇难船的1分30秒的预告片里面有……小兰和...
求跟侠岚类型的动画片 求跟侠岚类型的动画片《千年寻》一样!
刘备为何不踏实治理好夺取的荆州... 刘备为何不踏实治理好夺取的荆州四郡,而是非要借南郡?因为南郡的地理位置太过于紧要,是荆州四郡的门户,...
问道手游70套装怎么做 问道手... 问道手游70套装怎么做 问道手游70级极品套装打造步骤全面解析首先来说的第一个问题 套装是由超级...
苏超第四轮燃爆,网友:小龙虾大... 格隆汇6月14日|据央视财经,在苏超第四轮赛事中,淮安队将迎战南京队,被大家调侃是“小龙虾”与“盐水...
卓驭科技CEO沈劭劼:智能驾驶...   2025第十七届轩辕汽车蓝皮书论坛于2025年6月13日-15日在广州举行。卓驭科技CEO沈劭劼...
倾世王妃的繁体字怎么写的啊 倾世王妃的繁体字怎么写的啊倾世皇妃__倾世皇妃倾世王妃差别就在第一个字
羊城夏夜上演“粤乐新唱·潮挞非... 中新网广州6月14日电 (程景伟 文瑶)当高胡的悠扬遇见架子鼓的爆裂,当粤剧的锣鼓铿锵与贝斯的低沉吟...
前5月我国人民币贷款增加10.... 转自:中工网人民日报海外版北京6月13日电(记者徐佩玉)中国人民银行13日发布的金融统计数据显示,前...
光纤宽带机房为什么有尖叫声 光纤宽带机房为什么有尖叫声呵呵,主板设备,交换机里面有很多小的散热风扇,你听到的声音应该是风扇的声音...