【问题标题】:Iteration second cycle with sum reduction in CUDA在 CUDA 中减少总和的迭代第二个周期
【发布时间】:2013-10-28 19:14:18
【问题描述】:

我必须将此代码从 c++ 并行化到 CUDA C

  for(ihist = 0; ihist < numhist; ihist++){ 
      for(iwin = 0; iwin<numwin; iwin++){
          denwham[ihist] += (numbinwin[iwin]/g[iwin])*exp(F[iwin]-U[ihist]); 
          }
          Punnorm[ihist] = numwham[ihist]/denwham[ihist];
        }

在 CUDA C 中,使用求和:

extern __shared__ float sdata[];
  int tx = threadIdx.x;
  int i=blockIdx.x;
  int j=blockIdx.y;
  float sum=0.0;
  float temp=0.0;
  temp=U[j];


   if(tx<numwin)
   {
    sum=(numbinwin[tx]/g[tx])*exp(F[tx]- temp); 
    sdata[tx] = sum;
     __syncthreads();  
   }


  for(int offset = blockDim.x / 2;offset > 0;offset >>= 1)
  {
   if(tx < offset)
   {
    // add a partial sum upstream to our own
    sdata[tx] += sdata[tx + offset];
   }
   __syncthreads();
  }

   // finally, thread 0 writes the result
  if(threadIdx.x == 0)
  {
   // note that the result is per-block
   // not per-thread
   denwham[i] = sdata[0];

    for(int k=0;k<numhist;k++)
    Punnorm[k] = numwham[k]/denwham[k];
  }

并以这种方式初始化它:

 int smem_sz = (256)*sizeof(float);
  dim3 Block(numhist,numhist,1);
  NewProbabilitiesKernel<<<Block,256,smem_sz>>>(...);

我的问题是我无法使用 exp 遍历 U,我尝试了以下方法:

a) loop for/while inside the kernel that iterates over U 
b) iterate by thread
c) iterate to block

所有这些尝试都导致我在 C++ 代码和代码 cuda 之间得到不同的结果。如果我放置一个常量而不是 U [i],则代码可以正常工作!

你有什么想法可以帮助我吗?

谢谢。

【问题讨论】:

  • 尝试使用 expf 尝试增加程序的最小计算能力
  • 你好,我也用过expf但是不行,因为它加载了U[i]的值
  • 如果您瘫痪代码,它将无法行走。 :p
  • 嗨 sgar91 ,你可以给我一个代码解决方案吗?

标签: c++ cuda iteration


【解决方案1】:

看起来您可以将U 移出内部循环

for(iwin = 0; iwin<numwin; iwin++){
    denwham += numbinwin[iwin] / g[iwin] * exp(F[iwin]); 
}
for(ihist = 0; ihist < numhist; ihist++){ 
    Punnorm[ihist] = numwham[ihist] / denwham * exp(U[ihist]);
}

更新

之后,您可以使用 2 个简单的内核而不是 1 个复杂的内核来完成任务。

  1. 要计算的缩减内核denwham;
  2. 一维变换内核计算Punnorm

【讨论】:

  • H,但是我如何在 cuda 中移动 exp(U[ihist]) 的 ihist?用for内部内核逐个线程块?
  • 您可以使用两个内核或推力让您的生活更轻松。
  • 您有什么想法可以在同一个内核中完成这一切吗?
  • 如果你在单个内核中这样做,性能会很差,因为你会减少 numhist 次,这是不必要的。
  • 好的我明白了,您打算下载结果并将其发送到仅处理 ihist 的新内核?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-25
  • 1970-01-01
  • 2013-09-22
  • 1970-01-01
  • 1970-01-01
  • 2018-04-15
  • 2019-02-14
相关资源
最近更新 更多