次のグローバル バリアは、Fermi GTX580 ではなく Kepler K10 で機能します。
__global__ void cudaKernel (float* ref1, float* ref2, int* lock, int time, int dim) {
int gid = blockIdx.x * blockDim.x + threadIdx.x;
int lid = threadIdx.x;
int numT = blockDim.x * gridDim.x;
int numP = int (dim / numT);
int numB = gridDim.x;
for (int t = 0; t < time; ++t) {
// compute @ time t
for (int i = 0; i < numP; ++i) {
int idx = gid + i * numT;
if (idx > 0 && idx < dim - 1)
ref2 [idx] = 0.333f * ((ref1 [idx - 1] + ref1 [idx]) + ref1 [idx + 1]);
}
// global sync
if (lid == 0){
atomicSub (lock, 1);
while (atomicCAS(lock, 0, 0) != 0);
}
__syncthreads();
// copy-back @ time t
for (int i = 0; i < numP; ++i) {
int idx = gid + i * numT;
if (idx > 0 && idx < dim - 1)
ref1 [idx] = ref2 [idx];
}
// global sync
if (lid == 0){
atomicAdd (lock, 1);
while (atomicCAS(lock, numB, numB) != numB);
}
__syncthreads();
}
}
そのため、CPU に送り返された出力を見ると、1 つのスレッド (最初または最後のスレッド) がバリアを回避し、他のスレッドよりも早く実行を再開していることに気付きました。CUDA5.0を使用しています。ブロックの数も常にSMの数よりも小さくなります(私の実行セットでは)。
同じコードが 2 つのアーキテクチャで機能しない理由がわかりませんか? このグローバル同期を支援する Kepler の新機能は何ですか?