我有b个块,每个块有t个线程。
我可以使用
__syncthreads()
同步处于特定块中的线程。例如:
__global__ void aFunction()
{
for(i=0;i<10;i++)
{
//execute something
__syncthreads();
}
}
但我的问题是如何在所有块的所有线程中同步。我该怎么做?
我有b个块,每个块有t个线程。
我可以使用
__syncthreads()
__global__ void aFunction()
{
for(i=0;i<10;i++)
{
//execute something
__syncthreads();
}
}
#include <cuda_runtime_api.h>
#include <cuda.h>
#include <cooperative_groups.h>
cooperative_groups::grid_group g = cooperative_groups::this_grid();
g.sync();
如果您确保不生成过多的块,则可以尝试使所有块之间互相同步,例如通过使用原子操作主动等待。然而,这种方法速度较慢,会占用您的GPU内存控制器,被视为“hack”应该避免。
因此,如果您不针对Pascal(或更新)架构,则我建议的最佳方法是在同步点简单地终止您的内核,然后启动一个新的内核来继续您的工作。在大多数情况下,实际上它的表现会更快(或至少与所提到的hack的速度相似)。
cudaLaunchCooperativeKernel
来启动您的内核。这使得它对于简单项目来说不是一个好的解决方案。// A global var with 64 bits can track 64 blocks,
// use an array if you need to track more blocks
__device__ uint64_t CompleteMask;
//This is where we put in all the smarts
//from the CPU reference solver
__global__ void doWork() {
atomicAnd(&CompleteMask, 0);
//do lots of work
const auto SollMask = (1 << gridDim.x) - 1;
if (ThreadId() == 0) {
while ((atomicOr(&CompleteMask, 1ULL << blockIdx.x)) != SollMask) { /*do nothing*/ }
}
if (ThreadId() == 0 && 0 == blockIdx.x) {
printf("Print a single line for the entire process")
}
}
atomicAdd
来跟踪计数,像这样:// A global var with 64 bits can track 64 blocks,
// use an array if you need to track more blocks
__device__ int CompleteMask[2];
__device__ int CompleteSuperMask;
__global__ void doWork() {
for (auto i = 0; i < 2; i++) { atomicAnd(&CompleteMask[i], 0); }
atomicAnd(&CompleteSuperMask, 0);
//do lots of work
int SollMask[3];
SollMask[0] = -1;
SollMask[1] = (1 << (gridDim.x % 32)) - 1;
SollMask[2] = (1 << (gridDim.x / 32)) - 1;
const auto b = blockIdx.x / 32;
while (atomicOr(&CompleteMask[b], (1U << (blockIdx.x % 32))) != SollMask[b]) { /*do nothing*/ }
while (atomicOr(&CompleteSuperMask, (1U << b)) != SollMask[2]) { /*do nothing*/ }
if (threadIdx.x == 0 && blockIdx.x == 0) {
printf("Print a single line for the entire process");
}
}
... cooperative_groups::grid_group grp = cooperative_groups::this_grid(); grp.sync();
- interestedparty333