CUDA:在两个维度中访问任意长矩阵

时间:2011-05-21 09:29:54

标签: matrix cuda rows

嘿那里, 目前我正在使用仅在一个维度上编入索引的线程来访问矩阵的所有元素,如:

// Thread-ID
int idx = blockIdx.x * blockDim.x + threadIdx.x;
// Offset:
int offset = gridDim.x * blockDim.x;

while(idx < MATRIX_ROWS * MATRIX_COLS)
{   
    row = idx % MATRIX_ROWS;
    col = idx / MATRIX_ROWS;    

    matrix[ row ][ col ] = ...;
    idx += offset;
}

现在我想知道如何使用二维索引访问任意长矩阵。我希望一个块总是访问一行的单个元素。类似的东西(x-index引用cols,y-index引用矩阵的行):

// Thread-IDs
int idx = blockIdx.x * blockDim.x + threadIdx.x;
int idy = blockIdx.y * blockDim.y + threadIdx.y;

// Offset:
int offset = gridDim.x * blockDim.x;

while(idx < MATRIX_COLS)
{   
    matrix[ idy ][ idx ] = ...;
    idx += offset;
}

现在让我们假设在调用内核时矩阵的行数多于我启动的块:当启动N个块时,矩阵的前N行是正确处理的,但其他行呢?你会怎么做? 谢谢!

编辑:我提出了一个想法,但我不知道这是不是'丑陋'的编码!?

// Thread-IDs
int idx0 = blockIdx.x * blockDim.x + threadIdx.x;
int idx = idx0;
int idy = blockIdx.y * blockDim.y + threadIdx.y;

// Offset:
int offsetx = gridDim.x * blockDim.x;
int offsety = gridDim.y * blockDim.y;

while(idx < MATRIX_COLS && idy < MATRIX_ROWS)
{   
    matrix[ idy ][ idx ] = ...;

    idx += offsetx;
    if(idx > MATRIX_COLS)
    {
        // Jump to nex row and start from 'beginning' concerning columns
        idy += offsety;
        idx = idx0;
    }
}

1 个答案:

答案 0 :(得分:1)

也许你正在寻找这样的东西?

// Thread-IDs
int idx = blockIdx.x * blockDim.x + threadIdx.x;
int idy = blockIdx.y * blockDim.y + threadIdx.y;

// Offset:
int offsetx = gridDim.x * blockDim.x;
int offsety = gridDim.y * blockDim.y;

for(row = idy; row < MATRIX_ROWS; i+=offsety) {
    float * pos = matrix + row;

#pragma unroll
    for(col = idx; col < MATRIX_COLS; col+=offsetx) {
        pos[col] = .....;
    }
}

如果MATRIX_COLS是预处理器定义或常量,则编译器可能能够展开内部循环并提供更多性能。

编辑:代码的第一个版本是在我的脑后插入了列主要排序,所以忽略这里的评论。应该以这种方式合并访问。