首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >gcc中用于x86处理器的编译器障碍的运行时开销

gcc中用于x86处理器的编译器障碍的运行时开销
EN

Stack Overflow用户
提问于 2016-08-10 23:01:25
回答 1查看 347关注 0票数 1

我正在研究在x86 env中使用编译器屏障(在gcc中)的副作用/运行时开销。

编译器屏障: asm易失性(:“内存”)

GCC文档讲述了一些有趣的事情( https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html )

节选:

" memory“clobber告诉编译器,程序集代码对输入和输出操作数中列出的项以外的项执行内存读或写操作(例如,访问一个输入参数所指向的内存)。为了确保内存包含正确的值,GCC可能需要在执行asm之前将特定的寄存器值刷新到内存中。此外,编译器并不假设在asm之后从内存读取的任何值保持不变;它会根据需要重新加载它们。使用“内存”块可以有效地形成编译器的读/写内存屏障。

问题:

1)哪些寄存器值被刷新?

2)为什么要把它冲红?

3)举例?

4)除登记冲洗外,是否还有其他费用?

EN

回答 1

Stack Overflow用户

发布于 2016-08-10 23:30:15

另一个线程可能有指针指向的每个内存位置都需要在屏障之前更新,然后再重新加载。因此,在寄存器中存在的任何这样的值都需要存储(如果是脏的),或者只是“忘记”如果寄存器中的值只是内存中仍然存在的值的副本。

有关gcc dev的引用,请参见这是gcc的非错误报告。"memory" clobber只包含可以间接访问的内存(因此可以在此或另一个编译单元中获取地址)。

除挂号冲洗外,还有其他开销吗?

一个屏障可以防止优化,比如把一个商店从循环中挖出来,但这通常是你使用障碍的原因。确保您的循环计数器和循环变量是局部变量,没有将它们的地址传递给编译器看不到的函数,否则必须在循环中溢出/重新加载它们。让引用逃离您的函数总是一个潜在的优化问题,但它几乎是一个有障碍的更坏代码的保证。

为什么?

这就是障碍的关键所在:因此,值被同步到内存中,从而防止编译时重新排序。

asm volatile( ::: "memory" )是(确切的?)等价于atomic_signal_fence(memory_order_seq_cst) (而不是atomic_thread_fence,它需要mfence指令在x86上实现)。

示例:

有关原因的更多信息,请参见Jeff的编译时内存排序文章,以及实际x86 asm的示例。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38884893

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档