【问题标题】:Optimising C++ code block containing for and if优化包含 for 和 if 的 C++ 代码块
【发布时间】:2020-04-13 14:15:18
【问题描述】:

我正在解决一个问题,这里有一段代码的运行情况比理论上的预期差很多:

inline bool check(const int index, const float* f) const{
    for(int j=0; j<d; j++)
        if(points[index][j] != f[j])
            return false;
    return true;        
}

bool func(int p_cap, const float* f) const{
    int i = (p_cap - error > 0? p_cap - error: 0);
    int l = (p_cap + error + 1 < keyCount? p_cap + error + 1: keyCount);
    for(; i<l; i++)
        if(check(i, f))
            return true;
    return false;
}

这些函数在一个类中,pointskeyCount 都是该类的成员。 points 是一个keyCount*d 二维数组。 d 是一个全局变量。关于如何优化此代码块的任何帮助?谢谢...

编辑:

我正在使用插值在数组中进行搜索,并且我的数据是可能的。期望使用这种技术搜索任何点都会比线性搜索更快。我有这个期望的原因是因为error = 1。这意味着,对于任何一点,我都在查看 3 数组中的最多 3 不同点。我有一百万个这样的数组。每个存储正好 10 个点。线性搜索的预期值为N/2,这意味着我需要在到达查询点之前查看5(同样,预期/平均值)。因此,这个“插值代码”应该比线性搜索运行得更快,但这并没有发生。

使用的编译命令:

g++ -O3 -march=native -DNDEBUG test.cpp -o test

【问题讨论】:

  • d的值是多少?
  • 理论预期是什么?
  • check() 没有尺寸检查,很好。如果你有除 O(n) 以外的任何期望,那你就是在做梦。看起来您必须在最坏的情况下检查整个阵列。你也没有展示你是如何测量的,你的期望是什么等。获得更快的唯一方法是尽可能对数组进行排序并实现更快的搜索。
  • @PaulMcKenzie d 通常是 2 或 3
  • @bipll 我正在使用插值在数组中进行搜索,并且预计会比线性搜索更好

标签: c++ function loops optimization


【解决方案1】:

我不确定编译器是否已经这样做了,但你可以做两件事:

  • 使用 1 个 for 循环遍历数组(因为 C++ 将它们按顺序存储在内存中),这消除了多次索引和指针计算的需要,但前提是您要遍历所有条目并且所有条目都是可检查的。
  • 将其转换为单个 if 检查,在您的示例中,您在 check() 函数中使用 1,并且在 func() 函数中再次检查返回的值。

您需要检查编译后的代码,看看它是否已经应用了这些优化。

【讨论】:

  • 如果您使用不同的编译器标志(我正在使用),第一个由编译器完成。能否请您详细说明第二点?
  • @AnkitKumar 你的 check() 函数正在对每个条目进行 if 检查,然后它返回一个布尔值,然后在你的 func() 函数中检查(“再次以某种方式”)这个布尔值。最后,您可以省略所有 func() 的 if 检查,因为这些检查已被检查。
  • 我尝试了你所说的,如果没有 2 个 for 循环,我将无法做到这一点。现在有 2 个 for 循环,我不得不使用 goto 语句,我相信这会减慢代码速度。如果我错了,请纠正我,或者如果你知道,请提出不同的方法?
  • 嗯,您可以将第二个 for 循环放在第一个的正下方,而不是使用单独的函数。虽然我不确定编译器是否已经做了这个优化。
  • @AnkitKumar 我得到不同的结果,具体取决于使用函数 check() 与手动内联,试试吧:godbolt.org
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-12
  • 1970-01-01
  • 2012-11-13
  • 1970-01-01
  • 2013-01-17
相关资源
最近更新 更多