3

行列があり、行列の下三角部分にのみアクセスしたい場合。適切なスレッド インデックスを見つけようとしていますが、これまでのところ管理できていません。何か案は?下三角行列をループするインデックスが必要です。これが私の行列だとします。

1 2 3 4
5 6 7 8
9 0 1 2
3 5 6 7

インデックスは

1 
5 6
9 0 1
3 5 6 7

この例では、1D 配列の位置 0、4、5、8、9、10、12、13、14、15 です。

CPU ループは次のとおりです。

for(i = 0; i < N; i++){
    for(j = 0; j <= i; j++){
             .......

ここで、N は行数です。私はカーネルで何かを試していました:

 __global__ void Kernel(int N) {

        int row = blockIdx.x * blockDim.x + threadIdx.x;
        int col = blockIdx.y * blockDim.y + threadIdx.y;
        if((row < N) && (col<=row) )
           printf("%d\n", row+col);
      }

そして、次のように呼び出します。

 dim3 Blocks(1,1);
 dim3 Threads(N,N);
 Kernel<<< Blocks, Threads>>>(N);

しかし、まったく機能しません。私が得るもの:

0
1
2
2
3
4
4

2 に答える 2

8

スレッドのグリッドを起動してから、対角線より上にあるスレッドをすべて無効にします。つまり、スレッドの約 50% が何も実行しないため、非常に非効率的です。

コードの簡単な修正は、インデックスを修正することです。

__global__ void Kernel(int N)
{
  int row = blockIdx.x * blockDim.x + threadIdx.x;
  int col = blockIdx.y * blockDim.y + threadIdx.y;
  if((row < N) && (col<=row) )
    printf("%d\n", row * N + col);
}

おそらく、より効率的で複雑な解決策は、正しい数のスレッドを起動してインデックスを変換することです。出発点については、この回答を確認してください...

于 2012-09-11T12:32:20.667 に答える
3

問題は、1D 配列にインデックスを付けていることです。そのため、それをマップするには、行インデックスに列数を掛ける必要があるため、次の例に従います。

__global__ void Kernel(int N) {
        int row = blockIdx.x * blockDim.x + threadIdx.x;
        int col = blockIdx.y * blockDim.y + threadIdx.y;
        if((row < N) && (col<=row) )
           printf("%d\n", row*N + col);
 }
于 2012-09-11T12:00:57.973 に答える