栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

linux设备驱动中的编译乱序和执行乱序

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

linux设备驱动中的编译乱序和执行乱序

往期链接:

linux设备驱动中的并发


本期主题:
编译乱序和执行乱序


目录

1.从实际例子引出编译乱序

1.为什么会有编译乱序?2.编译屏障barrier()设置


1.从实际例子引出编译乱序 1.为什么会有编译乱序?

编译器的工作就是帮我们优化代码性能,在不改变程序行为的情况下重新排序一些指令。但是有一个关键问题在于,编译器并不知道什么代码需要关注线程安全,它只会按照单线程的方式来处理这些指令,所以这样就存在了编译乱序的问题,因此,我们如果清楚知道哪些代码不应该被优化,我们就需要明确的告诉编译器。

看实际例子:

int a, b;
#define barrier() __asm__ __volatile__("": : :"memory")

void test_func(void)
{
	a = b + 1;
	b = 0;
}

int main(void)
{
	test_func();
	return 0;
}

gcc默认为O0编译,我们先看下O0编译完之后的目标文件反汇编的结果:

jason@ubuntu:~/WorkSpace/2.Linux_Driver/1.compile$ arm-none-linux-gnueabi-gcc -O0 main.c
jason@ubuntu:~/WorkSpace/2.Linux_Driver/1.compile$ arm-none-linux-gnueabi-objdump -d a.out > O0.asm

O0反汇编的结果表明与代码是一致的,没有乱序

用同样的方式测试O2优化过后的结果:

发现经过O2优化的代码,反汇编出来的指令执行顺序有改变,这是编译器的优化结果。

2.编译屏障barrier()设置

可以使用编译屏障barrier()来保证上述指令不会被优化。

    __asm__ 表示这是内嵌汇编,内嵌汇编的语法如下:__asm__ (汇编语句模板: 输出部分: 输入部分: 描述部分),其中memory描述表示直接从内存取,而不要用原来寄存器中的缓存;有一篇文章关于内嵌汇编讲得比较好 gcc内嵌汇编简单介绍需要注意的是,C语言内的volatile关键字和这个意义并不完全相同,C语言的volatile主要是避免了内存访问的合并行为,告诉了编译器,这个变量是有可能被外部修改的,因此需要重新读一下,不能用寄存器中的缓存值;

实验验证,添加了barrier()之后,O2编译的顺序也是正确的

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/714258.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号