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

在此示例中,一维数组的位置 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

问题是我们正在索引一维数组,因此为了映射它,我们需要将行索引乘以列数,因此遵循示例:

__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 回答