C++ 如何在Visual Studio 2017中使用CUDA 10.0使GPU进程比CPU进程快得多?
聪明的开发者! 我是CUDA编程的初学者,我的代码有一个大问题 下面的代码是来自Nvidia的示例代码,我做了一些修改,以显示GPU进程比CPU进程快得多。然而,在编译这段代码之后,我得到了一个意想不到的结果,CPU进程比GPU进程快得多 这是我为Visual Studio 2017编写的cuda代码 ===========================================================================C++ 如何在Visual Studio 2017中使用CUDA 10.0使GPU进程比CPU进程快得多?,c++,cuda,gpu,nvidia,gpgpu,C++,Cuda,Gpu,Nvidia,Gpgpu,聪明的开发者! 我是CUDA编程的初学者,我的代码有一个大问题 下面的代码是来自Nvidia的示例代码,我做了一些修改,以显示GPU进程比CPU进程快得多。然而,在编译这段代码之后,我得到了一个意想不到的结果,CPU进程比GPU进程快得多 这是我为Visual Studio 2017编写的cuda代码 =========================================================================== #定义N 10 这是GPU进程中的add2
#定义N 10
这是GPU进程中的add2 function()
全局无效添加2(int*a,int*b,int*c){`
//来自网格扇区的GPU块
//int tid=blockIdx.x;//检查index=if的数据
插入N的最小值,您将从CPU获得较慢的结果。但如果您输入较大的数字,这将显示比CPU快得多的速度
//GPU线程
//int tid=threadIdx.x;//结果与blockIdx.x相同
//GPU意外向量//与上述结果相同
int tid=threadIdx.x+blockIdx.x*blockDim.x;
如果(tid
这是来自CPU进程的add function()
`void add(int*a、int*b、int*c){
int-tid=0;
而(tid
这是Main函数()
intmain(){
//持续时间的值
大整数tFreq、tStart、tEnd;
cudaEvent\u t启动、停止;
浮点tms,ms;
int a[N],b[N],c[N];//CPU值
int*dev_a、*dev_b、*dev_c;//GPU值----------------------------------------------
//为GPU创建alloc--------------------------------------------------------------
cudamaloc((void**)和dev_a,N*sizeof(int));
Cudamaloc((void**)和dev_b,N*sizeof(int));
cudamaloc((void**)和dev_c,N*sizeof(int));
//从CPU填充“a”和“b”
对于(int i=0;i coutGPU在运行单个操作时通常比CPU慢。此外,将数据发送到GPU并重新读取需要时间
GPU的优点是它可以并行执行许多操作
正如您将N
定义为10,上传和下载数据可能比在CPU上执行需要更长的时间。为了看到GPU的优势,请将您的问题规模扩大到更大的程度。理想情况下,您希望在每个GPU核心上执行最少的几个操作,然后才能看到一些好处。例如e使用GPU的1280个内核,您希望一次执行4000次或更多操作,以获得GPU的好处。您的意思是400000次,而不是4000次。4000次需要与10次相同的时间…@Talonmes在GPU上执行需要与10次相同的时间,但在CPU上需要更长的时间。我同意GPU处理mor时e更快乐,但我给出了一个近似的最小任务大小,以开始看到一些好处。@AlanBirtles非常感谢您帮助我理解我不知道的内容。顺便问一下,我想问一些其他问题。我能找出比CPU更快的最小操作是什么吗?(这个问题是我对cuda编程的好奇。你可以免费回答,也可以忽略。)唯一的解决方法是通过实验,这取决于您执行的操作、使用的数据量、编译器是否优化cpu代码以使用SIMD指令,当然还有cpu和GPU的速度are@AlanBirtles好的,我会的!再次感谢你们给我的建议!OP已经在十字架上承认了贴出他们可以通过对代码进行一些修改来获得CPU和GPU之间的不同比较。GPU:更多延迟,更多吞吐量。CPU:更少延迟,更少吞吐量。因此,您可以使用基本算法的适当构建块和CPU或GPU来构建算法。您是希望简单操作的延迟更短,还是希望许多简单操作的延迟更短(高通量)?GPU可以为高级算法(如大3D FFT或蛮力nbody)提供更短的延迟,但矢量或矩阵的元素相乘/求和的延迟更短。
`___global____ void add2(int *a, int *b, int *c) {`
// GPU block from grid sector
//int tid = blockIdx.x; // checking the data of index = if you
insert min of N, you will get slow result from CPU. But if you put big number, this show much faster than CPU
// GPU thread
//int tid = threadIdx.x; // Same result as blockIdx.x
// GPU unexpected vector // Same result as above
int tid = threadIdx.x + blockIdx.x*blockDim.x;
if (tid < N) {
c[tid] = a[tid] + b[tid];
}
}
`void add(int *a, int *b, int *c) {
int tid = 0;
while (tid < N) {
c[tid] = a[tid] + b[tid];
tid += 1;
}
}
int main() {
// Values for time duration
LARGE_INTEGER tFreq, tStart, tEnd;
cudaEvent_t start, stop;
float tms, ms;
int a[N], b[N], c[N]; // CPU values
int *dev_a, *dev_b, *dev_c; // GPU values----------------------------------------------
// Creating alloc for GPU--------------------------------------------------------------
cudaMalloc((void**)&dev_a, N * sizeof(int));
cudaMalloc((void**)&dev_b, N * sizeof(int));
cudaMalloc((void**)&dev_c, N * sizeof(int));
// Fill 'a' and 'b' from CPU
for (int i = 0; i < N; i++) {
a[i] = -i;
b[i] = i * i;
}
// Copy values of CPU to GPU values----------------------------------------------------
cudaMemcpy(dev_a, a, N * sizeof(int), cudaMemcpyHostToDevice);
cudaMemcpy(dev_b, b, N * sizeof(int), cudaMemcpyHostToDevice);
//////////////////////////////////////
QueryPerformanceFrequency(&tFreq); // Frequency set
QueryPerformanceCounter(&tStart); // Time count Start
// CPU operation
add(a, b, c);
//////////////////////////////////////
QueryPerformanceCounter(&tEnd); // TIme count End
tms = ((tEnd.QuadPart - tStart.QuadPart) / (float)tFreq.QuadPart) * 1000;
//////////////////////////////////////
// show result of CPU
cout << fixed;
cout.precision(10);
cout << "CPU Time=" << tms << endl << endl;
for (int i = 0; i < N; i++) {
printf("CPU calculate = %d + %d = %d\n", a[i], b[i], c[i]);
}
cout << endl;
///////////////////////////////////////
cudaEventCreate(&start);
cudaEventCreate(&stop);
cudaEventRecord(start, 0);
// GPU operatinog---------------------------------------------------------------------
//add2 <<<N,1 >>> (dev_a, dev_b, dev_c); // block
//add2 << <1,N >> > (dev_a, dev_b, dev_c); // Thread
add2 << <N/32+1, 32 >> > (dev_a, dev_b, dev_c); // grid
///////////////////////////////////////
cudaEventRecord(stop, 0);
cudaEventSynchronize(stop);
cudaEventElapsedTime(&ms, start, stop);
///////////////////////////////////////
// show result of GPU
cudaMemcpy(c, dev_c, N * sizeof(int), cudaMemcpyDeviceToHost);
cout << fixed;
cout.precision(10);
cout << "GPU Time=" << ms << endl << endl;
for (int i = 0; i < N; i++) {
printf("GPU calculate = %d + %d = %d\n", a[i], b[i], c[i]);
}
//Free GPU values
cudaFree(dev_a);
cudaFree(dev_b);
cudaFree(dev_c);
return 0;
}