参考: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");的更多相关文章

  1. #define barrier() __asm__ __volatile__("": : :"memory") 中的memory是gcc的东西

    gcc内嵌汇编简介 在内嵌汇编中,可以将C语言表达式指定为汇编指令的操作数,而且不用去管如何将C语言表达式的值读入哪个寄存器,以及如何将计算结果写回C 变量,你只要告诉程序中C语言表达式与汇编指令操作 ...

  2. 转: __asm__ __volatile__内嵌汇编用法简述

    from: http://www.embedu.org/Column/Column28.htm __asm__ __volatile__内嵌汇编用法简述 作者:刘老师,华清远见嵌入式学院高级讲师,AR ...

  3. 内存屏障(Memory barrier)-- 转发

    本文例子均在 Linux(g++)下验证通过,CPU 为 X86-64 处理器架构.所有罗列的 Linux 内核代码也均在(或只在)X86-64 下有效. 本文首先通过范例(以及内核代码)来解释 Me ...

  4. 并行计算之Memory barrier(内存

    本文转载自:http://name5566.com/4535.html 参考文献列表:http://en.wikipedia.org/wiki/Memory_barrierhttp://en.wiki ...

  5. 理解 Memory barrier

    理解 Memory barrier(内存屏障) 发布于 2014 年 04 月 21 日2014 年 05 月 15 日 作者 name5566 参考文献列表:http://en.wikipedia. ...

  6. Linux内核同步机制之(三):memory barrier【转】

    转自:http://www.wowotech.net/kernel_synchronization/memory-barrier.html 一.前言 我记得以前上学的时候大家经常说的一个词汇叫做所见即 ...

  7. 理解 Memory barrier(内存屏障)无锁环形队列

    原文:https://www.cnblogs.com/my_life/articles/5220172.html Memory barrier 简介 程序在运行时内存实际的访问顺序和程序代码编写的访问 ...

  8. Memory barrier 简介

    Memory barrier Memory barrier 简介 程序在运行时内存实际的访问顺序和程序代码编写的访问顺序不一定一致,这就是内存乱序访问.内存乱序访问行为出现的理由是为了提升程序运行时的 ...

  9. 理解 Memory barrier(内存屏障)【转】

    转自:http://name5566.com/4535.html 参考文献列表:http://en.wikipedia.org/wiki/Memory_barrierhttp://en.wikiped ...

随机推荐

  1. 使用jQuery Mobile实现通讯录

    jQuery Mobile 通讯录 拨打电话作者:方倍工作室 地址: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional/ ...

  2. HDFS体系结构

    HDFS的设计目标 检测以及快速恢复硬件问题. 流式的数据访问. 移动计算比移动数据的代价小. 简化一致性模型. 超大规模数据集 异构软硬件平台之间的可移植性. HDFS的结构模型HDFS是一个主从的 ...

  3. linux appear packet loss solution

    故障排查: 早上突然收到nagios服务器check_icmp的报警,报警显示一台网站服务器的内网网络有问题.因为那台服务器挂载了内网的NFS,因此内网的网络就采用nagios的check_icmp来 ...

  4. [COCOS2D-X]AssetsManager

    转自:http://blog.csdn.net/xpwang168/article/details/8900764 资源更新方式分析 I zip整包更新 优点:省流量,速度快 缺点:有重复资源,需要打 ...

  5. mongod的主要参数解释

    mongod的主要参数有:

  6. OAuth 2.0介绍学习

    OAuth2.0是OAuth协议的下一版本,但不向后兼容OAuth 1.0即完全废止了OAuth1.0. OAuth 2.0关注客户端开发者的简易性.要么通过组织在资源拥有者和HTTP服务商之间的被批 ...

  7. UVaLive 7363 A Rational Sequence (二叉树)

    题意:给定一个二叉树,并对每一个进行编号和规定,现在给你一个值,问你是第几个. 析:这个题,我想了好久才想出来,这个真是数据结构练的太差了,不够扎实,这个题,应该从下向上推,如果分子大于分母,那么这个 ...

  8. HDU 5521 Meeting (最短路,dijstra)

    题意:有N个点,两个人,其中一个人住在点1,另一个人住在点n,有M个点集,集合内的数表示任意两点的距离为dis ,现在问,如果两个人要见面, 需要最短距离是多少,有哪几个点能被当成见面点. 析:分别对 ...

  9. IP访问SQL数据库设置

    http://wenku.baidu.com/link?url=mnjuPMo9qJvzluCHEvqVDawpuloKeGla05a2L3UtqzD_bF1VJMb7jHY4SBhuYH3-K_xF ...

  10. oracle对序列的操作

    select t.*, t.rowid from tbl_type t order by t.id desc Select SEQ_TBL_TYPE_ID.NextVal From Dual; ; ; ...