文章目录
- 一、简介
- 1.1GPU的优势
- 1.2 CUDA®:通用并行计算平台和编程模型
- 二、Cuda项目
- 三、实现效果
- 参考资料
一、简介
1.1GPU的优势
图形处理单元(GPU)1在相同的价格和功率范围内提供比CPU高得多的指令吞吐量和内存带宽。许多应用程序利用这些更高的功能在GPU上比在CPU上运行得更快(参见GPU应用程序)。其他计算设备,如fpga,也非常节能,但提供的编程灵活性远不如gpu。
GPU和CPU之间的这种能力差异的存在是因为它们在设计时考虑了不同的目标。CPU被设计成擅长于尽可能快地执行一系列被称为线程的操作,并且可以并行执行几十个线程,而GPU被设计成擅长于并行执行数千个线程(摊销较慢的单线程性能以获得更大的吞吐量)。
GPU专门用于高度并行计算,因此设计了更多的晶体管用于数据处理,而不是数据缓存和流控制。下图显示了CPU与GPU的芯片资源分布示例。
1.2 CUDA®:通用并行计算平台和编程模型
2006年11月,NVIDIA®推出了CUDA®,这是一种通用的并行计算平台和编程模型,利用NVIDIA gpu中的并行计算引擎,以比CPU更有效的方式解决许多复杂的计算问题。
CUDA附带了一个软件环境,允许开发人员使用c++作为高级编程语言。如图2所示,支持其他语言、应用程序编程接口或基于指令的方法,例如FORTRAN、DirectCompute、OpenACC。
二、Cuda项目
1、首先创建CMakeList文件,使用CMake软件生成VS项目(需要提前安装好Cuda库)。
CMakeLists.txt
cmake_minimum_required(VERSION 3.19 FATAL_ERROR)
project(CudaTest LANGUAGES CUDA CXX)
set(CMAKE_CXX_STANDARD 14)
set(CUDA_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN TRUE)
set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
set(CMAKE_CUDA_ARCHITECTURES "60;61;62;70;72;75;80;86;87")
set(CMAKE_CUDA_SEPARABLE_COMPILATION TRUE)
set(CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS TRUE)
set(CMAKE_CUDA_HOST_COMPILATION_CPP FALSE)
set(CMAKE_CUDA_PROPAGATE_HOST_FLAGS FALSE)
# CUDA
find_package(CUDAToolkit REQUIRED)
file( GLOB header_list *.h )
file( GLOB source_list *.hpp *.cpp *.cu)
add_executable(${PROJECT_NAME} ${header_list})
target_sources(${PROJECT_NAME} PRIVATE ${source_list})
target_link_libraries(${PROJECT_NAME}
PRIVATE
CUDA::cusparse
CUDA::cusolver)
2、举个例子
main.cu
#include <iostream>
#include <cuda_runtime.h>
// CUDA 核函数:执行向量加法
__global__ void vectorAdd(float* A, float* B, float* C, int N) {
int i = threadIdx.x + blockIdx.x * blockDim.x;
if (i < N) {
C[i] = A[i] + B[i];
}
}
int main() {
int N = 1000; // 向量大小
size_t size = N * sizeof(float);
// 分配CPU内存
float* h_A = (float*)malloc(size);
float* h_B = (float*)malloc(size);
float* h_C = (float*)malloc(size);
// 初始化向量A和B
for (int i = 0; i < N; ++i) {
h_A[i] = static_cast<float>(i);
h_B[i] = static_cast<float>(i * 2);
}
// 分配GPU内存
float* d_A, * d_B, * d_C;
cudaMalloc((void**)&d_A, size);
cudaMalloc((void**)&d_B, size);
cudaMalloc((void**)&d_C, size);
// 将数据从CPU传输到GPU
cudaMemcpy(d_A, h_A, size, cudaMemcpyHostToDevice);
cudaMemcpy(d_B, h_B, size, cudaMemcpyHostToDevice);
// 指定线程块大小和网格大小
int blockSize = 256;
int gridSize = (N + blockSize - 1) / blockSize;
// 启动CUDA核函数
vectorAdd<<<gridSize, blockSize >>> (d_A, d_B, d_C, N);
// 将结果从GPU传输回CPU
cudaMemcpy(h_C, d_C, size, cudaMemcpyDeviceToHost);
// 打印结果的一部分以验证
for (int i = 0; i < 10; ++i) {
std::cout << "C[" << i << "] = " << h_C[i] << std::endl;
}
// 释放GPU内存
cudaFree(d_A);
cudaFree(d_B);
cudaFree(d_C);
// 释放CPU内存
free(h_A);
free(h_B);
free(h_C);
system("pause");
return 0;
}
三、实现效果
参考资料
[1]https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html