【问题标题】:Switch optimization for many cases guarantees equal access time for any case? ( C++ )许多情况下的开关优化保证任何情况下的访问时间相等? (C++)
【发布时间】:2010-01-25 01:37:20
【问题描述】:

我在这里看到了针对特定语言的答案,关于使用跳转表优化超过 5 种情况的开关,以保证任何情况下的恒定访问时间。
C/C++ 是这样吗?
它特别适用于 gcc 吗?视觉工作室?
如果没有,按发生频率排序是否有帮助?

【问题讨论】:

  • 如果 C 可以很好地优化 switch 语句,似乎会让 C 成为“Go 杀手”......
  • 如果 6 个案例的散列速度更快,我会非常感到惊讶。也许是 25。当然,哈希表可能会减少访问时间的差异,但它是通过增加固定开销来实现的。
  • 我相信你明白,这只有在 switch 分支实际上并没有做太多事情的情况下才重要,并且如果 PC 实际上在很长一段时间内处于 switch 中,比如 10% 或更多。否则它基本上是量子噪声。

标签: c++ c optimization switch-statement


【解决方案1】:

该标准不保证 switch 语句将如何实现。我从未见过编译器生成哈希表,尽管有不少编译器会生成跳转表。除非我的记忆力比平时更差,否则当案例足够密集时(对于“足够”的不同值),VS 和 gcc 都可以生成跳转表。不幸的是,几乎不可能说(甚至必须弄清楚)按出现频率排序会有所帮助 - 不仅编译器之间不同,甚至同一编译器的不同版本之间也不同。

【讨论】:

  • @Pretruza:你可以修复你原来的帖子
  • 因为编译器实现者很懒惰,而且还不需要大开关数组。除非 unicode 出现。在此处查看性能比较:programming.sirrida.de/hashsuper.pdf 完美哈希是恒定的,跳转表仅适用于密集数组,elsif 链是线性的。
【解决方案2】:

【讨论】:

  • 链接已失效;有没有其他副本?
【解决方案3】:
  • C 和 C++ 不保证 switch 语句的运行时间。
  • 恐怕我不知道任何编译器的实现细节。这可能取决于优化标志。
  • 不能保证对案例进行排序会有所帮助,标准也没有规定,您的实现可能会也可能不会:
    • 根据编译器选项做不同的事情
    • 记录它的作用
    • 保证在未来的版本中不会改变它的功能
    • 完全忽略源中案例的顺序,并根据需要重新排序。当然,假设这些案例是“独立的”:没有失败;没有从一种情况开始并跨越另一种情况的变量声明;我没有忘记其他任何事情。

【讨论】:

    【解决方案4】:

    这就是编译器将为您做的事情。如果是 GCC,它将使用跳转表。

    【讨论】:

      【解决方案5】:

      c(以及扩展为 c++)仅打开整数类型,因此不需要散列。编译器通常会使用适合您正在编译的体系结构的习语。这可能是索引寻址(如果使用小范围)、跳转表或完全不同的东西。

      【讨论】:

      • 哈希不是必需的,但偶尔可以使用完美哈希作为跳转表的索引来优化一堆整数情况 - 基本上采用一组不连续的数字并将它们映射到一个连续的空间比你遍历二叉决策树的速度要快。这是否是任何编译器编写者都可以烦恼的优化是另一回事......
      • @Steve:我会相信你的话,但是对于我已经知道的足够组装甚至可以评论的架构(这些天大多很旧),跳转表会更快。甚至是一个两级跳转表来管理大整数范围内的稀疏目标。
      • 我可以想象的一个例外是一组二进制标志的完美哈希。 IE。如果所有“案例值”都是 2 的幂。
      • 或者假设情况是 147 的连续倍数。我强烈希望完美的哈希“除以 147”(并检查余数为 0),然后是跳转表,比任何通用的都要快转变。但我也不指望编译器会提出这个问题。在很多情况下,完美的散列会很快,困难在于找到能做到这一点的散列函数。而在 C 中,枚举类型并不能完全满足您的要求,因此对案例的完美哈希确实需要检查以捕获其他值。
      【解决方案6】:

      哈希似乎不是实现开关的有效方法,因为查找会导致额外的缓存未命中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-11-17
        • 1970-01-01
        • 2020-11-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多