Fenrier Lab

CUDA 编程入门(5):程序计时与性能指标

程序计时[1] 既然我们专注于高性能计算,那么程序的运行时间就是一个非常值得关注的指标,在 CUDA 中,提供了很有用的 API 来帮助我们对程序在 Device 端的运行时间进行统计。下面的代码展示了如何来使用这些工具: void vectorAdd(const float *a, const float *b, const int n, float* c) { float *d_a, *d_b, *d_c; cudaMalloc((void**)&d_a, n * sizeof(float)); cudaMalloc((void**)&...
点我阅读更多...

CUDA 编程入门(4):搭建 CUDA 开发环境

项目结构 上一篇我们写了一个简单的小程序,使用一条命令就可以编译通过,但实际的项目结构要复杂得多,因此在本篇文章中,我们先介绍如何使用 VSCode 搭建一个 CMake 工程来进行 CUDA 开发,并集成 googletest 框架来做测试。 首先,我们的项目结构如下 |.vscode/ |--c_cpp_properties.json |include/ |--vector_add.h |src/ |--vector_add_kernel.cu |test/ |--CMakeLists.txt |--test.cpp |CMakeLists.txt 这里的 c_cpp_properties.json 主要是用来指引 VSCode,使其能够识别在源码中 include 的头...
点我阅读更多...

CUDA 编程入门(3):向量加法示例

前面的文章中,我们简单了解了 GPU 的硬件结构,以及建立在其之上的 CUDA 编程模型,现在,我们来通过一个简单的向量加法例子来展示如何使用 CUDA 的 C++ 扩展来开发一个并行计算程序。 首先,从硬件层面来看,CUDA 程序涉及到 CPU 端和 GPU 端的执行过程,其中 CPU 端又被称为 Host,GPU 端又被称为 Device。一个标准的并行计算流程是: 在 Host 端申请内存空间,分配数据,将数据拷贝到 Device 端; 在 Device 端定义算法,也就是 cuda kernel 方法; 在 Host 端调用 kernel 方法,启动计算任务; 在 Host 端等待计算任务完成,将计算结果从 Device 端拷贝回 Host 端。 下面...
点我阅读更多...

CUDA 编程入门(2):CUDA 编程模型

CUDA 的全称是 Compute Unified Device Architecture,它是建立在英伟达 GPU 硬件架构之上的并行计算平台和编程模型。 CUDA 计算模型 CUDA 计算模型是对 GPU 运算单元的抽象,它是一种分层次的计算结构,其中最基本的计算单位是线程 (Thread),从逻辑上来讲,每个 thread 可以负责计算任务的一部分,比如向量相加任务中的元素相加、矩阵乘法任务中的行列相乘等等。于是,通过 thread,我们可以将一个大的计算任务分解成多个小的计算任务,以更加细粒度的方式来调度,从而实现高效的并行计算。 Thread 的物理执行单元就是流处理器(SP),也就是说,每个 thread 都会被分配到一个 SP 执行,具体的调度过程是用户不可见的,由...
点我阅读更多...

CUDA 编程入门(1):英伟达GPU的硬件架构简介

CUDA 是建立在英伟达GPU硬件架构之上的并行计算平台和编程模型。因此,就像要写好高性能的 CPU 程序,必须对 CPU 的硬件架构有一定的理解一样,我们写 CUDA 程序也必须对 GPU 有最基本的了解。 从冯诺依曼体系结构说起 总所周知,冯诺依曼体系结构是现代计算机的基础,它包含了五个基本部件:运算器、控制器、存储器、输入设备和输出设备。其中,运算器和控制器合称为中央处理器(CPU),存储器包括内存和外存,输入设备和输出设备合称为外设。CPU 通过总线与内存和外设进行数据交换。 图1.1 冯诺依曼体系结构[1] 经过近几十年的高速发展,这些基本部件都变得无比复杂且强大。对于 CPU 来说,它的核心频率已达到数 GHz,核心数量也达到数十甚至上百个。而存储器则发展...
点我阅读更多...