cuda乘法

viv*_*v80 -1 cuda multiplication

串行代码片段如下所示:

int i, j;
for(j=0; j<ny; j++)
{
    for(i=0; i<nx; i++)
    {
        x[i + j*nx] *= y[i];
    }
}
Run Code Online (Sandbox Code Playgroud)

我使用这个内核将其转换为CUDA:

int tid = blockIdx.x * blockDim.x + threadIdx.x;
int i,j;
for(tid = 0; tid <nx*ny; tid++)
{
    j = tid/nx;
    i = tid - j*nx;
    x[tid] *= y[i];
}
Run Code Online (Sandbox Code Playgroud)

但是GPU内核没有提供任何加速改进?关于更好解决方案的任何建议?提前致谢

Pat*_*k87 6

如果这是序列号:

  int i, j;
  for(j=0; j<ny; j++)
  {
      for(i=0; i<nx; i++)
      {
          x[i + j*nx] *= y[i];
      }
  }
Run Code Online (Sandbox Code Playgroud)

那么你应该这样做:

  __global__ void fn(float *x, int nx)
  {
     int tid = blockIdx.x * blockDim.x + threadIdx.x;
     int j = tid/nx, i = tid - j * nx;
     x[tid] *= y[i];
  }

  fn<<<nx*ny/B, B>>>(x, nx); // with B = 256, 512, etc.
Run Code Online (Sandbox Code Playgroud)

你正在做的事情是相当奇怪的:你指示CUDA内核的每个线程迭代0和nx*ny之间的所有 tid值,并计算与你的CPU版本相同的功能!此外,而不是仅仅遍历指数,你实际上是在做环效率比你做的CPU版本; 换句话说,你在每个线程中做同样的事情,效率低于在CPU上的1个线程中做的事情.难怪这会慢一点; 它应该更快,更慢.你的CUDA内核是:

  int **tid** = blockIdx.x * blockDim.x + threadIdx.x;
  int i,j;
  for(**tid** = 0; **tid** <nx*ny; **tid**++)
  {
      j = tid/nx;
      i = tid - j*nx;
      x[tid] *= y[i];
  }
Run Code Online (Sandbox Code Playgroud)

对于每个线程,这会执行与主机代码相同的nx*ny迭代; 你失去了并行性的所有好处,因为每个线程都在做同样的事情; 你可以使用GPU上的一个线程获得相同的性能,并获得相同的结果!

如果这是您的CUDA源文件中的逐字代码,则需要更改它并重做比较; 如果这是您编写的代码,以帮助解释您的代码正在为非CUDA观众做些什么,那么您需要提供您的实际CUDA代码,以便我们可以看到正在发生的事情......实际情况,性能分析我做过 - 琐碎的 - 是你所能想到的.