我正在编写一个需要迭代直到完成的函数。我意识到我可以使用原子操作符,但速度在这个内核中是至关重要的,我怀疑它们可能不是必需的。
我已经包含了一小段伪代码来演示我打算做什么
__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中是原子的吗?
摘要:
如果两个线程将相同的值写入一个布尔存储器位置,结果是什么?
可以从无符号短内存位置读取,因为另一个线程正在向同一位置写入新值,返回的值既不是该内存位置中的先前值也不是新值?
答案 0 :(得分:3)
如果两个线程将相同的值写入一个布尔存储器位置,结果是什么?
最终结果是其中一个写入的值将最终存储在该内存位置。哪个值未定义。如果所有书面值都相同,您可以确定该值最终会在该位置。
可以从无符号短内存位置读取,因为另一个线程正在向同一位置写入新值,返回的值既不是该内存位置中的先前值也不是新值?
假设这些是正在进行的两个操作(一次写入,一次读取),没有。读取值可以是写入开始前的值,也可以是写入完成后的值。如果您正在进行多次写入,那么当然可以看到第一个问题的答案。实际的写入值是未定义的,除非它就像其中一个写入成功而其他所有写入都没有成功。
我在正确对齐的8位,16位或32位数据类型的上下文中进行了上述语句,您的示例就是这样。