3

C++ AMP を使い始めたばかりですが (学習方法として)、パフォーマンスに関して期待した結果が得られません。助けてください

解決する問題は非常に単純です。私は Vector と Matrix 構造を持っています (C++ コード、ところで私は C++ の初心者です)。

struct Vector
{
    public : float X, Y, Z;
};

struct Matrix
{
    public : float M11, M12, M13, M14,
                   M21, M22, M23, M24,
                   M31, M32, M33, M34,
                   M41, M42, M43, M44;
};

目標は、同じ行列に何百万ものこれらのベクトルを何度も乗算することです。計算を行うコードは次のとおりです。

Vector compute(const Matrix matrix, const Vector vector) restrict(amp,cpu)
{
    float tx = vector.X;
    float ty = vector.Y;
    float tz = vector.Z;

    Vector result;

    result.X = (matrix.M11 * tx) + (matrix.M12 * ty) + (matrix.M13 * tz) + matrix.M14;
    result.Y = (matrix.M21 * tx) + (matrix.M22 * ty) + (matrix.M23 * tz) + matrix.M24;
    result.Z = (matrix.M31 * tx) + (matrix.M32 * ty) + (matrix.M33 * tz) + matrix.M34;

    return result;
}

これで、このメソッドを CPU または GPU で実行できます。

CPU:

Vector* cpu_compute(const Matrix matrix, const Vector *vectors, const int size)
{
    Vector *result = (Vector*)malloc(size * sizeof(Vector));

    for (int i = 0; i < size; ++i)
    {
        result[i] = compute(matrix, vectors[i]);
    }

    return result;
}

GPU:

Vector* gpu_compute(const Matrix matrix, const Vector *vectors, const int size)
{
    Vector *result = (Vector*)malloc(size * sizeof(Vector));

    array_view<const Vector, 1> vectors_view(size, vectors);
    array_view<Vector, 1> result_view(size, result);

    accelerator acc = pick_accelerator();

    parallel_for_each(acc.default_view, vectors_view.extent, [=](index<1> idx) restrict(amp)
    {
        result_view[idx] = compute(matrix, vectors_view[idx]);
    });

    return result;
}

このコードを 2020 万のベクトルで実行すると、次の結果が得られます。

  • CPU (C++): 226ms
  • CPU (C#): 223ms
  • GPU : 339ms

そして、私にはいくつかの驚きがあります。まず、C# と C++ のコードはほぼ同じ速度で実行されます。第二に、GPU は期待したほど高速ではありません。

メモリ転送でペナルティを支払わなければならないことは知っていますが、この例ではそれほど目立つとは思いませんでした。投入するデータの量に関係なく、GPU は常に遅くなります。これは、私が何か間違ったことをしていることを意味します。そうしないと、シングル コア CPU に負けたとしても、GPU を使用してゲームをプレイする人は誰もいないでしょう。

質問: この種の計算を CPU よりも GPU で実行する方法はありますか?

ありがとう

参考までに: Windows 7 を実行しています (これにより、WARP を使用できなくなります)、NVIDIA GeForce GTX 690 および Intel Core i7 3930k を搭載しています。

4

2 に答える 2

3

現時点では、結果データを GPU にコピーするだけのオーバーヘッドが発生しています。

array_view<Vector, 1> result_view(size, result);
result_view.discard_data()

このデータがコピーされないように、discard_data() を呼び出す必要があります。

これを考慮しても、実行している作業量が GPU との間のコピーのコストを隠していないため、ここで大幅な速度向上が見られる可能性は低いです。

別の補足事項。C++ バージョンをループとして記述して、コンパイラーが計算を自動的にベクトル化できるかどうかを確認してみてください。これを行うのは簡単で、大幅なスピードアップが得られる可能性があります。

自動並列化と自動ベクトル化

于 2013-09-07T17:58:21.233 に答える
2

おそらく、メモリアクセスと計算の比率が悪いのでしょう。

メモリアクセスは高価です (CPU から GPU へのコピーとその逆) が、コピーされたメモリでの計算は安価です (強力な GPU)。

計算はほとんど行わず、頻繁に新しい値にアクセスします。

これが事実であることを確認するには、計算をコメントアウトして、実行時間 (コピーのみ) を確認します。

また、初心者の方は、 codeplexで amp book のサンプルを入手してください。ここでは、何がどのように機能するかについてもよく理解できます。

于 2013-07-03T22:11:36.447 に答える