CONSTEXPR计算的编译时间性能

Compile-time performance of constexpr computation

本文关键字:时间性 性能 时间 编译 计算 CONSTEXPR      更新时间:2023-10-16

我有一些不平凡的C 17功能标记为constexpr。他们正在进行与图相关的计算(深度优先遍历)和一般算法(例如,查找,排序,唯一...)。

如果我尝试通过将结果放入constexpr全局变量来强制编译时进行评估,则可能发生3件事:

  1. 对于小型计算(为了提出一个想法,可以说〜100个节点的图,节点或多或少是整数),汇编很好(take 〜2s)
  2. 使用〜500个节点,汇编需要〜1分钟,并需要30GB的内存(!)。
  3. 使用〜1000个节点,汇编需要太多的记忆才能让我完成。

如果我删除constexpr预选赛并要求进行运行时计算,则编译和执行非常快(小于5s)

我将g 8.2与-o3 -std = c 17。

为什么要花这么长时间?G 是否以constexpr的编译时间优化问题而闻名?在汇编过程中,我应该从constexpr功能中获得什么性能?据我了解,编译器将自己变成了constexpr计算的解释器。但是毫无疑问,考虑到数据的尺寸很小,在Python中评估同一程序会非常快。

编辑:此处提到了此类问题(GCC开发人员的博客)

g 记录编译时结构。更重要的是,可以沿着进行编译时间结构,除非您小心

指数爆炸是非常有可能的,也许是您所看到的。

有降低编译时间复杂性的策略。避免深层递归。注意累积的符号长度。确保只需要检查您要采用的分支机构。

我的意思是,检查一个非常简单的:

std::conditional_t< (A<B), make_type_A<Ts...>, make_type_B<Ts...> >

此代码的作者可能只打算仅制作一种类型,但是此代码要求创建两种类型。

这不太可能是您的问题,但是运行constexpr代码时可能会出现类似的问题。

对于每个呼叫,请计算出所需状态的大小。加起来所需的总状态。扔进10倍的头顶。

您还可以分析您的问题的o通知是什么样本要比完成的2个要多。检查100、200、300、400、500尺寸图。尝试线性图,琐碎图,完整图,随机图具有恒定或百分比连接性。

编译时间增长的O通知可能会帮助您缩小问题所在的位置。如果是线性,多项式或指数级,您将要查看各种问题。

线性带有尖锐的拐点意味着您正在击中资源瓶颈。也许是记忆。开始绘制其他资源使用图,看看是否可以找到瓶颈。

,如果您不记录并放大"悬崖",则指数看起来很像线性和悬崖。可能有一个狭窄的部分,指数部分将恒定因子留在后面。

多项式变得有趣。多项式(日志图可以帮助找到)的顺序可以判断出哪种操作将您搞砸了。很像知道您的传统算法是O(n^3)意味着您正在寻找三循环。o(n^3)编译时间意味着您以某种方式实例化了三循环的等效。