1

CPU 用と GPU 用の 2 つの行列クラスがあります。たとえばMatrixCudaMatrixそれぞれ と です。宣言と定義は、ファイル.h.cpp.cuhおよびにあり.cuます。でmain、私は持っています

Matrix<int2_>      foo1(1,2);
// Definition of the elements of foo1...
CudaMatrix<int2_>  foo2(1,2);

cout << typeid(foo1).name() << "\n";
cout << typeid(foo2).name() << "\n";

// Equality
foo2=foo1;

今、 aと a のoperator=間にオーバーロードはありませんが、次のオーバーロードがありますCudaMatrixMatrixoperator=

const CudaMatrix& operator=(const CudaMatrix<LibraryNameSpace::int2_>&);

2つの間CudaMatrix。何が起こるかは次のとおりです。

  1. この 2 つは、とtypeidの正しいクラスを返します。foo1foo2
  2. 上記のオーバーロードは、割り当てoperator=のために実行時にコンパイルされ、呼び出されます。foo2=foo1それどころか、コンパイル エラーが発生すると予想していました。
  3. 割り当ての結果は、!の正しい結果につながります。foo2

Visual Studio 2010 を使用し、リリース モードでコンパイルしています。

この明らかに非論理的な動作が発生する理由について、誰かがいくつかのヒントを持っていますか?

ありがとう。

4

1 に答える 1

2

これが機能する理由の鍵は、コピー コンストラクターと明示的なコピー代入演算子の両方があるためです。これら 2 つの要素が組み合わさることで、一見未定義のケースが正しく機能します。したがって、これを行うと:

Matrix<int2_>      foo1(1,2);
CudaMatrix<int2_>  foo2(1,2);

foo2 = foo1;

何が起こるかはこれと同等です:

Matrix<int2_>      foo1(1,2);
CudaMatrix<int2_>  foo2(1,2);

// foo2 = foo1;
{   
    CudaMatrix<int2_> x(foo1); // copy constructor
    foo2 = x; // Copy assignment
}

ここで注意する必要があるデバイスのメモリ使用量の影響があることに注意してください (つまり、2 つのデバイス メモリの割り当てと、フードの下にある API 呼び出しの 2 つのセット)。

これは CUDA 固有のものではなく、C++98 オブジェクト モデルの標準機能であることに注意してください。3 のルールがどのように機能するのか、なぜ機能するのか (そして、類似しているように見える反例がなぜ機能しないのか) について詳しく知りたい場合は、3 のルールを修正することをお勧めします。

于 2013-06-25T19:03:01.733 に答える