gpt4 book ai didi

C++:为什么访问类数据成员比访问全局变量慢?

转载 作者:太空宇宙 更新时间:2023-11-03 10:27:40 25 4
gpt4 key购买 nike

我正在实现一个计算量大的程序,在过去的几天里,我花了很多时间来熟悉面向对象的设计、设计模式和 SOLID 原则。我需要在我的程序中实现几个指标,所以我设计了一个简单的界面来完成它:

class Metric {
typedef ... Vector;
virtual ~Metric() {}
virtual double distance(const Vector& a, const Vector& b) const = 0;
};

我实现的第一个指标是 Minkowski 指标,

class MinkowskiMetric : public Metric {
public:
MinkowskiMetric(double p) : p(p) {}
double distance(const Vector& a, const Vector& b) const {
const double POW = this->p; /** hot spot */
return std::pow((std::pow(std::abs(a - b), POW)).sum(), 1.0 / POW);
private:
const double p;
};

使用此实现代码运行非常慢有人尝试使用全局变量而不是访问数据成员,我的最后一个实现没有完成工作但看起来像这样。

namespace parameters {
const double p = 2.0; /** for instance */
}

热点线看起来像:

        ...
const double POW = parameters::p; /** hot spot */
return ...

只需进行更改,代码在我的机器上的运行速度至少提高了 275 倍,在 Ubuntu 14.04.1 中使用带有优化标志的 gcc-4.8 或 clang-3.4。

这是一个常见的陷阱吗?有什么办法吗?我只是错过了什么吗?

最佳答案

这两个版本的区别在于,在一种情况下,编译器必须加载 p 并用它执行一些计算,而在另一种情况下,您使用的是全局常量,编译器可能可以直接替换。所以在一种情况下,生成的代码可能会这样做:

  1. 加载p
  2. 调用abs(a - b),将结果命名为c
  3. 调用pow(c, p),将结果命名为d
  4. 调用d.sum()(不管是什么意思),将结果命名为e
  5. 计算1.0/p,将结果命名为i
  6. 调用pow(e, i)

那是一堆库调用,库调用很慢。此外,pow 很慢。

当你使用全局常量时,编译器可以自己做一些计算。

  1. 调用abs(a - b),将结果命名为c
  2. pow(c, 2.0) 更高效地计算为 c * c,将结果命名为 d
  3. 调用d.sum(),将结果命名为e
  4. 1.0/2.00.5pow(e, 0.5)可以翻译成更高效的sqrt(e )

关于C++:为什么访问类数据成员比访问全局变量慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27987269/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com