__asm__ __volatile__ ("" : : : "memory")

本文详细解析了内存屏障(memory barrier)的基本概念及其实现方式。通过深入探讨__asm__,__volatile__和memory的作用,揭示了如何利用这些技术确保CPU正确地处理内存操作,防止不必要的优化行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.内存屏障(memory barrier)
  #define set_mb(var, value) do { var = value; mb(); } while (0)
  #define mb() __asm__ __volatile__ ("" : : : "memory")

1)set_mb(),mb(),barrier()函数追踪到底,就是__asm__ __volatile__("":::"memory"),而这行代码就是内存屏障。
2)__asm__用于指示编译器在此插入汇编语句
3)__volatile__用于告诉编译器,严禁将此处的汇编语句与其它的语句重组合优化。即:原原本本按原来的样子处理这这里的汇编。
4) memory强制gcc编译器假设RAM所有内存单元均被汇编指令修改,这样cpu中的registers和cache中已缓存的内存单元中的数据将作废。cpu将不得不在需要的时候重新读取内存中的数据。这就阻止了cpu又将registers,cache中的数据用于去优化指令,而避免去访问内存。
5)"":::表示这是个空指令。barrier()不用在此插入一条串行化汇编指令。在后文将讨论什么叫串行化指令。
6)__asm__,__volatile__,memory在前面已经解释

### C++ 中 `__asm__ volatile` 的用法 在嵌入式编程和其他低级操作场景下,内联汇编提供了一种直接控制硬件的方式。对于 GCC 编译器而言,在 C++ 代码中使用 `__asm__` 或者更推荐的形式 `asm` 关键字可以实现这一点。 当声明为 `volatile` 时,告知编译器这段汇编代码不应该被优化掉或重排,这通常用于访问特定寄存器、I/O端口或者其他需要严格顺序执行的操作[^1]。 下面是一个简单的例子展示如何利用带有约束条件的 `asm volatile` 来确保某些指令按照预期工作: ```cpp float fpenv; double sum; // 假设这里有一些初始化语句给定初始值给变量 fpenv = /* some value */; int x = 5, y = 7; // 使用 'memory' clobber 表明此段汇编会读写内存中的数据, // 防止编译器做出不安全假设并重新排列指令。 asm volatile ( "mtfsf 255,%1\n\t" : "=X" (sum) // 输出操作数列表 : "f" (fpenv), // 输入操作数列表 "r"(x), // 添加额外输入以创建依赖关系 "r"(y) ); // 这里的加法由于存在对前面 asm 的隐含依赖而不会提前移动到 asm 上方被执行 sum += static_cast<double>(x + y); ``` 上述代码片段通过指定合适的输出和输入参数以及必要的clobbers(如 `"memory"`),使得编译器能够理解哪些资源可能受到影响,并据此调整其优化策略。 此外需要注意的是,立即浮点数操作数仅限于目标平台支持相同格式的情况下才能正常使用;如果主机与目标机之间有不同的浮点表示,则可能导致不可预见的行为[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值