如何改善巨型布尔表达式的编译时间?

Cap*_*nky 6 c++ optimization compilation

我需要对矢量执行相当复杂的检查,我必须重复数千次.为了提高效率,我将给定的公式转换为C++源代码,并在高度优化的二进制文件中进行编译,我在代码中调用它.公式总是纯粹的布尔值:只有&&,|| 而且!用过的.典型的源代码如下所示:

#include <assert.h>
#include <vector>

using DataType = std::vector<bool>;

static const char T = 1;
static const char F = 0;
const std::size_t maxidx = 300;

extern "C" bool check (const DataType& l);

bool check (const DataType& l) {
  assert (l.size() == maxidx);
  return (l[0] && l[1] && l[2]) || (l[3] && l[4] && l[5]); //etc, very large line with && and || everywhere
}
Run Code Online (Sandbox Code Playgroud)

我编译如下:

g++  -std=c++11 -Ofast -march=native -fpic -c check.cpp
Run Code Online (Sandbox Code Playgroud)

生成的二进制文件的性能至关重要.

它完美地利用了最近的测试用例和大量变量(300,如上所示).在这个测试用例中,g ++消耗超过100 GB的内存并永久冻结.

我的问题非常简单:如何简化编译器的代码?我应该使用一些额外的变量,摆脱矢量或其他东西?

EDIT1:好的,这是top工具的截图.

在此输入图像描述

cc1plus忙于我的代码.在检查功能取决于584个变量(抱歉在上面的例子中一个不精确的数)并且它包含450'000表达式.

我同意@ akakatak的评论如下.似乎g ++执行O(N ^ 2).

Cap*_*nky 0

这是一个有点死板的帖子,但我仍然应该分享我的结果。

Thilo 在上面的评论中提出的解决方案是最好的。它非常简单,并且提供了可测量的编译时间改进。只需将您的表达式分成相同大小的块即可。但是,根据我的经验,您必须仔细选择合适的子表达式长度 - 如果有大量子表达式,您可能会遇到执行性能显着下降的情况;编译器将无法完美地优化整个表达式。