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;
}