编译器内存障碍会产生影响,迫使编译器确保缓存在寄存器中的所有堆栈变量在屏障之前写入内存。
例如,GCC有以下声明:
asm inline ("" : : : "memory");
有没有办法告诉编译器(特别是GCC,但我也对其他人感兴趣)只对特定的变量做同样的效果?类似于以下想象的构造:
int x;
...
asm inline ("" : : : "memory(x)");
预期的行为是x和x的值只会被写入相应的内存位置,如果它恰好被缓存在寄存器中。
这样做的原因是我有一个特定的变量,我需要确保它不会缓存在寄存器中,以便硬件引擎可以读取它的值。但是,完整的编译器内存屏障将强制编译器向内存写入所有其他变量的值,这些变量可能会在该时间点缓存在寄存器中,这可能比我更多的数据需要写。我想知道是否有更具体的内容。
提前致谢!
答案 0 :(得分:5)
尝试{ int y = x; *(volatile int*)&x = y; }
并检查生成的程序集。
答案 1 :(得分:3)
由于您愿意使用gcc扩展,因此可以使用该功能的原子指令扩展:
__sync_bool_compare_and_swap(&myvar, 0, 0)
如果已经0
:),则将变量的值设置为0
,并且另外暗示该内存位置的完整顺序一致性。
答案 2 :(得分:2)
重新收集lkml上的一个线程,单变量仅编译器屏障的方法之一是:
#define forget(x) __asm__ __volatile__("":"=m"(x):"m"(x))
答案 3 :(得分:1)
我想你可以通过在asm
的输出值列表中指定变量来实现它:
__asm__ __volatile__ ("" : "=r" (x) : : )
有关详情,请参阅Extended Asm。
最好使用"g"
约束而不是"r"
作为更宽松的。
__asm__ __volatile__ ("" : "=g" (x) : : )
另外,我发现了内联汇编的另一个great howto。