gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 20:14:03 25 4
gpt4 key购买 nike

我对 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 ch[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] 一次,因此如果出现问题,这些位置的结束数字应分别为 640 和 480上面#1 中已得到解决。但您的 CPU 代码会循环执行 ch[1] 的更新,ch[0] 每次更新都会执行 480 次。从逻辑上讲,我们可以通过将 GPU 代码修改为类似于 CPU 代码来解决此问题,反之亦然,将 CPU 代码修改为类似于 GPU 代码。

以下代码解决了上述 2 个问题,将 CPU 代码修改为与 GPU 类似,ch[0]ch[1]< 中的预期结果均为 307200/code> 对于 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
$

关于c - CUDA并行计算是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28023718/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com