CUDA矩阵与向量乘法并行计算问题:Stride设置异常
问题分析与解决
你的核心问题是任务拆分逻辑错误:矩阵向量乘法中,每个输出元素b[i]是矩阵A第i行与向量x的点积,需要对该行所有列j做A[i][j] * x[j]的累加。但你当前的代码让i和j都用同一个线程索引idx和步长stride,导致大部分(i,j)组合没被处理,最终只计算了对角线上的元素(比如stride=3时,只有i=j=0、1、2被计算),所以结果变成A[0][0]*x[0]、A[1][1]*x[1]、A[2][2]*x[2],也就是你看到的(1,4,9)。
修正后的Kernel代码
#define L 3 #define C L __managed__ int A[C][L], x[C]; __global__ void multiply(int *b) { int idx = blockIdx.x * blockDim.x + threadIdx.x; int stride = gridDim.x * blockDim.x; // 每个线程负责处理若干个输出元素i for (int i = idx; i < L; i += stride){ b[i] = 0; // 先清零,避免未初始化的垃圾值 // 对每个负责的i,遍历整行所有列j计算点积 for (int j = 0; j < C; j++){ b[i] += A[i][j] * x[j]; } } }
关键修正点
- 任务拆分逻辑:线程按输出元素
i分配,每个线程处理i = idx, idx+stride, idx+2*stride...的输出位置,确保每个i只被一个线程处理,无重复、无遗漏。 - 内层循环范围:对每个
i,遍历所有j(0到C-1)完成点积计算,保证每个元素都被累加到对应的b[i]中。 - 初始化
b[i]:必须先将b[i]清零,否则会累加内存中的初始垃圾值,导致结果错误。
为什么原代码会出错
当你用3个及以上线程时,stride >= 3,原代码中i和j都从idx开始以stride步长遍历,最终只有i=j=idx的位置被计算,相当于只做了对角线元素的乘法,完全漏掉了行内其他列的累加,自然得到错误结果。
内容的提问来源于stack exchange,提问作者yuggoth19
相关产品推荐
相关产品推荐

