CUDA非原子写冲突结果

时间:2014-03-03 15:46:36

标签: c++ cuda atomic

我正在编写一个需要迭代直到完成的函数。我意识到我可以使用原子操作符,但速度在这个内核中是至关重要的,我怀疑它们可能不是必需的。

我已经包含了一小段伪代码来演示我打算做什么

__global__ void TestKernel()
{
  __shared__ bool lbRepeat[1];
  do
  {
    lbRepeat=false;
    __syncthreads();
    if(Condition == true) lbRepeat=true;
    __syncthreads();
  }
  while(lbRepeat);
}

如果没有线程发现条件为真,则lbRepeat将为false。

如果一个线程发现Condition为true,则lbRepeat为真。

如果多个线程同时在lbRepeat中写入true,结果会是什么?

我想将其扩展为复制整数值(特别是无符号16位)。除了检查条件,我想复制一个无符号的16位整数。

__global__ void TestKernel()
{
  __shared__ unsigned short liValues[32*8];
  __shared__ bool lbRepeat[1];

  unsigned long tid = threadIdx.x+threadIdx.y*blockDim.x;
  do
  {
    lbRepeat=false;

    __syncthreads();
    if(Condition == true)
    {
       liValue[tid] = liValue[Some_Value_In_Range];
       lbRepeat=true;
    }
    __syncthreads();
  }
  while(lbRepeat);

}

如果另一个线程正在写入内存,因为它被读取可能导致既不返回先前的值也不返回新的值?我不介意是否返回前一个值或新值(两者都有效),但每个值的混合会导致问题。

我认为这是不可接受的,但我的测试似乎表明它可以按预期工作。这是因为未签名的短拷贝在CUDA中是原子的吗?

摘要:

如果两个线程将相同的值写入一个布尔存储器位置,结果是什么?

可以从无符号短内存位置读取,因为另一个线程正在向同一位置写入新值,返回的值既不是该内存位置中的先前值也不是新值?

1 个答案:

答案 0 :(得分:3)

  

如果两个线程将相同的值写入一个布尔存储器位置,结果是什么?

最终结果是其中一个写入的值将最终存储在该内存位置。哪个值未定义。如果所有书面值都相同,您可以确定该值最终会在该位置。

  

可以从无符号短内存位置读取,因为另一个线程正在向同一位置写入新值,返回的值既不是该内存位置中的先前值也不是新值?

假设这些是正在进行的两个操作(一次写入,一次读取),没有。读取值可以是写入开始前的值,也可以是写入完成后的值。如果您正在进行多次写入,那么当然可以看到第一个问题的答案。实际的写入值是未定义的,除非它就像其中一个写入成功而其他所有写入都没有成功。

我在正确对齐的8位,16位或32位数据类型的上下文中进行了上述语句,您的示例就是这样。