在阅读linux 2.6.23内核代码中遇到mb()/rmb()/wmb() 这几个宏,不明白如何使用,

在分析其汇编代码后,大概的了解了这和内存屏障有关,代码如下:

#define X86_FEATURE_XMM2 (0*32+26) /* Streaming SIMD Extensions-2 */

......

#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2)

#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2)

#ifdef CONFIG_X86_OOSTORE

/* Actually there are no OOO store capable CPUs for now that do SSE,

but make it already an possibility. */

#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM)

#else

#define wmb() __asm__ __volatile__ ("": : :"memory")

#endif

.......

/*

* Alternative instructions for different CPU types or capabilities.

*

* This allows to use optimized instructions even on generic binary

* kernels.

*

* length of oldinstr must be longer or equal the length of newinstr

* It can be padded with nops as needed.

*

* For non barrier like inlines please define new variants

* without volatile and memory clobber.

*/

#define alternative(oldinstr, newinstr, feature) \

asm volatile ("661:\n\t" oldinstr "\n662:\n" \

".section .altinstructions,\"a\"\n" \

"   .align 4\n" \

"   .long 661b\n"          /* label */ \

"   .long 663f\n"    /* new instruction */ \

"   .byte %c0\n"          /* feature bit */ \

"   .byte 662b-661b\n"    /* sourcelen */ \

"   .byte 664f-663f\n"    /* replacementlen */ \

".previous\n" \

".section .altinstr_replacement,\"ax\"\n" \

"663:\n\t" newinstr "\n664:\n" /* replacement */\

".previous" :: "i" (feature) : "memory")

内存屏障主要解决的问题是编译器的优化和CPU的乱序执行。

编译器在优化的时候,生成的汇编指令可能和c语言程序的执行顺序不一样,在需要程序严格按照c语言顺序执行时,需要显式的告诉编译不需要优化,这在linux下是通过barrier()宏完成的,它依靠volidate关键字和memory关键字,前者告诉编译barrier()周围的指令不要被优化,后者作用是告诉编译器汇编代码会使内存里面的值更改,编译器应使用内存里的新值而非寄存器里保存的老值。

同样,CPU执行会通过乱序以提高性能。汇编里的指令不一定是按照我们看到的顺序执行的。linux中通过mb()系列宏来保证执行的顺序。具体做法是通过mfence/lfence指令(它们是奔4后引进的,早期x86没有)以及x86指令中带有串行特性的指令(这样的指令很多,例如linux中实现时用到的lock指令,I/O指令,操作控制寄存器、系统寄存器、调试寄存器的指令、iret指令等等)。简单的说,如果在程序某处插入了mb()/rmb()/wmb()宏,则宏之前的程序保证比宏之后的程序先执行,从而实现串行化。wmb的实现和barrier()类似,是因为在x86平台上,写内存的操作不会被乱序执行。

实际上在RSIC平台上,这些串行工作都有专门的指令由程序员显式的完成,比如在需要的地方调用串行指令,而不像x86上有这么多隐性的带有串行特性指令(例如lock指令)。所以在risc平台下工作的朋友通常对串行化操作理解的容易些。

linux编译 mb_string,linux mb()/rmb()/wmb()相关推荐

  1. linux与RMB的关系,linux mb()/rmb()/wmb()

    在阅读linux 2.6.23内核代码中遇到mb()/rmb()/wmb() 这几个宏,不明白如何使用, 在分析其汇编代码后,大概的了解了这和内存屏障有关,代码如下: #define X86_FEAT ...

  2. I/O函数 writel __raw_writel mb()/rmb()/wmb()

    在邮件列表里讨论了一下writel是如何实现的,这个函数实现在操作系统层,有内存保护的情况下,往一个寄存器或者内存地址写一个数据. 在arch/alpha/kernel/io.c中有 188 void ...

  3. spdlog linux编译出错,Linux下编写Makefile引入第三方库

    Linux下编写Makefile引入第三方库 前言:一直在使用CmakaList 生成Makefile文件,其实很少去写Makefile,但是最近帮朋友处理了一个Makefile引入第三方库的问题,就 ...

  4. linux编译 mb_string,一起来学学Linux C(一)文件写入

    一.前言 很久以前接触了VB,后来一直想学C,但是一直被Win API掐住手脚,也一直在用VB去实践WinAPI,所以对C也是一知半解,在后来又转到Linux下学习Java.Android,索性也就在 ...

  5. linux编译sqrt,linux c sqrt

    我想到的一个简单可能性是,在常见情况下,每个值保留一个压缩数组,每个值2位,而每个值分隔一个4字节(原始元素索引为24位,实际值为8位,因此(idx << 8) | value))其他的. ...

  6. linux 编译缓存,Linux磁盘缓存(disk cache)详解

    在Linux系统里通过free命令,我们经常可以看到类似下面的输出: $ free -m total used free shared buffers cached Mem: 24097 21665 ...

  7. linux 编译openmp,Linux 系统中OpenMP

    转自:http://hi.baidu.com/linzch/blog/item/db3252fb6227c01e6c22eb21.html *怎么在Linux上运行OpenMP程序? > 只需要 ...

  8. linux编译ace,Linux下编译ACE

    操作系统:Centos4.7 ACE版本:ACE-6.0.2 安装过程: 下载ACE-6.0.2.tar.gz. 下载完成后将其解压tar -zxvf ACE-6.0.2.tar.gz用户登陆目录.我 ...

  9. linux编译blas,Linux下安装BLAS,CBLAS,LAPACK

    1.下载 BLAS,CBLAS:http://www.netlib.org/blas/ LAPACK:http://www.netlib.org/lapack/ 2.上传 将下载好的三个压缩文件上传到 ...

  10. linux编译准备,Linux 下编译指南

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 首先,我们需要获取最新的源码. 使用如下命令即可: git clone -b master --depth=1 https://github.com/Cl ...

最新文章

  1. 利用Python基础代码语句,实现2G时代文字小游戏,世界如此简单
  2. python编程是干啥用的-浅谈Python类中的self到底是干啥的
  3. python怎么安装numpy库-Python NumPy库安装使用笔记
  4. [原创] Legato 8.1 oracle full backup skip 奇怪的问题处理过程 -- 非调度日期手工运行调度也不成功(skip)...
  5. Jquery一些笔记
  6. 黑客攻防技术宝典Web实战篇第2版—第6章 攻击验证机制
  7. translucent 属性
  8. 三个梯度磁场_第二节 梯度磁场系统
  9. 刷《剑指offer》笔记
  10. python网络爬虫系列教程_Python网络爬虫系列教程连载 ----长期更新中,敬请关注!...
  11. 第五次作业 第三章例题
  12. 学习项目管理PRINCE2有什么用??
  13. 【python简洁之道】-----1. 注释规则
  14. 【人话版】WEB3黑暗森林中的隐私博弈
  15. 【layoutit!】基于 bootstrap 实现可视化布局工具
  16. What is a hardlink and how to create one?
  17. Mac - was compiled with optimization - stepping may behave oddly; variables may not be available.
  18. 九大遥感目标检测数据集(附下载链接)
  19. 树立品牌价值标杆,维谛技术(Vertiv)荣膺“中国电气工业100强”殊荣
  20. Win10应用商店不能更新软件怎么办?

热门文章

  1. Javaweb(二)制作调查问卷
  2. linux mint字体缺失,WPS for Linux【Debian、Ubuntu、Deepin、Linux Mint】字体缺失解决【批量字体安装】...
  3. Excel 表格数据去重
  4. ASTC纹理压缩格式详解
  5. 移动智能终端PIN码破解
  6. 两个文件定义了同名的变量,会是同一个变量吗?
  7. 层次分析法原理及应用案例
  8. 一款非常萌的桌面工具---bongo cat mver0.1.6 附使用教程
  9. STM32与DS1302设计时钟芯片,超详细
  10. C++ 动态库、静态库、__declspec(dllexport)、符号隐藏、gcc visibility (“default“)