奇怪的性能问题

时间:2009-10-30 14:14:57

标签: performance g++ pointers alignment aliasing

我有一个与此类似的容器。

template <typename Nat, typename Elt>
class NatMap {
 public:
  Elt& operator[] (Nat nat) { 
    return tab [nat.GetRaw()];
  }
 private:
  Elt tab [Nat::kBound];
};

我想删除Elt有一个默认构造函数的要求:

template <typename Nat, typename Elt>
class NatMap {
 public:
  Elt& operator[] (Nat nat) { 
    return ((Elt*)tab) [nat.GetRaw()];
  }
 private:
  char tab [Nat::kBound * sizeof(Elt)];
};

我使用g ++ - 4.3并且这个代码在我的应用程序中比前一代码慢25%。不幸的是,减速并未体现在综合基准测试中。 我想这是关于编译器优化,别名,对齐或类似的东西。

我该怎样做才能恢复表现? (虽然不需要默认的构造函数)

更新

刚才我尝试了新的g ++ - 4.4,它为后面的代码提供了以下警告:

dereferencing pointer '<anonymous>' does break strict-aliasing rules

2 个答案:

答案 0 :(得分:1)

您可能遇到对齐问题。如果Elt是原始对齐类型以外的某种大小,那么通过放置到字符数组中将其分配可能涉及许多未对齐的读取,当编译器为您对齐时,您不会看到这些读取。或者您可能遇到一个称为加载命中存储的问题,某些处理器在将值写入内存然后立即将其读回时会显示;在那些处理器中,只要是管道,它就可以是一个停顿。

或者它可能完全不同,GCC会产生某种病理代码。

不幸的是,堆栈跟踪无法帮助追踪这些问题,因为它们看起来像加载操作(lwlb等),需要40个周期而不是1个周期。停顿在CPU内部的微代码中,而不是您编写的x86代码。但是使用-S命令行选项查看程序集可以帮助您弄清楚编译器实际发出的内容,以及它们在两个实现之间的区别。也许在一个版本中出现了一些糟糕的操作。

答案 1 :(得分:0)

小建议:不要试图做出有根据的猜测,比如编译器优化是不同的,你可以单步执行,也可以找出with this unorthodox method