我有这样的事情:
__global__ void globFunction(int *arr, int N) {
int idx = blockIdx.x* blockDim.x+ threadIdx.x;
// calculating and Writing results to arr ...
__syncthreads();
// reading values of another threads(ex i+1)
int val = arr[idx+1]; // IT IS GIVING OLD VALUE
}
int main() {
// declare array, alloc memory, copy memory, etc.
globFunction<<< 4000, 256>>>(arr, N);
// do something ...
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么我阅读时会得到旧的价值arr[idx+1]?我致电了__syncthreads,所以我希望看到更新后的值。我做错什么了?我正在读取缓存还是什么?
Numba Cuda 有syncthreads() 来同步块内的所有线程。如何在不退出当前内核的情况下同步网格中的所有块?
在C-Cuda 中有一个cooperativeBlocks 库来处理这种情况。我在 Numba 文档中找不到类似的内容。
为什么这很重要!
这种事情发生在归约中,人们在每个块中计算一些东西,然后你想要找到块上的最大值。
很简单,我们可以将它们作为两个单独的调用推送到流中。这确保了块计算在调用reduce之前全部完成。
但如果这两个操作是轻量级的,那么执行时间主要由设置内核而不是操作的执行决定。如果它们位于 python 循环内,并且循环和两个内核调用可以融合到一个内核中,则循环的运行速度可以轻松提高 1000 倍
for u in range(100000):
Amax =CudaFindArrayMaximum(A)
CudaDivideArray(A,Amax)
CudaDoSomethingWithMatrix(A)
Run Code Online (Sandbox Code Playgroud)
由于循环中的三行中的每一行都是快速内核,因此我想将它们和循环全部放入一个内核中。
但如果不同步网格中的所有块,我想不出任何方法可以做到这一点。事实上,出于同样的原因,即使是找到最大值的第一步本身也很棘手。