CUDA中if/else块内的线程同步

CUDA中if/else块内的线程同步,cuda,parallel-processing,gaussian,thread-synchronization,Cuda,Parallel Processing,Gaussian,Thread Synchronization,我想在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

我想在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();
}
我不知道这是为什么。当我从if/else块中删除同步时,它就工作了。有人能给我解释一下吗?

\uu syncthreads()
等待一个threadblock的所有线程都达到这一点并完成计算。由于您的if/else条件,有些线程在else循环中等待,有些线程在if循环中等待,它们彼此等待。但是if循环中的线程永远不会到达else循环。

\uuu syncthreads()
等待一个threadblock的所有线程都到达该点并完成计算。由于您的if/else条件,有些线程在else循环中等待,有些线程在if循环中等待,它们彼此等待。但是if循环中的线程永远不会到达else循环。

\uu syncthreads()
正在执行此操作

线程
到达
\uuu syncthreads
作为指令时,它将阻止/暂停,当发生这种情况时
扭曲
(32个线程)也将阻止,它将阻止,直到同一
线程块
中的所有
线程都到达该语句

但是,如果同一
线程块中的一个扭曲或一个线程未达到相同的
\uuuu syncthreads
语句,它将死锁,因为至少有一个
线程等待所有其他
线程达到相同的语句,如果不发生,您将得到一个死锁

您现在要做的是,通过在if语句中放置一个
\uuuu syncthreads
来排除至少一个
线程参与
\uuuu syncthreads
。因此,死锁
\uuu syncthreads()
正在执行此操作

线程
到达
\uuu syncthreads
作为指令时,它将阻止/暂停,当发生这种情况时
扭曲
(32个线程)也将阻止,它将阻止,直到同一
线程块
中的所有
线程都到达该语句

但是,如果同一
线程块中的一个扭曲或一个线程未达到相同的
\uuuu syncthreads
语句,它将死锁,因为至少有一个
线程等待所有其他
线程达到相同的语句,如果不发生,您将得到一个死锁


您现在要做的是,通过在if语句中放置一个
\uuuu syncthreads
来排除至少一个
线程参与
\uuuu syncthreads
。因此,死锁

我正在使用GPU Ocelot模拟CUDA env。可能的重复我正在使用GPU Ocelot模拟CUDA env。可能的重复我认为
\u syncthreads()
锁定某个抽象对象(信号量或其他)。但在我看来,它锁定了这个声明。对我来说很奇怪。我猜它类似于抽签函数,抽象它是如何工作的
如果(uu popc(ballot())!=blockDim.x){block();}否则{notify()}
我认为
\uu syncthreads()
锁定了某个抽象对象(信号量或其他)。但在我看来,它锁定了这个声明。对我来说很奇怪。我猜它类似于ballot函数,抽象出它是如何工作的
if(uu popc(ballot())!=blockDim.x){block();}else{notify();}
==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