【问题标题】:Performance impact of -fno-strict-aliasing-fno-strict-aliasing 的性能影响
【发布时间】:2009-08-04 04:32:58
【问题描述】:

是否有任何研究或一组基准显示性能 由于在 GCC 中指定 -fno-strict-aliasing(或 在其他编译器中等效)?

【问题讨论】:

标签: c++ c performance compiler-construction


【解决方案1】:

它会因编译器而异,因为不同的编译器以不同的攻击级别实现它。 GCC 对此相当激进:启用严格别名将导致它认为“明显”等同于人类的指针(如foo *a; bar *b = (bar *) a;)不能别名,这允许一些非常激进的转换,但显然可以打破非- 精心编写的代码。由于这个原因,Apple 的 GCC 默认禁用严格别名。

相比之下,LLVM 甚至没有 严格的别名,而且,虽然这是计划中的,但开发人员表示他们计划在没有其他东西可以判断的情况下将其作为后备案例来实现等价。在上面的例子中,它仍然会判断 a 和 b 等价。如果它不能以任何其他方式确定它们的关系,它只会使用基于类型的别名。

根据我的经验,严格别名的性能影响主要与循环不变的代码运动有关,其中类型信息可用于证明循环内加载不能对正在迭代的数组进行别名,从而允许它们拉出循环。 YMMV。

【讨论】:

    【解决方案2】:

    我可以从经验告诉你(在 PS3 上用一个大型项目对此进行了测试,PowerPC 是一种架构,由于它有很多寄存器,实际上可以很好地从 SA 中受益)你将看到的优化是通常会非常本地化(范围明智)并且很小。在一个 20MB 的可执行文件上,它可能会刮掉 80kb 的 .text 部分(= 代码),而这一切都在小范围和循环中。

    此选项可以使您生成的代码比现在更轻量级和优化(考虑在 1% 到 5% 的范围内),但不要期望任何大的结果。因此,使用 -fno-strict-aliasing 的效果可能根本不会对您的性能产​​生很大影响。也就是说,拥有需要 -fno-strict-aliasing 的代码充其量只是次优情况。

    【讨论】:

    • 因为代码大小 == 速度?您的 PS3 示例既不存在也不存在。它是如何运行的?
    • 我在哪里说它更快?可能是 - 考虑到潜在的加载/存储被省略,这根本不是不可想象的 - 并且在任何情况下,更小的可执行文件在内存绑定的机器上是更可取的。所以它在这里,也在那里。
    • OP 询问性能影响,而您只讨论了代码大小。然后,您使用 ipso facto 论据来解释为什么您不会看到很大的性能差异。然后您将 Linux 内核称为“充其量是次优情况”。我想你可以明白为什么你投了反对票。
    • 在许多情况下,忽略严格别名规则的代码更容易阅读,并且即使在编译器(可能是由于配置)没有特别有效地优化 memcpy() 上也会产生不错的性能。如果严格别名不能产生有意义的性能提升,那么与编写可读代码和禁用严格别名相比,编写丑陋繁琐的代码不是次优的吗?
    【解决方案3】:

    这是 2004 年进行的研究的链接:http://docs.lib.purdue.edu/cgi/viewcontent.cgi?article=1124&context=ecetr,其中涉及严格别名对代码性能的影响。图 2.5 显示了 3% 到 10% 的相对改善。

    研究人员对性能下降的解释:

    通过检查汇编代码,我们发现降级是 寄存器分配算法。 GCC 实现了一个图形着色寄存器分配器[2, 3]。使用严格的混叠,变量的生存范围变得更长,导致高注册压力和“溢出”。使用更保守的别名,相同的变量也会在其(较短的)生存范围结束时产生内存传输。

    [2] 彼得·伯格纳、彼得·达尔、大卫·恩格布雷森和马修·T·奥基夫。溢出代码 通过干扰区域溢出最小化。在 SIGPLAN 编程会议上 语言设计与实现,第 287-295 页,1997 年。

    [3] Preston Briggs、Keith D. Cooper 和 Linda Torczon。图形着色的改进 寄存器分配。 ACM 编程语言和系统交易, 16(3):428–455,1994 年 5 月。

    【讨论】:

    • 您是否知道有任何研究着眼于通过严格别名也无法通过restrict 限定符实现的优化价值?跨度>
    • 我不知道,你知道任何可以满足这些要求的优化吗?
    • restrict 限定符不能有效地用来告诉编译器静态持续时间对象不会别名,并且在某些情况下,程序可能有多个可能相关的指向同一类型的指针,这些指针可能会别名彼此。基于类型的别名将允许在那些原本不可用的情况下进行一些优化。恕我直言,通过添加更好的限定符可以更好地处理这种情况(例如,在对象可能暴露给外部代码的情况下允许使用 register 限定符,但是在访问时它们可能表现得好像它们获得了一个新地址而不是通过指针)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-17
    • 2015-04-08
    相关资源
    最近更新 更多