【问题标题】:Performance overhead of using volatile for setjmp/longjmp对 setjmp/longjmp 使用 volatile 的性能开销
【发布时间】:2023-03-12 13:02:02
【问题描述】:

要使 setjmp/longjmp 工作,您需要将局部变量声明为 volatile。如果有人使用 -O3 编译其代码,那么 volatile 变量对性能的影响有多大。在 x86 多核平台上它会很大还是只有一点点?

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

【问题讨论】:

  • 这可能会对您的代码造成重大的性能影响吗?如果是,是否有任何东西阻止您在使用和不使用 volatile 的情况下测量性能?
  • 关于这一点,除了您已经表达的观点之外,没有太多可以说的一般性。这在很大程度上取决于架构和使用模式。与相同但非volatile 代码相比,如果有很多加载/存储正在进行,请查看汇编程序。如果您仍然看不清楚,请对其进行基准测试,这是确定的唯一方法。此外,您只需声明那些变量volatile,您需要在longjmp 访问之前更改这些变量。根据我的经验,gcc 在检测这些情况方面非常出色。
  • 克里斯,我是从理论上讲的。

标签: c linux gcc x86 setjmp


【解决方案1】:

顺便说一句,volatile 的语义都取决于平台/编译器。在某些编译器上,例如具有 IA64 架构的 MSVC,volatile 关键字不仅可以防止编译器重新排序操作,它还可以使用获取/释放语义执行每个读/写操作,这意味着存在内存屏障操作。另一方面,GCC 仅阻止编译器在读取/写入易失性内存位置之前/之后重新排序操作......在具有弱内存模型的平台上,获取释放语义不会像使用MSVC。

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-21
      • 2015-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-21
      • 1970-01-01
      相关资源
      最近更新 更多