Linux 内核 barrier宏

阅读数:132 评论数:0

跳转到新版页面

分类

Linux

正文

一、源码相关

// include/linux/compiler-gcc.h
/**
* asm指示后面的语句是汇编语句。
* volatile表示禁止对后面的代码进行优化
* ""表示这里是个空指令,因为是空指令,所以没有输入输出。
* 在gcc中,如果以这种方式嵌入汇编,需要用肉个冒号代替输出操作数的位置,然后
* 再加上为分隔输入而加入的冒号,即为"":::
* memory是gcc中的一特殊语法,表示只从内存进行读取数据
*/

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

 程序在运行时内存实际的访问顺序和程序代码编写时指定的顺序可能不一致,这就是内存乱序访问。内存乱序访问的主要原因是为了提升程序运行时的性能。主要发生在两个阶段:

1、编译时,编译器优化(指令重排)

2、运行时,多CPU间交互

Memory Barrier能够让CPU或编译器在内存访问上有序,一个Memory Barrier之前的内存访问操作必定先于其之后的完成。

而上面提供的barrier()用于让编译器保证其之前的内存访问先于其之后的完成。

二、多种内存屏障宏

内存屏障确保在并发执行的环境中,内存操作的执行顺序符合预期。

在多核处理器上,每个核可能有自己的缓存。因此,一个核上的写操作可能不会立即对其他核可见。内存屏障用于确保在必要的时候,这些操作对所有处理器都是可见的。

Linux内核提供了多种内存屏障宏:

1、mb()

Memory Barrier,一个全屏障,保证所有先于mb()的读写操作在内存中的更新对所有处理器都可见后,才能执行后续的读写操作。

2、rmb()

Read Memory Barrier,一个读屏障,确保所有先于rmb()的读操作完成后,才能执行后续的读操作。

3、wmb()

Write Memory Barrier,一个写屏障,确保所有先于wmb()的写操作完成后,才能执行后续的写操作。

4、smp_mb()

SMP Memory Barrier,当编译为SMP(对称多处理)内核时,它作为一个全屏障;在单处理器编译时,它可能不做任何事情。

5、smp_rmb()和smp_wmb()

类似于smp_mb(),但分别用于读和写内存操作。

 




相关推荐

mainline 、longterm、stable、linux-next、snapshot这些名词,都是linux kernel sou

__CONCAT,连接两个参数,##用于粘贴两个参数,#用于替换参数 #define __CONCAT(a, b) a ##

<img src="http://123.56.17.129:2177/images/linux_kernel.png" alt="" /

在编程中,一个符号symbol是一个程序的创建块,它是一个变量名或一个函数名。 内核符号表(Kernel Symbol Table) 内核并不使用符号名。它是通过

在Kernel_path/Makefile中可以查看到 # SPDX-License-Identifier: GPL

一、概述 在 Linux 内核中,printk 是一个类似于用户空间 C 语言中的 printf 函数的内核级日志记录功能。它用于内核代码中输出调试信息到控制台或系统日志。printk 可以在几乎任何

一、概述  在日常工作中,经常会需要对内核进行Debug、或者进行优化工作。一些简单的问题,可以通过dmesg/printk查看,优化借助一些工具进行。 但是当问题逻辑复杂,优化面宽泛的时候,往往无从

一、概述 在 Linux 内核编程中,asmlinkage 是一个关键字,用于告诉编译器该函数将通过堆栈而不是寄存器接收所有的参数。这个宏主要用于那些需要从用户空间通过系统调用接口调用的函数。在系统调

上图是Intel手册中对标志寄存器的图示,几个

一、概述 自从Linux内核代码迁移到Git以来,Linux内核配置/构建系统(也称为Kconfig / kbuild)已存在很长时间了。 二、Kconfig (Kernel config) menu