有人可以帮助了解 Hillis & Steele:内核函数如何为每个线程执行工作吗?
__global__ void scan(float *g_odata, float *g_idata, int n)
{
extern __shared__ float temp[]; // allocated on invocation
int thid = threadIdx.x;
int pout = 0, pin = 1;
// load input into shared memory.
// This is exclusive scan, so shift right by one and set first elt to 0
temp[pout*n + thid] = (thid > 0) ? g_idata[thid-1] : 0;
__syncthreads();
for (int offset = 1; offset < n; offset *= 2)
{
pout = 1 - pout; // swap double buffer indices
pin = 1 - pout;
if (thid >= offset)
temp[pout*n+thid] += temp[pin*n+thid - offset];
else
temp[pout*n+thid] = temp[pin*n+thid];
__syncthreads();
}
g_odata[thid] = temp[pout*n+thid1]; // write output
}
从现在开始,我已经了解以下内容:首先,我们有pout=0, pin=1 and thid = [1,bockDim.x]
. 所以在第一次同步之前,我们有一个简单的向右移动,例如,如果我们有数组[1 | 2 | 5 | 7 ]
,新数组是[0 |1 | 2 | 5 | 7 ]
.
我将执行for loop
视为多个实例,每个实例对应每个thId
. 例如,如果thId=0
我们要执行以下操作:
thid=0
offset=1
- pout = 1-0=1 (在函数开头使用 pout 初始化)
- 引脚 = 1 - 1 =0;(使用刚刚计算的噘嘴,ei 1)
- temp[4] = temp[0](else 语句)
[0 | 1 | 2 | 5 | 0]
offset=2
- pout = 1-1=0 (使用循环中上一步的 pout)
- 引脚 = 1 - 0 =1;(刚刚计算的值)
- temp[0] = temp[4] ( else 语句)
- [0 | 1 | 2 | 5 | 0]
pout 和 pin 变量是根据 for 循环内部的信息更改的,而不是
在开始时考虑这些变量的初始化。以我想象的相同方式
执行thid=1
.thid=1
offset=1
- pout = 1 - 0 = 1(在函数开头使用 pout 初始化)
- 引脚 = 1 - 1 = 0
- temp[4+1] = temp[0+1-1] ( if 语句) ???? 内存超出温度范围????
谁能给出一个直观的例子来说明它是如何执行的?另外,当最后一个代码语句将被执行时,将使用哪个 pout 值?