博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
__asm__ __volatile__("": : :"memory");
阅读量:6198 次
发布时间:2019-06-21

本文共 3140 字,大约阅读时间需要 10 分钟。

参考:

 

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[0] += 1;        r = e[0];        d[1] += 1;        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:

 
00000000 
: 0: 4603 mov r3, r0 2: c805 ldmia r0, {r0, r2} 4: 3001 adds r0, #1 6: 3201 adds r2, #1 8: 6018 str r0, [r3, #0] a: 6808 ldr r0, [r1, #0] c: 605a str r2, [r3, #4] e: 4770 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[0] += 1;        r = e[0];        asm volatile("" ::: "memory");        d[1] += 1;        return r;}
 

So you'll get your instruction sequence as you want it to be:

 
00000000 
: 0: 6802 ldr r2, [r0, #0] 2: 4603 mov r3, r0 4: 3201 adds r2, #1 6: 6002 str r2, [r0, #0] 8: 6808 ldr r0, [r1, #0] a: 685a ldr r2, [r3, #4] c: 3201 adds r2, #1 e: 605a str r2, [r3, #4] 10: 4770 bx lr 12: 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.

 

转载地址:http://fbjca.baihongyu.com/

你可能感兴趣的文章
C语言中的迷途指针
查看>>
DeepMind AlphaStar:Demo很强大,但比赛输了
查看>>
北京教育软件创业公司招 .net工程师
查看>>
Elasticsearch聚合查询案例分享
查看>>
kali下Atscan查找admin登录界面
查看>>
Mac上使用Jenv管理多个JDK版本
查看>>
Exception in thread "main" java.lang.NoSuchMethodException: xxx.main([Ljava.lang.String;)
查看>>
Maven之 环境搭建
查看>>
java8 Lambda表达式的新手上车指南(1)--基础语法和函数式接口
查看>>
2016 VR年终大趴行业大佬齐聚,共同探讨AR、VR的商业化道路之变
查看>>
Apache Wicket 7.13.0 发布,Java Web 开发框架
查看>>
CompletableFuture的runAfterBothAsync
查看>>
ShenNiu.MVC管理系统
查看>>
今日科技联播:SpaceX将向国际空间站发送新设备:人工智能机器人
查看>>
指针和引用(4)指向指针的指针
查看>>
镁客网2016:这一年,我们深耕于“硬科技”不能自拔
查看>>
【前端开发】前端架构与具体的应用的矛盾,最终的简单才是王道。
查看>>
道德迷宫,不该成为无人驾驶发展的拦路虎!
查看>>
手撸一个 MVVM 不是梦
查看>>
阿里AI界的新伙伴,1秒钟自动生成20000条文案
查看>>