Numba cuda:使用共享内存添加数字导致覆盖

Numba cuda: Using shared memory to add numbers results in overwriting

我一直在尝试使用共享内存添加数字,所以它如下所示:

线程0:将共享内存变量sharedMemT[0]加1

线程1:将共享内存变量sharedMemT[0]加1

同步线程并将 sharedMemT[0] 存储到输出[0]

但结果是... 1??

@cuda.jit()
def add(output):
    sharedMemT = cuda.shared.array(shape=(1), dtype=int32)
    sharedMemT[0] = 0
    cuda.syncthreads()

    sharedMemT[0] += 1
    cuda.syncthreads()
    output[0] = sharedMemT[0]

out = np.array([0])
add[1, 2](out)
print(out) # results in [1]

恭喜,您参加了记忆竞赛。线程0和1同时运行,所以结果是undefined,无论是对共享内存变量的操作,还是回写到全局内存中。

为了使其正常工作,您需要使用原子内存操作序列化对共享内存变量的访问,然后只有一个线程写回全局内存:

$ cat atomic.py

import numpy as np
from numba import cuda, int32

@cuda.jit()
def add(output):
    sharedMemT = cuda.shared.array(shape=(1), dtype=int32)
    pos = cuda.grid(1)
    if pos == 0:
        sharedMemT[0] = 0

    cuda.syncthreads()

    cuda.atomic.add(sharedMemT, 0, 1)
    cuda.syncthreads()

    if pos == 0:
        output[0] = sharedMemT[0]

out = np.array([0])
add[1, 2](out)
print(out)

$ python atomic.py
[2]