// 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;
}
}
答案 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
是预处理器定义或常量,则编译器可能能够展开内部循环并提供更多性能。
编辑:代码的第一个版本是在我的脑后插入了列主要排序,所以忽略这里的评论。应该以这种方式合并访问。