2

これと同じような容器があります。

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
4

2 に答える 2

1

アライメントの問題が発生している可能性があります。Elt がネイティブのアライメント タイプ以外のサイズである場合、文字配列への配置を介して Elt を割り当てると、コンパイラがアライメントしたときに表示されない多くのアライメントされていない読み取りが発生する可能性があります。または、ロード ヒット ストアと呼ばれる問題が発生している可能性があります。これは、一部のプロセッサが値をメモリに書き込んですぐに読み戻すときに発生します。これらのプロセッサでは、パイプラインである限りストールになる可能性があります。

あるいは、GCC によるある種の異常なコード生成など、まったく別のものである可能性もあります。

残念ながら、スタック トレースはこれらの問題の追跡には役立ちません。これらの問題は、1 回ではなく 40 サイクルを要したロード操作 ( 、 など)lwのように見えるだけだからです。lbストールは、作成した x86 コードではなく、CPU 内のマイクロコードにあります。ただし、コマンドライン オプションを使用してアセンブリを調べると-S、コンパイラが実際に出力しているものと、2 つの実装間での違いを理解するのに役立ちます。たぶん、あるバージョンで悪い操作が発生している可能性があります。

于 2009-11-03T02:43:49.217 に答える
0

小さな提案: コンパイラの最適化が異なる場合など、知識に基づいた推測を試みるのではなく、シングルステップで行うか、この非正統的な方法で調べることができます。

于 2009-10-30T16:22:36.227 に答える