我想在 CUDA 中实现高斯消除。但是我在 if/else 中的线程同步有问题。
这是我的简单代码:
__device__ bool zr(float val) {
const float zeroEpsilon = 1e-12f;
return fabs(val) < zeroEpsilon;
}
__global__ void gauss(float* data, unsigned int size, bool* success) {
//unsigned int len = size * (size + 1);
extern __shared__ float matrix[];
__shared__ bool succ;
__shared__ float div;
unsigned int ridx = threadIdx.y;
unsigned int cidx = threadIdx.x;
unsigned int idx = (size + 1) * ridx + cidx;
matrix[idx] = data[idx];
if (idx == 0)
succ = true;
__syncthreads();
for (unsigned int row = 0; row < size; ++row) {
if (ridx == row) {
if (cidx == row) {
div = matrix[idx];
if (zr(div)) {
succ = false;
div = 1.0;
}
}
__syncthreads();
matrix[idx] = matrix[idx] / div;
__syncthreads();
}
else {
__syncthreads();
__syncthreads();
}
if (!succ)
break;
}
__syncthreads();
if (idx == 0)
*success = succ;
data[idx] = matrix[idx];
__syncthreads();
}
它是这样工作的:
- 将矩阵复制到共享内存中。
- 遍历行。
- 将行除以对角线上的值。
问题出在 for 循环内的 if/else 块内 - 死锁:
==Ocelot== PTX Emulator failed to run kernel "_Z5gaussPfjPb" with exception:
==Ocelot== [PC 30] [thread 0] [cta 0] bar.sync 0 - barrier deadlock:
==Ocelot== context at: [PC: 59] gauss.cu:57:1 11111111111111111111
==Ocelot== context at: [PC: 50] gauss.cu:54:1 11111111111111111111
==Ocelot== context at: [PC: 33] gauss.cu:40:1 00000000000000011111
==Ocelot== context at: [PC: 30] gauss.cu:51:1 11111111111111100000
我不知道为什么会这样。当我从 if/else 块中删除同步时,它可以工作。有人可以解释一下吗?