我正在尝试将cuda输入数组复制到共享内存数组中。前n个值完美地复制到共享数组中,但是此后发生了一些非常奇怪的模式。谁能找到我在做什么错/这里发生了什么?
我尝试使用s_x [tid] = x [tid],s_x [row] = x [row]以及其他两个组合。我知道他们在逻辑上是没有道理的,但必须尝试一切。
这是我写的内核函数:
__global__ void mv_cuda_shared(float* y, float* A, float* x, int n)
{
extern __shared__ float s_x[];
int row = blockIdx.x * blockDim.x + threadIdx.x;
int tid = threadIdx.x;
s_x[row] = x[row];
__syncthreads();
if(tid == 0 && row == 0)
for(int i = 0; i < n; i++){printf("s_x[%d] = %10.6f x = %10.6f\n", i, s_x[i], x[i]);}
float temp = 0;
if(row < n)
{
for(int k = 0; k < n; k++)
{
temp += (A[row*n + k] * s_x[k]);
}
}
y[row] = temp;
}
这是我在main方法中调用它的地方(省略所有cuda malloc和复制):
mv_cuda_shared<<<(N/BLOCK_SIZE), BLOCK_SIZE, N*sizeof(float)>>>(d_y, d_A, d_x, N);
所以我希望s_x匹配x。但是,相反,前N个(n = N)元素被正确复制,但是其余元素似乎遵循一个模式。例如,s_x [N-1]之后的4个条目说为1。然后,之后的4个条目为.24566 ....(我检查一下,并且该数字甚至不在原始数组中)。那么,谁能看到我做错了什么?
答案 0 :(得分:1)
此代码中的所有内容都没有多大意义,但是,如果要真正地为每个块将全局存储阵列的n
个元素加载到共享内存中,则复制代码必须类似于:
extern __shared__ float s_x[];
int tid = threadIdx.x;
for(int i=tid; i<n; i+=blockDim.x) {
s_x[i] = x[i];
}
__syncthreads();
但是,我怀疑这确实是您所需要的,并且怀疑您可能怀有s_x
在所有块之间共享的(不正确的)概念,而不是在块范围内共享,这意味着每个块都有其自己的位置。在共享内存中拥有该阵列的完整副本。