1

2つの行列(AとB)、2次元があります。そして、グローバルメモリに入れてポインタを介してアクセスする代わりに、テクスチャ2dに入れて使用すると、少しスピードアップすると思います。行列はそれほど大きくなく、さまざまな位置がさまざまなスレッドによって読み取られます。

したがって、現在、私のコードはグローバルメモリを使用しており、取得した値は正しいので、マトリックス内のすべての値を乗算しています。

A[i][j] * B[ p[i] ] [ p[j] ]

私がテストしているインスタンスの最適値は9552、別の値を取得することはできません。

9511だから私はテクスチャに移動しました、そして私が今得たので、いくつかのフェッチが間違った値を返すようです。

CUDAでテクスチャを検索していたところ、[0..n-1]でインデックスが付けられていることがわかりました。しかし、それらにはいくつかの正規化されたアクセスと、フィルタリングのような他のいくつかのものがあり、必要な値はネイバーの補間です。

テクスチャのデフォルトオプションは何ですか?多分それが問題です。プログラミングガイドでデフォルトが見つかりませんでした。

関連するコードは次のとおりです。

宣言:

texture<float,2> A_matrix;
texture<float,2> B_matrix;

割り当て:

HANDLE_ERROR( cudaMalloc( (void**)&_A, n * n * sizeof(float) ) );
HANDLE_ERROR( cudaMalloc( (void**)&_B, n * n * sizeof(float) ) );

Memcpy

HANDLE_ERROR( cudaMemcpy( _A, A, n * n * sizeof(float), cudaMemcpyHostToDevice ) );
HANDLE_ERROR( cudaMemcpy( _B, B, n * n * sizeof(float), cudaMemcpyHostToDevice ) );

バインディングと記述子(私はばかげているので2つ作成しました)

cudaChannelFormatDesc desc = cudaCreateChannelDesc<float>();
    cudaChannelFormatDesc desc2 = cudaCreateChannelDesc<float>();

    HANDLE_ERROR( cudaBindTexture2D( NULL, A_matrix,
                                   _A,
                                   desc, n, n,
                                   sizeof(float) * n ) );
    HANDLE_ERROR( cudaBindTexture2D( NULL, B_matrix,
                                   _B,
                                   desc2, n, n,
                                   sizeof(float) * n ) );

そして私がそれを使うところ

res += tex2D(A_matrix, i, j)  * tex2D(B_matrix, p[i], p[j]);

では、どうすればテクスチャを正しく使用できますか?それとも、このようになっているのでしょうか。

編集:

これは、このメモリアクセスを使用するコードであり、コメント行はテクスチャを使用せず、完全に機能します。

__device__ inline float datastruct::getPermutationValue(int* p)
{
    float res = 0;
    for(int i = 0 ; i < ints[data_n] ; i++)
        for(int j = 0 ; j < ints[data_n] ; j++)
            res += tex2D(A_matrix, i, j)  * tex2D(B_matrix, p[i], p[j]);
            //res += qap_A[i * ints[data_n] + j]  * qap_B[p[i] * ints[data_n] + p[j]];
    return res;
}
4

2 に答える 2

1

テクスチャはグラフィックスの必要性から生まれたものであり、そのため、標準によって定義されたいくつかの特異性があります。この場合、正確なポイントに到達していないという点で、提供している座標に問題が発生している可能性があります。これを試して:

res += tex2D(A_matrix, i+0.5f, j+0.5f)  * tex2D(B_matrix, p[i]+0.5f, p[j]+0.5f);

ちなみに、パフォーマンスを向上させるには、ピッチメモリまたはCUDAアレイの使用を検討する必要があります。詳細については、CUDAプログラミングガイドおよびリファレンスマニュアルを参照してください。

于 2010-11-26T09:44:36.953 に答える
1

申し訳ありませんが、CUDAの2Dテクスチャは苦痛になる可能性があります。たった150行の簡単なコードがあります。nvidiaフォーラムに投稿しました。コンパイルするには、SDKライブラリの1つが必要になると思います。私は、より複雑な操作のためにテクスチャを使ってあまり運がなかった。これがお役に立てば幸いです。コンパイルしてください。

于 2010-11-28T21:57:23.720 に答える