CUDA是英伟达的技术,所以非N卡用不了=_=

下载CUDA

官方安装教程:https://docs.nvidia.com/cuda/cuda-installation-guide-microsoft-windows/index.html

懒得看的话直接下载:https://developer.nvidia.com/cuda-downloads

选择自己的系统版本

下载完直接安装就好,就是个普通的应用程序。安装完后用CMD输入nvcc -V(注意大小写)检查是否安装成功。

安装成功

测试

更优质的教程以及硬件层面解释可以看这里:https://www.zhihu.com/collection/757090574

创建一个CUDA工程

创建Cuda工程

打开之后就是一个案例工程,是一个向量相加的简单例子。不过太复杂了,这里先把别的都删掉,写如下的小程序,用来看看自己显卡啥样r:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

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

#include <iostream>

int main()
{
cudaDeviceProp devProp;
cudaGetDeviceProperties(&devProp, 0);

std::cout << "使用GPU device: " << devProp.name << std::endl;
std::cout << "SM的数量:" << devProp.multiProcessorCount << std::endl;
std::cout << "每个线程块的共享内存大小:" << devProp.sharedMemPerBlock / 1024.0 << " KB" << std::endl;
std::cout << "每个线程块的最大线程数:" << devProp.maxThreadsPerBlock << std::endl;
std::cout << "每个SM的最大线程数:" << devProp.maxThreadsPerMultiProcessor << std::endl;
std::cout << "每个SM的最大线程束数:" << devProp.maxThreadsPerMultiProcessor / 32 << std::endl;

return 0;
}

输出

我的2060S有34个 Streaming Multiprocessor(SM),每个SM可以调度1024个线程,也就是我的显卡最多可以同时调度34816个线程。

当然具体的介绍还是看这个教程吧:https://www.zhihu.com/collection/757090574

做个小案例

这里自己写一个简化版的向量相加的小案例,用于了解一下基础的编程结构:

这里先设计一下,比如说5维向量那就开5个线程,每个算对应位的加法,然后存到结果数组里就好了。

首先 include 各种库,然后写一个需要在显卡里运行的程序:

1
2
3
4
5
6
7
8
9
10
#include <cuda_runtime.h>
#include <device_launch_parameters.h>

#include<iostream>

__global__ void VectorAdd(const float* a, const float* b, float* c)
{
const int index = threadIdx.x;
c[index] = a[index] + b[index];
}

这里的 global 表示这个函数被CPU调用,在GPU运行。

然后实现 main 函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
int main()
{
// 声明两个待计算的向量数组和用于储存结果的数组
const int vectorLength = 5;
const float a[vectorLength] = { 1, 2, 3, 4, 5 };
const float b[vectorLength] = { 1.3, 2.4, 3.6, 4.7, 5.5 };
float c[vectorLength] = { 0 };

auto vectorSize = vectorLength * sizeof(float);

// 开辟显存
float* dev_a = 0;
float* dev_b = 0;
float* dev_c = 0;

cudaMalloc(&dev_a, vectorSize);
cudaMalloc(&dev_b, vectorSize);
cudaMalloc(&dev_c, vectorSize);

// 传入数据
cudaMemcpy(dev_a, a, vectorSize, cudaMemcpyHostToDevice);
cudaMemcpy(dev_b, b, vectorSize, cudaMemcpyHostToDevice);
cudaMemcpy(dev_c, c, vectorSize, cudaMemcpyHostToDevice);

// 显卡计算
VectorAdd << <1, vectorLength >> > (dev_a, dev_b, dev_c);

// 取得结果
cudaDeviceSynchronize(); // 等待显卡计算完
cudaMemcpy(c, dev_c, vectorSize, cudaMemcpyDeviceToHost);

for (int i = 0; i < vectorLength; i++) std::cout << c[i] << " ";

// 清空显存
cudaFree(dev_a);
cudaFree(dev_b);
cudaFree(dev_c);

return 0;
}

这里使用了 cudaMalloc cudaMemcpy 等显卡的方法去分配显存以及传入数据。最后结果如下:

结果

其他

进阶教程:

当然是官网:https://docs.nvidia.com/cuda/#


1