6

これに似た関数シグネチャがあります

void Mutliply(const MatrixMN& a, const MatrixMN& b, MatrixMN& out);

内部的に、マトリックス クラスにはコンポーネントfloat* data;を表す がありm x nます。aコンパイラにそれを伝え、出力行列にエイリアスを設定しbないようにして、大量のロードストアを実行しないようにしたいと思います。

どうすればそれを行うことができますか?関数シグネチャへのポインターを渡して__restrict(MSVC で) ポインターをマークできることはわかっていますが、オブジェクトにメモリへのポインターが含まれている参照渡しオブジェクトのイディオムを保持したいと思います。

__restrictまた、オブジェクト参照では機能しないことも知っています。

4

4 に答える 4

2

オプティマイザの動作方法によってはassert(&in1 != &out && &in2 != &out)、上部の がうまくいく場合があります。また、out パラメーターを削除して、オプティマイザーを信頼して余分なコピーを削除することもできます (もちろん、それが純粋な out パラメーターであると仮定します)。コードがインライン化の候補である場合、コンパイラはそれ自体でエイリアス化されていないことを確認する場合があります。restrict参照パラメーターで実際に機能しない場合は、関数呼び出しに余分なレベルを設定し、適切に制限されたポインターを受け入れる 2 番目の関数に 3 つすべてを渡すことができます。うまくいけば、それはあなたのためにインライン化されるでしょう。

于 2011-06-09T02:32:37.430 に答える
1

引数を取るエクスポートされていない(file- staticprivate)乗算関数を記述しfloat*、引数に。でマークを付けますrestrict。この関数をMultiply呼び出します。

于 2011-06-09T02:38:46.743 に答える
1

あなたは __restrict ポインターに慣れているように見えるので、私はあなたが知っていることを使用しますが、それでもラップして、参照を使用してインターフェースを提供できます。

void Multiply(const MatrixMN& a, const MatrixMN& b, MatrixMN& out) {
  if (&a == &b || &a == &out || &b == &out) {
    // indicate precondition violation however you like
    assert(!"precondition violated");
    abort();  // assert isn't always executed
  }
  else {
    DoMultiply(&a, &b, &out);
  }
}

void DoMultiply(MatrixMN const * __restrict a, MatrixMN const * __restrict b,
              MatrixMN * __restrict out)
{
  //...
}

ポインター バージョンを「非公開」にします。たとえば、「詳細」名前空間に配置したり、内部リンケージを付与したり (この場合は該当しません)、特別な名前を付けたりします。パラメータの代わりにローカル変数を使用して、関数本体を「else」内に配置することもできますが、上記のほうがきれいです。

于 2011-06-09T02:42:42.247 に答える
-1

マクロラッパーがコンパイル時__restrictに効果を発揮するのはどうですか: (以下は疑似コードで、チェックされていません):

#define Multiply(A,B,C) Multiply_restrict(&A, &B, &C)

中間メソッドは次のように定義されます。

inline void Multiply_restrict(const MatrixMN* __restrict pA,
            const MatrixMN* __restrict pB, MatrixMN* __restrict pC)
{
  Multiply_(*pA, *pB, *pC);
}

そして最後に_、オリジナルの後に を追加するだけMultiplyです:

void Mutliply_(const MatrixMN& a, const MatrixMN& b, MatrixMN& out);

したがって、最終的な効果は、呼び出しているものとまったく同じになります。

Multiply(x, y, answer);
于 2011-06-09T02:31:38.197 に答える