C++ 块级原子写入
可以在块级别执行原子写入吗?C++ 块级原子写入,c++,c,cuda,gpu,gpgpu,C++,C,Cuda,Gpu,Gpgpu,可以在块级别执行原子写入吗? 作为一个例子,考虑如下: __global__ kernel (int atomic) { atomic+=blockid.x; //should be atomic for each block } 虽然不清楚“块/块级别”是什么意思,但听起来您只需要一个原子添加。 这些都可以在#include中的内核中找到 __global__ kernel (int atomic) { atomic_add(blockid.x,&atomic); }
作为一个例子,考虑如下:
__global__ kernel (int atomic)
{
atomic+=blockid.x; //should be atomic for each block
}
虽然不清楚“块/块级别”是什么意思,但听起来您只需要一个原子添加。 这些都可以在
#include
中的内核中找到
__global__ kernel (int atomic)
{
atomic_add(blockid.x,&atomic);
}
atomic
的类型必须是atomic\u t
和blockid.x-an-int.虽然不清楚块/块级别的含义,但听起来您只需要一个原子添加。
这些都可以在#include
中的内核中找到
__global__ kernel (int atomic)
{
atomic_add(blockid.x,&atomic);
}
atomic
必须是atomic\u t
类型和blockid.x-an-int.您可以在CUDA中执行一些原子操作。请参阅《CUDA编程指南》中的Apendix B.11原子函数。i、 e:
__global__ void kernel (int *result)
{
atomicAdd(result, blockIdx.x); //
}
您还可以交换变量的值
__global__ void kernel (int *result)
{
atomicExch(result, blockIdx.x); //
}
这两个示例都在全局内存中运行
在共享内存上运行的原子函数和在64位字上运行的原子函数仅适用于计算能力为1.2及以上的设备
问候。您可以在CUDA中执行一些原子操作。请参阅《CUDA编程指南》中的Apendix B.11原子函数。i、 e:
__global__ void kernel (int *result)
{
atomicAdd(result, blockIdx.x); //
}
您还可以交换变量的值
__global__ void kernel (int *result)
{
atomicExch(result, blockIdx.x); //
}
这两个示例都在全局内存中运行
在共享内存上运行的原子函数和在64位字上运行的原子函数仅适用于计算能力为1.2及以上的设备
注意。您可以在共享内存上执行原子操作,但不是您在代码段中尝试的方式:内核的
int
参数是一个线程特定的变量;即使所有线程都获得了您在启动时提供的相同值,它们也不会将其存储在共享内存中——并且原子化地对其进行操作是毫无意义的
例如,如果您将一个int*
传递给某个缓冲区,那将是全局内存中的一个缓冲区。您可以对全局内存中的数据执行设备范围的原子操作,如@pQB中所述。但是你问了关于块级原子操作。。。这对全球数据来说意义不大。但是,如果您的一个线程写入某个全局地址,它可能会暂停所有\uuthreadfence\u block()
,直到块中的所有其他线程都能看到此写入的效果
CUDA中也支持正确的块级原子,但在共享内存上支持。阅读有关如何在相关中使用共享内存的信息
如果您有一些\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuux
,您确实可以对其。但是-请记住,块中的所有线程都将执行相同的操作,并且您肯定不希望一次最多尝试1024次原子写入。通常情况下,您会有
__shared__ some_buffer[NumFoosPerBar];
// ...
if (check_condition()) {
int foo_index = get_thread_foo_index_for(threadIdx.x);
atomicAdd(&some_buffer[foo_index], 7);
}
其中可能有多个线程写入同一位置,但不一定。当您确实需要多次写入时—不要使用原子,而是对要写入的值执行某种程度的缩减。您可以在共享内存上执行原子操作,但不是您在代码段中尝试的方式:内核的
int
参数是线程特定的变量;即使所有线程都获得了您在启动时提供的相同值,它们也不会将其存储在共享内存中——并且原子化地对其进行操作是毫无意义的
例如,如果您将一个int*
传递给某个缓冲区,那将是全局内存中的一个缓冲区。您可以对全局内存中的数据执行设备范围的原子操作,如@pQB中所述。但是你问了关于块级原子操作。。。这对全球数据来说意义不大。但是,如果您的一个线程写入某个全局地址,它可能会暂停所有\uuthreadfence\u block()
,直到块中的所有其他线程都能看到此写入的效果
CUDA中也支持正确的块级原子,但在共享内存上支持。阅读有关如何在相关中使用共享内存的信息
如果您有一些\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuux
,您确实可以对其。但是-请记住,块中的所有线程都将执行相同的操作,并且您肯定不希望一次最多尝试1024次原子写入。通常情况下,您会有
__shared__ some_buffer[NumFoosPerBar];
// ...
if (check_condition()) {
int foo_index = get_thread_foo_index_for(threadIdx.x);
atomicAdd(&some_buffer[foo_index], 7);
}
其中可能有多个线程写入同一位置,但不一定。当您确实需要多次写入时-不要使用原子,而是对要写入的值执行某种程度的缩减。如果我添加#include,则会出现致命错误C1083:无法打开包含文件:“asm/atomic.h”:没有这样的文件或目录OK获得它。我应该添加sm_11及其原子添加,而不是原子添加。谢谢。你说的其实不是CUDA的解决方案(问题不清楚-检查标签)@randy:你接受了一个完全错误的答案。请接受pQB的答案,因为它对CUDA是正确的,而莱克没有正确地阅读问题。@harrism:好吧,5年后,兰迪似乎没有回到这个网站,我们被错误的答案所困扰。我至少会投反对票,并且我已经将其标记为“非答案”。如果我添加“include”,我会得到致命错误C1083:无法打开include文件:“asm/atomic.h”:没有这样的文件或目录OK会得到它。我应该添加sm_11及其原子添加,而不是原子添加。谢谢。你说的其实不是CUDA的解决方案(问题不清楚-检查标签)@randy:你接受了一个完全错误的答案。请接受pQB的答案,因为它对CUDA是正确的,而莱克没有正确地阅读问题。@harrism:好吧,5年后,兰迪似乎没有回到这个网站,我们被错误的答案所困扰。至少我会投反对票,我已经把它标为“不是答案”。记住,如果你