__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 ...
随机推荐
- 【转】Nginx系列(五)--nginx+tomcat实现负载均衡
原博文出于: http://blog.csdn.net/liutengteng130/article/details/47129909 感谢! Nginx占有内存少,并发能力强,事实上Nginx ...
- Hibernate之Session对象的相关方法以及持久化对象的状态
一.持久化对象的状态 站在持久化的角度, Hibernate 把对象分为 4种状态: 持久化状态,临时状态,游离状态,删除状态.Session 的特定方法能使对象从一个状态转换到另一个状 ...
- log4j2使用总结
一.Log4j有三个主要的组件:Loggers,Appenders和Layouts,这里可简单理解为日志级别,日志要输出的地方和日志格式 1. Logger Logger的日志级别有6级,分别是TRA ...
- Web Service学习之九:Restful WebService
1.Rest 2.Rest webService 3.SpringMVC Restful 参考: http://spring.io/guides/gs/rest-service/ http://www ...
- HDU 5802 Windows 10 (贪心+dfs)
Windows 10 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5802 Description Long long ago, there was ...
- JSF 2 password example
In JSF, you can use the <h:inputSecret /> tag to render a HTML input of type="password&qu ...
- Spring InitializingBean and DisposableBean example
In Spring, InitializingBean and DisposableBean are two marker interfaces, a useful way for Spring to ...
- Labview中创建属性节点和调用节点的用法
创建属性节点 个人感觉有点像C中的指针 创建调用节点
- CodeForces 560B Gerald is into Art
Gerald is into Art time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- 去掉 CONSOLE 窗口(转)
建立一个win32 console application的话,linker的/subsystem选项应该为CONSOLE,可以在VC开发环境的project->setting->link ...