开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第18天,点击查看活动详情
一、安装扩展
要想运行CUDA,还需要C++编译环境。
安装及配置visual studio
CUDA C在很大程度上与标准C没有区别。在GPU上执行的函数通常称为核函数
使用CUDA需要C++的编译环境,这里我们可以安装visual studio,这里给一个visual studio 2017的下载地址 www.aliyundrive.com/s/L7Kzx437C…,下载安装即可。
注意:CUDA只支持2017-2019版的visual studio,如果不是这个范围的vs会报错,如下图所示:
下载完成后,打开安装文件,按下图所示选择安装即可:
安装完成后还需要将cl.exe所在目录加入到环境变量中,我们可以在vs目录下搜索cl.exe获取路径:
然后将该地址加入到环境变量中即可。
4)检查安装是否成功
我们可以建立一个main.cu的文件,然后加入下面的代码:
#include <stdio.h>
__global__ void hello() {
}
int main() {
hello<<<1, 1>>>();
printf("草莓桃桃酥");
return 0;
}
然后在cmd中执行命令:nvcc main.cu -o main,会看到如下输出:
然后再输入命令:main.exe执行文件,看到输入输出即代表成功:
二、CUDA在GPU和CPU运行效率对比
说了那么多GPU的优势,不实际上手试试怎么行呢?实践出真知,不然都是口说无凭。
下面是一个分别使用CPU和CUDA调用GPU执行矩阵运算的代码,会根据我们输入的Num值来执行运算,Num=10000相当于会运算10000*10000次,也就是1亿次,我的显卡为:GTX1060,来看一下实际的运行比较吧:
#include <stdio.h>
#include <time.h>
#define Num (10000)
#define THREADS 1000
void serial_add(double *a, double *b, double *c)
{
for(int index=0;index<Num;index++)
{
for(int j=0;j<Num;j++)
{
c[index] = a[index]*a[index] + b[index]*b[index];
}
}
}
__global__ void vector_add(double *a, double *b, double *c)
{
int index = blockIdx.x * blockDim.x + threadIdx.x;
for(int j=0;j<Num;j++)
{
c[index] = a[index]*a[index] + b[index]*b[index];
}
}
int main()
{
clock_t start,end;
double *a, *b, *c;
int size = Num * 8;
//分配内存空间
a = (double *)malloc( size );
b = (double *)malloc( size );
c = (double *)malloc( size );
for( int i = 0; i < Num; i++ )
{
a[i] = b[i] = i;
c[i] = 0;
}
start = clock();
serial_add(a, b, c);
end = clock();
float time1 = ((float)(end-start))/CLOCKS_PER_SEC;
printf("通过CPU执行消耗的时间: %f 秒\n",time1);
//CUDA
start = clock();
double *d_a, *d_b, *d_c;
cudaMalloc( (void **) &d_a, size );
cudaMalloc( (void **) &d_b, size );
cudaMalloc( (void **) &d_c, size );
cudaMemcpy( d_a, a, size, cudaMemcpyHostToDevice );
cudaMemcpy( d_b, b, size, cudaMemcpyHostToDevice );
vector_add<<< (Num + (THREADS-1)) / THREADS, THREADS>>>( d_a, d_b, d_c );
cudaMemcpy( c, d_c, size, cudaMemcpyDeviceToHost );
//释放内存和显存
free(a);
free(b);
free(c);
cudaFree( d_a );
cudaFree( d_b );
cudaFree( d_c );
end = clock();
float time2 = ((float)(end-start))/CLOCKS_PER_SEC;
printf("CUDA调用GPU执行消耗的时间: %f 秒",time2);
return 0;
}
输出结果
通过CPU执行消耗的时间: 0.275000 秒
CUDA调用GPU执行消耗的时间: 0.109000 秒
可以看到这么小的数据量就有2倍多的差距了,这时候我们增大Num的值,改为10W的话,它们之间的差距会更大:
通过CPU执行消耗的时间: 36.223000 秒
CUDA调用GPU执行消耗的时间: 0.900000 秒
可以看到差距越来越大,当然也不排除我的测试方法是否存在问题。欢迎大家指导和指正。