线程索引计算
本文档是线程索引计算的速查手册,提供常用的索引计算公式和模式。
内置变量
每个线程通过内置变量获取其在层次结构中的位置:
| 变量 | 含义 | 维度 |
|---|---|---|
threadIdx | 线程在线程块内的索引 | (x, y, z) |
blockIdx | 线程块在网格内的索引 | (x, y, z) |
blockDim | 线程块的维度大小(线程数) | (x, y, z) |
gridDim | 网格的维度大小(线程块数) | (x, y, z) |
索引计算公式
一维索引(最常用)
// 全局线程 ID
int idx = blockIdx.x * blockDim.x + threadIdx.x;
全局 ID = 线程块索引 × 线程块大小 + 线程索引
示例:
__global__ void vectorAdd(const float* a, const float* b, float* c, int n) {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx < n) {
c[idx] = a[idx] + b[idx];
}
}
二维索引(图像处理常用)
// 二维线程块内的线程 ID
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
// 转换为一维索引(行优先)
int idx = y * width + x;
示例:
__global__ void imageKernel(float* input, float* output, int width, int height) {
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
if (x < width && y < height) {
int idx = y * width + x;
output[idx] = input[idx] * 2.0f;
}
}
三维索引(体积数据常用)
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
int z = blockIdx.z * blockDim.z + threadIdx.z;
// 转换为一维索引
int idx = (z * height + y) * width + x;
边界检查
// 始终检查边界,防止越界访问
if (idx < n) {
// 安全访问
data[idx] = data[idx] * 2.0f;
}