__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 ...
随机推荐
- POJ-1002 解题报告
1.题目描述 http://poj.org/problem?id=1002 2.解题过程 按部就班来解题的话,这个题目很容易写出来,这是我的第一个版本的代码,思路是读入一行电话字符串,均转化为整型 ...
- Hadoop2.0新特性-持续追加【干货】
1.NAME NODE HA 2.NAME NODE Federation 3.HDFS 快照(目录快照) 4.HDFS 缓存 5.HDFS ACL 6.异构层级存储结构 -------------- ...
- SQL Server 2000的并发连接数是多少
开始->管理工具->性能(或者是运行里面输入 mmc)然后通过 添加计数器添加 SQL 的常用统计(MSSQL General Statistics) 然后在下面列出的项目里面选择 用户连 ...
- [置顶] Kendo UI开发教程: Kendo UI 示例及总结
前面基本介绍完Kendo UI开发的基本概念和开发步骤,Kendo UI的示例网站为http://demos.kendoui.com/ ,包含了三个部分 Web DemoMobile DemoData ...
- Delphi异形窗口之PNG
//1.单元内容 unit UnitAlienForm; interface uses Windows, Forms, Classes, Graphics; //从文件加载PNG procedure ...
- 从工程中删除Cocoapods
从工程中删除Cocoapods 分类: Xcode iOS 2013-08-24 01:11 5512人阅读 评论(2) 收藏 举报 CocoapodsiOSXcode 1. 删除工程文件夹下的Pod ...
- dns解析对SEO产生的影响
DNS 是域名系统 (Domain Name System) 的缩写,它是由解析器和域名服务器组成的.域名服务器是指保存有该网络中所有主机的域名和对应的IP地址,并具有将域名转换为IP地址功能的服务器 ...
- react-native 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。
Q: A:
- SQLite的37个核心函数
转载:http://www.feiesoft.com/00012/ abs(X) abs(X)返回 X 的绝对值. Abs(X) returns NULL if X is NULL. Abs(X) r ...
- JavaScript- 获取经度纬度
昨天获得一个小需求,需要取地理位置. 通过以下的JS能获得经度和纬 if(navigator.geolocation) { navigator.geolocation.getCurrentPositi ...