使用寄存器减少CUDA

时间:2011-07-22 02:34:30

标签: cuda reduction

我需要使用减少来计算N个信号的平均值。输入是大小为MN的1D阵列,其中M是每个信号的长度。

最初我有额外的共享内存来首先复制数据并对每个信号进行减少。但是,原始数据已损坏。

我的程序尝试最小化共享内存。所以我想知道如何使用寄存器对N个信号进行减少求和。我有N个线程,一个共享内存(float)s_m [N * M],0 .... M-1是第一个信号,等等。

我需要N个寄存器(或一个)来存储N个不同信号的平均值吗? (我知道如何使用多线程编程和1个寄存器进行顺序添加)。我想要做的下一步是从其对应信号的均值中减去输入中的每个值。

2 个答案:

答案 0 :(得分:3)

您的问题非常小(N = 32且M <128)。但是,有些指导原则:

假设您为N个线程中的每个线程减少了N个值。

  • 如果N非常大(> 10),那么只需在每个线程中按顺序减少M.
  • 如果N <&lt;成千上万,考虑使用一个warp或一个线程块来执行N次减少。
  • 如果N非常小但M非常大,请考虑每N个减少使用多个线程块。
  • 如果N非常小且M非常小(正如您的数字所示),如果生成和/或消耗减少的输入/输出的计算也在GPU上运行,则仅考虑使用GPU进行减少

答案 1 :(得分:-1)

根据我对这个问题的理解,我说你不需要N个寄存器来存储N个不同信号的平均值。

如果你已经有N个线程[假设每个线程只对一个信号进行减少],那么你不需要N个寄存器来存储一个信号的减少量。您只需要一个寄存器来存储平均值。

dim3 threads (N,1);
reduction<<<threads,1>>>(signals);  // signals is the [N*M] array 

__global__ reduction (int *signals)
{
   int id = threadIdx.x;
   float meanValue = 0.0;

   for(int i = 0; i < M; i++)
          meanValue = signals[id*M +i];

   meanValue =  meanValue/M;

   // Then do the subtraction
   for(int i = 0; i < M; i++)
          signals[id*M +i] -= meanValue;
}

如果你需要对N个不同信号的所有均值进行全局减少,那么你需要使用2个寄存器[一个存储本地均值,另一个存储全局均值]和共享存储器

dim3 threads (N,1);
reduction<<<threads,1>>>(signals);  // signals is the [N*M] array 

__global__ reduction (int *signals)
{
   __shared__ float means[N];      // shared value
   int id = threadIdx.x;
   float meanValue = 0.0;
   float globalMean = 0.0;

   for(int i = 0; i < M; i++)
          meanValue += signals[id*M +i];

   means[id] =  meanValue/M;

   __syncthreads();

   // do the global reduction
   for(int i = 0; i < N; i++)
          globalMean += means[i];

   globalMean = globalMean/N;

   // Then do the subtraction
   for(int i = 0; i < M; i++)
          signals[id*M +i] -= globalMean;
}

我希望这会对你有所帮助。任何疑惑,让我知道。