我想在CUDA中实现一个简单的矩阵乘法。矩阵的维度在运行时确定,我也想使用共享内存以获得性能提升。我已经实现了这样的功能,但每次运行它时,我都会收到此错误:
mulKernel launch failed: an illegal memory access was encountered
我也不确定是否可以使用malloc来分配共享内存。但是,如果我想使用这样的东西
__shared__ float matrM_sm[tile_width][tile_width];
编译器抱怨必须在运行时知道tile_width ...
我已经尝试了所有我能想到的东西,并尝试了各种建议,但没有一个有效。这是函数(可以找到完整的工作文件HERE):
__global__ void mulKernelSM(float *matrR, const float *matrM, const float *matrN,
const int m_x, const int m_y, const int n_x, const int n_y, const int tile_width)
{
int i, j;
extern __shared__ float shared[];
float *matrM_sm = shared;
float *matrN_sm = &shared[tile_width * tile_width];
int bx = blockIdx.x;
int by = blockIdx.y;
int tx = threadIdx.x;
int ty = threadIdx.y;
int row = by * tile_width + ty;
int col = bx * tile_width + tx;
float tmp;
int limit = ceil(m_y / (float) tile_width);
for (i = 0; i < limit; i++)
{
tmp = 0.0;
if (i * tile_width + tx < m_y && row < m_x)
matrM_sm[ty * tile_width + tx] = matrM[row * m_y + (i * tile_width + tx)];
else
matrM_sm[ty * tile_width + tx] = 0.0;
if (i * tile_width + ty < n_x && col < n_y)
matrN_sm[ty * tile_width + tx] = matrN[col + (i * tile_width + ty) * n_y];
else
matrN_sm[ty * tile_width + tx] = 0.0;
__syncthreads();
for (j = 0; j < tile_width; j++)
tmp += matrM_sm[ty * tile_width + j] * matrN_sm[j * tile_width + tx];
__syncthreads();
}
if (row < m_x && col < n_y)
matrR[row * n_y + col] = tmp;
}
基本布局应该工作,因为我还实现了没有共享内存的版本,工作得很好。下面列出了没有共享内存的功能:
__global__ void mulKernel(float *matrR, const float *matrM, const float *matrN,
const int m_x, const int m_y, const int n_x, const int n_y)
{
int row = blockIdx.y * blockDim.y + threadIdx.y;
int col = blockIdx.x * blockDim.x + threadIdx.x;
int i;
if ((row < m_x) && (col < n_y))
{
float tmp = 0.0;
for (i = 0; i < m_y; i++)
{
tmp += matrM[row * m_y + i] * matrN[col + n_y * i];
}
matrR[row * n_y + col] = tmp;
}
}
如果缺少任何信息,我会立即提供。
答案 0 :(得分:-1)
您换了row, col
。此外,我相信要获取全局线程索引,您应该执行此操作int x_global = threadIdx.x + blockDim.x * threadIdx.y