CUDA 并行计算是如何工作的?

How does CUDA parallel computing work?

我是 CUDA 的新手,只是对它的工作原理感到困惑。

我创建了一个简单的 void 来在 GPU 上执行。

__global__ void Test (int *ch) {


long i = blockIdx.x;
ch[2] = i;
long u = threadIdx.x;
ch[3] = u;

if (i < 640)
{
    ch[0]++;

    if (u < 480)
    {

    ch[1]++;
    }

}  

}

我用<<<640,480>>>调用了虚空。在所有教程中,我都看到 If 正在替换 "CPU" for 循环。原来的 "CPU-Void" 看起来像这样:

void Test (int *ch) {

h_ch[2] = 640;
h_ch[3] = 480;

for(int a = 0;a < 640;a++)
{
    ch[0]++;

    for(int b = 0;b < 480;b++)
    {

    ch[1]++;
    }

}  

}

如果我打印由 CPU 生成的 ch 数组,我将看到类似这样的内容:ch[0] = 640 ch[1] = 307200 ch[2] = 640 ch[3] = 480但是 GPU 是做什么的?

我得到了这些结果:ch[0] = 1038(值每隔 运行 发生变化!)ch[1] = 1038(似乎等于 ch[0])ch[2] = 639 通道[3] = 31

发生了什么事?我假设得到与 CPU.

相同的结果

感谢您的回答

下面是完整的代码:(我只想要相同的结果) 您可以选择 CPU 或 gpu

 #include "cuda_runtime.h"
 #include "device_launch_parameters.h"

 #include <stdio.h>
 #include <iostream>

 int *h_ch , *ch;

 __global__ void Test (int *ch) 
{

long i = blockIdx.x;
ch[2] = i;
long u = threadIdx.x;
ch[3] = u;

if (i < 640)
{
    ch[0]++;
    if (u < 480)
    {

    ch[1]++;


    }

}

}
void test (int *h_ch)
{

h_ch[2] = 640;
h_ch[3] = 480;

for(int a = 0;a < 640;a++)
{
h_ch[0]++;

for(int b = 0;b < 480;b++)
{

h_ch[1]++;
}

}  

}
int main()
{
h_ch = (int *)malloc(4*sizeof(int));
cudaMalloc((void **)&ch,4*sizeof(int));

h_ch[0] = 0;
h_ch[1] = 0;
h_ch[2] = 0;
h_ch[3] = 0;

cudaMemcpy(ch,h_ch,4*sizeof(int),cudaMemcpyHostToDevice);

//Test<<<640,480>>>(ch);
test(h_ch);

//cudaMemcpy(h_ch,ch,4*sizeof(int),cudaMemcpyDeviceToHost);

for(int i = 0;i < 4;i++) printf("%d ",h_ch[i]);

int a;
std::cin >> a;

return 0;
}

有几个问题。

  1. 您有多个线程在尝试更新两个位置 ch[0]ch[1] 时相互踩踏。在 GPU 中,多个线程并行执行。当所有这些线程都试图同时更新同一个位置时,就会出现混乱。如果您想看到此代码正常工作,请将您的普通更新(例如 ch[1]++;)替换为原子更新(例如 atomicAdd(ch+1, 1);

  2. 你的 GPU 代码和 CPU 代码在逻辑上是不一样的。您的 GPU 代码让每个线程更新 ch[0]ch[1] 一次,因此如果上面 #1 中的问题得到解决,这些位置的结束数字应该分别为 640 和 480。但是您的 CPU 代码在循环中执行 ch[1] 的更新,每次 ch[0] 的更新执行 480 次。我们可以通过将 GPU 代码修改为类似于 CPU 代码来解决此问题,反之亦然,从逻辑上讲,将 CPU 代码修改为类似于 GPU 代码。

以下代码解决了上述 2 个问题,将 CPU 代码修改为类似于 GPU,ch[0]ch[1] 中的预期结果均为 307200 CPU 和 GPU:

$ cat t609.cu
#include <stdio.h>
#include <iostream>

int *h_ch , *ch;

__global__ void Test (int *ch)
{

  long i = blockIdx.x;
  long u = threadIdx.x;

  if (i < 640)
    atomicAdd(ch,1);
  if (u < 480)
    atomicAdd(ch+1,1);
}

void test (int *h_ch)
{

  for(int a = 0;a < 640;a++)
    for(int b = 0;b < 480;b++){
      h_ch[0]++;
      h_ch[1]++;}

}
int main()
{
  h_ch = (int *)malloc(4*sizeof(int));
  cudaMalloc((void **)&ch,4*sizeof(int));

  h_ch[0] = 0;
  h_ch[1] = 0;
  h_ch[2] = 0;
  h_ch[3] = 0;

  cudaMemcpy(ch,h_ch,4*sizeof(int),cudaMemcpyHostToDevice);

  Test<<<640,480>>>(ch+2);
  test(h_ch);

  cudaMemcpy(h_ch+2,ch+2,2*sizeof(int),cudaMemcpyDeviceToHost);

  for(int i = 0;i < 4;i++) printf("%d \n",h_ch[i]);

  return 0;
}
$ nvcc -arch=sm_20 -o t609 t609.cu
$ ./t609
307200
307200
307200
307200
$