__asm__ __volatile__("": : :"memory");
参考:http://stackoverflow.com/questions/14950614/working-of-asm-volatile-memory
asmvolatile("":::"memory");
creates a compiler level memory barrier forcing optimizer to not re-order memory accesses across the barrier.
For example, if you need to access some address in a specific order (probably because that memory area is actually backed by a different device rather than a memory) you need to be able tell this to the compiler otherwise it may just optimize your steps for the sake of efficiency.
Assume in this scenario you must increment a value in address, read something and increment another value in an adjacent address.
int c(int *d, int *e) {
int r;
d[] += ;
r = e[];
d[] += ;
return r;
}
Problem is compiler (gcc in this case) can rearrange your memory access to get better performance if you ask for it (-O). Probably leading to a sequence of instructions like below:
<c>:
: mov r3, r0
: c805 ldmia r0, {r0, r2}
: adds r0, #
: adds r2, #
: str r0, [r3, #]
a: ldr r0, [r1, #]
c: 605a str r2, [r3, #]
e: bx lr
Above values for d[0] and d[1] are loaded at the same time. Lets assume this is something you want to avoid then you need to tell compiler not to reorder memory accesses and that is to use asm volatile("" ::: "memory").
int c(int *d, int *e) {
int r;
d[] += ;
r = e[];
asm volatile("" ::: "memory");
d[] += ;
return r;
}
So you'll get your instruction sequence as you want it to be:
<c>:
: ldr r2, [r0, #]
: mov r3, r0
: adds r2, #
: str r2, [r0, #]
: ldr r0, [r1, #]
a: 685a ldr r2, [r3, #]
c: adds r2, #
e: 605a str r2, [r3, #]
: bx lr
: bf00 nop
It should be noted that this is only compile time memory barrier to avoid compiler to reorder memory accesses, as it puts no extra hardware level instructions to flush memories or wait for load or stores to be completed. CPUs can still reorder memory accesses if they have the architectural capabilities.
This sequence is a compiler memory access scheduling barrier, as noted in the article referenced by Udo. This one is GCC specific - other compilers have other ways of describing them, some of them with more explicit (and less esoteric) statements.
__asm__ is a gcc extension of permitting assembly language statements to be entered nested within your C code - used here for its property of being able to specify side effects that prevent the compiler from performing certain types of optimisations (which in this case might end up generating incorrect code).
__volatile__ is required to ensure that the asm statement itself is not reordered with any other volatile accesses any (a guarantee in the C language).
memory is an instruction to GCC that (sort of) says that the inline asm sequence has side effects on global memory, and hence not just effects on local variables need to be taken into account.
__asm__ __volatile__("": : :"memory");的更多相关文章
- #define barrier() __asm__ __volatile__("": : :"memory") 中的memory是gcc的东西
gcc内嵌汇编简介 在内嵌汇编中,可以将C语言表达式指定为汇编指令的操作数,而且不用去管如何将C语言表达式的值读入哪个寄存器,以及如何将计算结果写回C 变量,你只要告诉程序中C语言表达式与汇编指令操作 ...
- 转: __asm__ __volatile__内嵌汇编用法简述
from: http://www.embedu.org/Column/Column28.htm __asm__ __volatile__内嵌汇编用法简述 作者:刘老师,华清远见嵌入式学院高级讲师,AR ...
- 内存屏障(Memory barrier)-- 转发
本文例子均在 Linux(g++)下验证通过,CPU 为 X86-64 处理器架构.所有罗列的 Linux 内核代码也均在(或只在)X86-64 下有效. 本文首先通过范例(以及内核代码)来解释 Me ...
- 并行计算之Memory barrier(内存
本文转载自:http://name5566.com/4535.html 参考文献列表:http://en.wikipedia.org/wiki/Memory_barrierhttp://en.wiki ...
- 理解 Memory barrier
理解 Memory barrier(内存屏障) 发布于 2014 年 04 月 21 日2014 年 05 月 15 日 作者 name5566 参考文献列表:http://en.wikipedia. ...
- Linux内核同步机制之(三):memory barrier【转】
转自:http://www.wowotech.net/kernel_synchronization/memory-barrier.html 一.前言 我记得以前上学的时候大家经常说的一个词汇叫做所见即 ...
- 理解 Memory barrier(内存屏障)无锁环形队列
原文:https://www.cnblogs.com/my_life/articles/5220172.html Memory barrier 简介 程序在运行时内存实际的访问顺序和程序代码编写的访问 ...
- Memory barrier 简介
Memory barrier Memory barrier 简介 程序在运行时内存实际的访问顺序和程序代码编写的访问顺序不一定一致,这就是内存乱序访问.内存乱序访问行为出现的理由是为了提升程序运行时的 ...
- 理解 Memory barrier(内存屏障)【转】
转自:http://name5566.com/4535.html 参考文献列表:http://en.wikipedia.org/wiki/Memory_barrierhttp://en.wikiped ...
随机推荐
- 【恒天云技术分享系列11】Sheepdog简介
sheepdog是近几年开源社区新兴的分布式块存储文件系统,采用完全对称的结构,没有类似元数据服务的中心节点.这种架构带来了线性可扩展性,没有单点故障和容易管理的特性.对于磁盘和物理节点,SheepD ...
- python日志输出
import logging logger = logging.getLogger() #生成一个日志对象,()内为日志对象的名字,可以不带,名字不给定就是root,一般给定名字,否则会把其他的日志输 ...
- html5+css3中的background: -moz-linear-gradient 用法
在CSS中background: -moz-linear-gradient 让网站背景渐变的属性,目前火狐3.6以上版本和google浏览器支持这个属性. background: -moz-linea ...
- [转载]Linux LVM硬盘管理及LVM扩容
最近项目中一直在用Linux,其中涉及到了Linux的LVM,本来想自己写一篇关于LVM的文章,搜了一下,发现了一篇更好的,转载过来,也感谢作者gaojun 原文Linux LVM硬盘管理及LVM扩容 ...
- HDU 1312 http://acm.hdu.edu.cn/showproblem.php?pid=1312
#include<stdio.h> #include<string.h> #include<math.h> #include<stdlib.h> #de ...
- [iOS 多线程 & 网络 - 2.0] - 发送接收 服务器信息
A.搭建java服务器 使用eclipse.tomcat和struts2框架搭建一个简单的服务器 1.准备好合适版本的JDK.eclipse EE.tomcat.struts2 框架包 2.配置JDK ...
- Linux 的进程组、会话、守护进程
一.进程组ID 每个进程都属于一个进程组.每个进程组有一个领头进程.进程组是一个或多个进程的集合,通常它们与一组作业相关联,可以接受来自同一终端的各种信号.每个进程组都有唯一的进程组ID(整数,也可以 ...
- Oracle创建dblink报错:ORA-01017、ORA-02063解决
Oracle环境:oracle 10.2.0.1 创建的 public dblink 连接oracle 11.2.0.3 ORA-01017: invalid username/password; l ...
- MAT(2)安装Memory Analyzer
http://www.eclipse.org/mat/ 两大功能: 1.find memory leaks 2.reduce memory consumption 安装步骤: 1. 打开 eclips ...
- error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏的解决方案
首先,卸载相关的软件,然后删除所有和virtual studio相关的目录 然后如果还出现该问题,则: Mark一下,解决方法:将嵌入清单设置为"否" 发生场合:在用 C++写一个 ...