Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cuda 原子团:块内的行为_Cuda - Fatal编程技术网

Cuda 原子团:块内的行为

Cuda 原子团:块内的行为,cuda,Cuda,我正在CUDA做一些原子学实验。我最大的疑问是,当运行在同一块中的两个线程原子地访问同一地址时,它们的行为如何。我尝试了一些使用atomicAdd的测试,它以原子方式工作,但是当我使用atomicCAS尝试下面的代码时,结果并不是我所期望的。有人有解释吗 #include <cuda_runtime.h> #include <iostream> #include <cuComplex.h> using namespace std; __global__ voi

我正在CUDA做一些原子学实验。我最大的疑问是,当运行在同一块中的两个线程原子地访问同一地址时,它们的行为如何。我尝试了一些使用atomicAdd的测试,它以原子方式工作,但是当我使用atomicCAS尝试下面的代码时,结果并不是我所期望的。有人有解释吗

#include <cuda_runtime.h>
#include <iostream>
#include <cuComplex.h>
using namespace std;
__global__ void kernel(int * pointer)
{
    *pointer=0;
    *(pointer+threadIdx.x+1)=0;
    __syncthreads();
    *(pointer+threadIdx.x+1)=atomicCAS(pointer,0,100);
}
int main(int argc,char ** argv)
{
    int numThreads=40;
    dim3 threadsPerBlock;
    dim3 blocks;
    int o[numThreads+1];
    int * pointer;
    cudaMalloc(&pointer,sizeof(int)*(numThreads+1));
    cudaMemset(pointer,0,sizeof(int)*(numThreads+1));
    threadsPerBlock.x=numThreads;
    threadsPerBlock.y=1;
    threadsPerBlock.z=1;
    blocks.x=1;
    blocks.y=1;
    blocks.z=1;
    kernel <<<threadsPerBlock,blocks>>> (pointer);
    cudaMemcpy(o,pointer,sizeof(int)*(numThreads+1),cudaMemcpyDeviceToHost);



    for (int i=0;i<numThreads+1;i++)
            cout << o[i] << " ";

    cout << endl;

}

i、 e.所有线程都发现要比较的值设置为0。

您已颠倒了执行配置参数的顺序。它是
,反之亦然。因此,您将启动40个块,每个块包含1个线程,而不是相反

这就是为什么会得到所看到的结果——因为每个块中只运行一个线程,所以数组中的最后一个
numThreads-1
值始终为零

如果我交换订单,我将得到以下输出:

100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 0 100 100 100 100 100 100 100

您可以看到,除了一个线程外,所有线程都像预期的那样写入了
100
,一个线程写入了
0

在内核调用中,threadperblock和blocks变量是反向的

与此相反:

 kernel <<<threadsPerBlock,blocks>>> (pointer);
内核(指针);
这样做:

 kernel <<<blocks, threadsPerBlock>>> (pointer);
内核(指针);

然后您将得到正确的输出。

如果发布时间没有那么大的不同,我会假设这是一个同步的答案…:)啊……是的,我犯了个愚蠢的错误。。。。让我问一件对我来说非常重要的事情……原子学在任何情况下都是原子的,或者在某些特定情况下它们不起作用?我记得在某个地方读过一些东西,但记不得了:(
 kernel <<<blocks, threadsPerBlock>>> (pointer);