【发布时间】:2015-01-16 15:26:57
【问题描述】:
我正在实现一个计算量很大的程序,在过去的几天里,我花了很多时间来熟悉面向对象的设计、设计模式和 SOLID 原则。我需要在我的程序中实现几个metrics,所以我设计了一个简单的界面来完成它:
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。
这是一个常见的陷阱吗? 有什么办法吗? 我只是错过了什么吗?
【问题讨论】:
-
在你的
MinkowskiMetric中复制一个const。 -
另外,您是否正确复制了您的课程
Metric?distance前面确实有一个virtual,对吧? -
另外,如果您追求速度,您可以尝试熟悉静态多态性的概念。我假设指标被多次调用,因此您可能希望将指标设为模板参数。
-
我不认为 virtual 是问题,因为 = 0 意味着该方法应该被覆盖,使成员 p const 也无济于事。
-
我敢打赌这是一个缓存未命中问题。指针间接和虚函数的使用让我怀疑每次必须通过对象的指针查找
p成员时,缓存都会丢失。将其与在间接级别少一级的全局变量中加载进行比较。
标签: c++ oop gcc optimization clang