C++ CUDA奇怪行为访问向量

C++ CUDA奇怪行为访问向量,c++,cuda,C++,Cuda,我在cuda中实现了一个简单的fft程序。这是内核函数: __global__ void fftKernel(cuComplex* dev_samples, size_t length, size_t llog, Direction direction) { int tid = threadIdx.x + blockDim.x * blockIdx.x; if (tid < length /

我在cuda中实现了一个简单的fft程序。这是内核函数:

__global__
void fftKernel(cuComplex* dev_samples,
              size_t length,
              size_t llog,
              Direction direction)
{
    int tid = threadIdx.x + blockDim.x * blockIdx.x;
    if (tid < length / 2) {

        // First step, sorts data with bit reversing and compute new coefficients;
        cuComplex c1 = dev_samples[bit_reverse(tid * 2) >> (32 - llog)];
        cuComplex c2 = dev_samples[bit_reverse(tid * 2 + 1) >> (32 - llog)];

        dev_samples[tid * 2] = cuCaddf(c1, c2);
        dev_samples[tid * 2 + 1] = cuCsubf(c1, c2);

        __syncthreads();

        int k = tid * 2;
        int block_start = tid * 2;

        // Butterfly propagation
        for (int i = 1, n = 4; i < llog; i++, n *= 2) {

            int new_block_start = (k/n) * n;
            if (new_block_start != block_start) {
                block_start = new_block_start;
                k -= n/4;
            }

            // We compute
            // X(k) = E(k) + TF(k, N) * O(k)
            // and
            // X(k + N/2) = E(k) - TF(k, N) * O(k)
            c1 = dev_samples[k];
            c2 = cuCmulf(twiddle_factor(k % n, n, direction), dev_samples[k + n/2]);

            dev_samples[k] = cuCaddf(c1, c2);
            dev_samples[k + n / 2] = cuCsubf(c1, c2);

            __syncthreads();
        }

        // Normalize if backward transforming
        if (direction == Backward) {
            dev_samples[tid].x /= length;
            dev_samples[tid].y /= length;
            dev_samples[tid + length/2].x /= length;
            dev_samples[tid + length/2].y /= length;
        }


        // Strange behavior if using this snipset 
        // instead of the previous one
        /*
        if (direction == Backward) {
            dev_samples[tid * 2].x /= length;
            dev_samples[tid * 2].y /= length;
            dev_samples[tid * 2 + 1].x /= length;
            dev_samples[tid * 2 + 1].y /= length;
        } */
    }
}
其中长度=4。 但是如果我使用注释掉的部分,我会得到错误的结果

 (1.5, 0)
 (-0.5, -0.5)
 (1, 0)  <--- wrong
 (-0.5, 0.5)
(1.5,0)
(-0.5, -0.5)
(1,0)>(32-llog)];
cuComplex c2=dev_样本[bit_reverse(tid*2+1)>>(32-llog)];
__同步线程();
dev_样本[tid*2]=cuCaddf(c1,c2);
dev_样本[tid*2+1]=cuCsubf(c1,c2);
__同步线程();
int k=tid*2;
int block_start=tid*2;
//蝴蝶繁殖
对于(int i=1,n=4;i1)和掩码);
掩码=0x33333333;//0011。。。
i=((i和掩码)>2)和掩码);
掩码=0x0F0F;//00001111。。。
i=((i和掩码)>4)和掩码);
掩码=0x00ff00ff;//00000000 11111111。。。
i=((i和掩码)>8)和掩码);
//0000000000000000 1111111111不需要掩码
i=(i>16);
返回i;
}
#定义信号长度4
使用名称空间std;
int main(int argc,字符**argv)
{
size\u t mem\u size=信号长度*sizeof(cuComplex);
cuComplex*信号=(cuComplex*)malloc(mem_大小);
cuComplex*dev_信号;
对于(int i=0;i<信号长度;i++){
信号[i].x=i;
信号[i],y=0;
}
CU_检查(cudaMalloc((无效**)和dev_信号,内存大小);
CU_检查(CUDAMCPy(开发信号、信号、内存大小、CUDAMCPyHostToDevice));
fft(偏差信号、信号长度、反向);
CU_检查(cudaMemcpy(信号、开发信号、内存大小、cudaMemcpyDeviceToHost));
cout我想您可能需要另一个
\uu syncthreads()
,这里:

    cuComplex c1 = dev_samples[bit_reverse(tid * 2) >> (32 - llog)];
    cuComplex c2 = dev_samples[bit_reverse(tid * 2 + 1) >> (32 - llog)];

    __syncthreads(); // <<< need this, otherwise possible race condition ?

    dev_samples[tid * 2] = cuCaddf(c1, c2);
    dev_samples[tid * 2 + 1] = cuCsubf(c1, c2);
cucomplexc1=dev_样本[bit_reverse(tid*2)>>(32-llog)];
cuComplex c2=dev_样本[bit_reverse(tid*2+1)>>(32-llog)];

__syncthreads();//我很确定这是不对的:

fftKernel<<<BLOCK_SIZE, gridSize>>>(...);
fftKernel(…);
第一个内核配置参数应该是网格维度,第二个应该是块维度

我能够重现您在发布的代码中指出的错误。当我反转这两个参数时:

fftKernel<<<gridSize, BLOCK_SIZE>>>(...);
fftKernel(…);
这个错误对我来说消失了


FWIW,
synccheck
工具确实报告了一个屏障错误,即使有上述“修复”。
synccheck
在CUDA 7中是新的,而且。

您正在(可能)中使用
\u syncthreads()发散代码。不清楚是否确实如此,但如果是,这是未定义的行为。完整的复制示例总是有用的。我强烈建议通过cuda memcheck工具集运行“buggy”内核(synccheck和racecheck工具非常有用)。当您谈论发散代码时,您是指(tidfftKernel<<<BLOCK_SIZE, gridSize>>>(...);
fftKernel<<<gridSize, BLOCK_SIZE>>>(...);