C语言 对setjmp/longjmp使用volatile的性能开销



要使setjmp/longjmp起作用,需要将局部变量声明为volatile。如果有人用-O3编译代码,易失性变量对性能的影响有多大?在x86多核平台上,它是很大还是很小?

在我看来,它只会增加一点开销,因为volatile变量仍然可以被缓存,并且从缓存中读取/写入非常快。意见吗?

作为一个快速的旁白,volatile的语义都依赖于平台/编译器。在IA64架构的MSVC等编译器上,volatile关键字不仅防止编译器对操作进行重新排序,而且还使用获取/释放语义执行每个读/写操作,这意味着存在内存屏障操作。另一方面,GCC只阻止编译器在读取/写入易失性内存位置之前/之后重新排序操作…在具有弱内存模型的平台上,不像在MSVC中那样维护获取-释放语义。

现在在x86上,由于其严格排序的内存模型,使用volatile关键字时存在的内存障碍不是问题,因此主要的惩罚将只是缺乏重新排序和编译器可以执行的其他优化。话虽如此,这将取决于您的代码看起来像什么。例如,如果您的代码中有一个紧循环,并且某些volatile限定变量实际上是循环不变量,那么如果这些内存位置被限定为非volatile,您将无法获得编译器可以做的一些优化。

影响取决于局部变量的数量以及代码对它们的处理。我相信可以为volatile的巨大影响编造一个极端的例子(例如,声明volatile变量的数组比CPU缓存大)。

似乎在实践中没有人想要维护所有变量都必须是volatile的代码。这意味着包含setjmp的函数可能会很小,可能只包含setjmp的东西。在这种情况下,将有很少或没有volatile变量,它们的"影响"应该确实很小。

最新更新