0

这是我从 udacity 的“并行计算简介”中获得的简短代码。这段代码中的索引让我感到困惑。

__global__ void use_shared_memory_GPU(float *array)
{
    int i, index = threadIdx.x;
    float average, sum=0.0f;

    __shared__ float sh_arr[128];

    sh_arr[index] = array[index];

    __syncthreads();

    // Now it begins to confuse me
    for(i=0; i<index; i++) { sum += sh_arr[i]; }   // what is the index here?

    average = sum / (index + 1.0f);               // what is the index here?
                                                  // why add 1.0f?

    if(array[index] > average) {array[index] = average;}

}

索引是作为每个线程的 Id 创建的,我可以理解。但是在计算平均值时,该指数用作线程数。第一个索引用作数组的并行计算 id,而第二个索引与普通 c 一样使用。我在我的程序中重复这个过程,但结果不会重复。

指数背后的诀窍是什么?我在 cuda-gdb 中打印它,它只显示 0。对此有详细解释吗?

加一分。计算平均值时,为什么要加 1.0f?

4

1 回答 1

2

此代码正在计算前缀和。值数组的前缀总和如下所示:

array:       1     2     4     3     5     7
prefix-sums: 1     3     7    10    15    22
averages:    1     2  2.33  2.25     3  3.67
index:       0     1     2     3     4     5

每个前缀总和是array直到该位置的值中元素的总和。该代码还计算“平均值”,即前缀总和除以用于计算总和的元素数。

在您显示的代码中,每个线程都在计算前缀和数组的不同元素(以及单独的平均值)。

因此,为了计算每个线程中的给定平均值,我们将前缀和除以索引,但我们必须将索引加 1,因为索引加 1 会得到用于计算前缀的元素数-该线程的总和(和平均值)。

于 2013-06-26T04:23:13.860 回答