【CUDA】认识CUDA

目录

一、CUDA编程

二、第一个CUDA程序

三、CUDA关键字

四、device管理

4.1 初始化

4.2 Runtime API查询GPU信息

4.3 决定最佳GPU


CUDA C++ 编程指南CUDA C++在线文档:CUDA C++ 编程指南

CUDA是并行计算的平台和类C编程模型,能很容易的实现并行算法。只需配备NVIDIA GPU,就可以在许多设备上运行并行程序

一、CUDA编程

CUDA编程允许程序执行在异构系统上,即CUP和GPU,二者有各自的存储空间,并由PCI-Express 总线区分开。注意二者术语上的区分:

  • Host:CPU and itsmemory (host memory)
  • Device: GPU and its memory (device memory)

device 可以独立于 host 进行大部分操作。当一个 kernel 启动后,控制权会立刻返还给 CPU 来执行其他额外的任务。所以CUDA编程是异步的。一个典型的CUDA程序包含由并行代码补足的串行代码,串行代码由host执行,并行代码在device中执行

host 端代码是标准C,device 是CUDA C代码。可以把所有代码放到一个单独的源文件,也可以使用多个文件或库。NVIDIA C编译器(nvcc)可以编译 host 和 device 端代码生成可执行程序

一个典型的CUDA程序结构包含五个主要步骤:

  1. 分配GPU空间
  2. 将数据从CPU端复制到GPU端
  3. 调用CUDA kernel来执行计算
  4. 计算完成后将数据从GPU拷贝回CPU
  5. 清理GPU内存空间

二、第一个CUDA程序

若是第一次使用CUDA,在Linux下可以使用下面的命令来检查CUDA编译器是否安装正确:

还需检查下机器上的GPU

以上输出显示仅有一个GPU显卡安装在机器上

CUDA 为许多常用编程语言提供扩展,如 C、C++、Python 和 Fortran 等语言。CUDA 加速程序的文件扩展名是.cu

下面包含两个函数,第一个函数将在 CPU 上运行,第二个将在 GPU 上运行

void CPUFunction()
{printf("This function is defined to run on the CPU.\n");
}
__global__ void GPUFunction()
{printf("This function is defined to run on the GPU.\n");
}int main()
{CPUFunction();GPUFunction<<<1, 1>>>();cudaDeviceSynchronize();return 0;
}
  • __global__ void GPUFunction()

__global__ 关键字表明以下函数将在 GPU 上运行并可全局调用
将在 CPU 上执行的代码称为主机代码,而将在 GPU 上运行的代码称为设备代码
注意返回类型为 void,使用 __global__ 关键字定义的函数要求返回 void 类型

  • GPUFunction<<<1, 1>>>();

当调用要在 GPU 上运行的函数时,将此种函数称为已启动的核函数
启动核函数时,必须提供执行配置,即在向核函数传递任何预期参数之前使用 <<< … >>> 语法完成的配置。在宏观层面,程序员可通过执行配置为核函数启动指定线程层次结构,从而定义线程组(称为线程块)的数量,以及要在每个线程块中执行的线程数量

  • cudaDeviceSynchronize();

与许多 C/C++ 代码不同,核函数启动方式为异步:CPU 代码将继续执行而无需等待核函数完成启动。调用 CUDA 运行时提供的函数 cudaDeviceSynchronize 将导致主机 (CPU) 代码暂作等待,直至设备 (GPU) 代码执行完成,才能在 CPU 上恢复执行

三、CUDA关键字

_global__关键字

__global__执行空间说明符将函数声明为内核。 其功能是:

  • 在设备上执行
  • 可从主机调用,可在计算能力为 3.2或更高的设备调用
  • __global__ 函数必须具有 void 返回类型,并且不能是类的成员函数
  • 对 global 函数的任何调用都必须指定其执行配置
  • 对 global 函数的调用是异步的,这意味着其在设备完成执行之前返回

__device__关键字

  • 在设备上执行
  • 只能从设备调用
  • __global__ 和 __device__ 执行空间说明符不能一起使用

__host__关键字

  • 在主机上执行
  • 只能从主机调用
  • __global__ 和 __host__ 执行空间说明符不能一起使用
  • __device__ 和 __host__ 执行空间说明符可以一起使用,此时该函数是为主机和设备编译的

四、device管理

4.1 初始化

当第一次调用任何CUDA运行时API(如cudaMalloc、cudaMemcpy等)时,CUDA Runtime会被初始化。这个初始化过程包括设置必要的内部数据结构、分配资源等,以便CUDA运行时能够管理后续的CUDA操作

每个CUDA设备都有一个与之关联的主上下文。主上下文是设备上的默认上下文,当没有显式创建任何上下文时,所有的CUDA运行时API调用都会在该主上下文中执行。主上下文包含了设备上的全局资源,如内存、纹理、表面等

开发者可以在程序启动时显式地指定哪个GPU成为"默认"设备。这个变化通常通过设置环境变量CUDA_VISIBLE_DEVICES或在程序中使用CUDA API(如cudaSetDevice)显式选择设备来实现。一旦选择了设备,随后的CUDA运行时初始化就会在这个指定的设备上创建主上下文

在没有显式指定设备的情况下,CUDA程序会默认在编号为0的设备(通常是第一个检测到的GPU)上执行操作

可以设置环境变量CUDA_VISIBLE_DEVICES-2来屏蔽其他GPU,这样只有GPU2能被使用。也可以使用CUDA_VISIBLE_DEVICES-2,3来设置多个GPU,其 device ID 分别为0和1

cudaDeviceReset

其作用是重置当前线程所关联的CUDA设备的状态,并释放该设备上所有已分配并未释放的资源

使用场景:

  1. 在程序结束时,调用该函数可以确保所有已分配的GPU资源都被正确释放,避免内存泄漏
  2. 若在程序的执行过程中遇到错误或需要中途退出,可释放已分配的资源,确保设备状态正确
  3. 在某些情况下,若设备状态出错(如由于之前的错误操作导致设备进入不可预测的状态),调用该函数可以尝试恢复设备到一个可用的状态

注意:

  1. 在调用该函数前,应确保所有已分配的设备内存和其他资源都已被正确地处理(如过cudaFree释放内存)。尽管其会释放这些资源,但最好还是在代码中显式地进行释放,以提高代码的可读性和可维护性
  2. 调用该函数后,当前线程与设备的关联关系可能会被重置。若需要继续使用设备,可能需要重新调用cudaSetDevice来设置当前线程要使用的设备

4.2 Runtime API查询GPU信息

cudaError_t cudaGetDeviceProperties(cudaDeviceProp *prop, int device);

GPU的信息被存放在cudaDeviceProp结构体中

#include <cuda_runtime_api.h>
#include <iostream>
#include <cmath>
using namespace std;int main()
{// 获取GPU数量int deviceCount = 0;cudaError_t errorId = cudaGetDeviceCount(&deviceCount);if (errorId != cudaSuccess) {printf("cudaGetDeviceCount returned %d\n-> %s\n", static_cast<int>(errorId), cudaGetErrorString(errorId));printf("Result = FAIL\n");exit(EXIT_FAILURE);}if (deviceCount == 0) {printf("There are no available device(s) that support CUDA\n");} else {printf("Detected %d CUDA Capable device(s)\n", deviceCount);}// 指定第一个GPUint device = 0;cudaSetDevice(device);// 获取GPU信息cudaDeviceProp deviceProp;cudaGetDeviceProperties(&deviceProp, device);int driverVersion = 0, runtimeVersion = 0;cudaDriverGetVersion(&driverVersion);cudaRuntimeGetVersion(&runtimeVersion);// 打印信息printf(" Device %d: \"%s\"\n", device, deviceProp.name);printf(" CUDA Driver Version / Runtime Version %d.%d / %d.%d\n", driverVersion/1000, (driverVersion%100)/10,runtimeVersion/1000, (runtimeVersion%100) / 10);printf(" CUDA Capability Major/Minor version number: %d.%d\n", deviceProp.major, deviceProp.minor);printf(" 全局内存总量: %.2f MBytes (%llu bytes)\n", (float)deviceProp.totalGlobalMem/(pow(1024.0,3)), static_cast<unsigned long long>(deviceProp.totalGlobalMem));printf(" GPU Clock rate: %.0f MHz (%0.2f GHz)\n", deviceProp.clockRate * 1e-3f, deviceProp.clockRate * 1e-6f);printf(" Memory Clock rate: %.0f Mhz\n", deviceProp.memoryClockRate * 1e-3f);printf(" Memory Bus Width: %d-bit\n", deviceProp.memoryBusWidth);if (deviceProp.l2CacheSize) {printf(" L2 Cache Size: %d bytes\n",deviceProp.l2CacheSize);}printf(" Max Texture Dimension Size (x,y,z) 1D=(%d), 2D=(%d,%d), 3D=(%d,%d,%d)\n",deviceProp.maxTexture1D , deviceProp.maxTexture2D[0],deviceProp.maxTexture2D[1],deviceProp.maxTexture3D[0], deviceProp.maxTexture3D[1],deviceProp.maxTexture3D[2]);printf(" Max Layered Texture Size (dim) x layers 1D=(%d) x %d, 2D=(%d,%d) x %d\n",deviceProp.maxTexture1DLayered[0], deviceProp.maxTexture1DLayered[1],deviceProp.maxTexture2DLayered[0], deviceProp.maxTexture2DLayered[1],deviceProp.maxTexture2DLayered[2]);printf(" 常量内存总量: %lu bytes\n",deviceProp.totalConstMem);printf(" 每个块的共享内存总量: %lu bytes\n",deviceProp.sharedMemPerBlock);printf(" 每个块可用的寄存器总数: %d\n",deviceProp.regsPerBlock);printf(" Warp size: %d\n", deviceProp.warpSize);printf(" 每个多处理器的最大线程数: %d\n",deviceProp.maxThreadsPerMultiProcessor);printf(" 每个块的最大线程数: %d\n",deviceProp.maxThreadsPerBlock);printf(" 块各维度的最大尺寸: %d x %d x %d\n", deviceProp.maxThreadsDim[0], deviceProp.maxThreadsDim[1], deviceProp.maxThreadsDim[2]);printf(" 网格每个维度的最大尺寸: %d x %d x %d\n", deviceProp.maxGridSize[0], deviceProp.maxGridSize[1], deviceProp.maxGridSize[2]);printf(" Maximum memory pitch: %lu bytes\n", deviceProp.memPitch);return 0;
}

4.3 决定最佳GPU

对于支持多GPU的系统,需从中选择一个来作为device,抉择出最佳计算性能GPU的一种方法就是由其拥有的处理器数量决定

int main()
{int numDevices = 0;cudaGetDeviceCount(&numDevices);if (numDevices > 1) {int maxMultiprocessors = 0, maxDevice = 0;for (int device=0; device < numDevices; ++device) {cudaDeviceProp props;cudaGetDeviceProperties(&props, device);if (maxMultiprocessors < props.multiProcessorCount) {maxMultiprocessors = props.multiProcessorCount;maxDevice = device;}}cudaSetDevice(maxDevice);}  return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/60176.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

知识中台如何在精简供应链管理中发挥作用?

您如何与供应商沟通并分享您的最佳实践&#xff1f;您如何确保供应商了解您的基准&#xff1f;如果您正在为这些问题烦恼&#xff0c;请不要担心&#xff0c;本文章将为您提供宝贵的见解。 构建具备弹性的供应链模型&#xff0c;其关键在于知识中台的数据质量。若缺乏数据支撑…

Python 在PDF中绘制形状(线条、矩形、椭圆形等)

在PDF中绘制图形可以增强文档的视觉效果。通过添加不同类型的形状&#xff0c;如实线、虚线、矩形、圆形等&#xff0c;可以使文档更加生动有趣&#xff0c;提高读者的阅读兴趣。这对于制作报告、演示文稿或是教材特别有用。本文将通过以下几个示例介绍如何使用Python 在PDF中绘…

Gitlab-执行器为Kubetnetes时的注意事项,解决DNS解析问题

一、Gitlab-Runner 这里对于Runner的理解非常重要。 具体执行ci流水线的叫执行器。执行器可以部署是shell、docker、k8s的pod.执行完任务则生命周期结束。 管理执行器的叫Gitlab-Runner。Runner则是与Gitlab Server的Ci agent.(可以简单这么理解) 二、执行器为Kubetnetes时,DN…

大数据新视界 -- 大数据大厂之 Impala 性能优化:新技术融合的无限可能(下)(12/30)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

讨论一个mysql事务问题

最近在阅读一篇关于隔离级别的文章&#xff0c;文章中提到了一种场景&#xff0c;我们下面来分析一下。 文章目录 1、实验环境2、两个实验的语句执行顺序3、关于start transaction和start transaction with consistent snapshot4、实验结果解释4.1、实验14.2、实验24.3、调整实…

json绘制热力图

首先需要一段热力信息的json&#xff0c;我放在头部了。 然后就是需要de-geo库了。 实现代码如下&#xff1a; import * as d3geo from d3-geoimport trafficJSON from ../assets/json/traffic.jsonlet geoFun;// 地理投影函数// let info {max: Number.MIN_SAFE_INTEGER,mi…

K8S之Prometheus 部署(二十)

部署方式&#xff1a;https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/prometheus 源码目录&#xff1a;kubernetes/cluster/addons/prometheus 服务发现&#xff1a;https://prometheus.io/docs/prometheus/latest/configuration/configuration/#kube…

kafka中节点如何服役和退役

服役新节点 1&#xff09;新节点准备 &#xff08;1&#xff09;关闭 bigdata03&#xff0c;进行一个快照&#xff0c;并右键执行克隆操作。 &#xff08;2&#xff09;开启 bigdata04&#xff0c;并修改 IP 地址。 vi /etc/sysconfig/network-scripts/ifcfg-ens33修改完记…

【Three.js基础学习】21.Realistic rendering

前言 课程回顾 渲染器 1.色调映射 值意在将高动态范围](HDR)值转换为低动态范围(LDR) Three.is中的色调映射实际上会伪造将LDR转换为HDR的过程&#xff0c;即使颜色不是HDR&#xff0c; 结果会产生非常逼真的渲染效果 THREE .NoToneMapping (default) 无色调映射 THREE.Linear…

ORB_SLAM3安装

ORB_SLAM3安装 一.前期准备1.1ubuntu查看当前版本的命令1.2 根据ubuntu版本&#xff0c;更新下载软件源1.3 先下载git1.4 vim语法高亮1.5 常见的linux命令 二.ORB-SLAM3下载2.1 ORB_SLAM3源码下载2.2 安装依赖库2.2.1 依赖库2.2.2 安装pangolin2.2.3 安装opencv2.2.4 Eigen3安装…

无需云端!国产开源大语言模型llama.cpp本地实战

作者&#xff1a;高瑞冬 注&#xff1a; 文章是2023年底写的。代码和运行方式虽有些旧&#xff0c;但基本原理一样。现在出来ollama&#xff0c;vllm等工具框架用来本地部署大模型&#xff0c;顺便更新一下。 [TOC](最后有彩蛋) 背景 上海人工智能实验室与商汤科技…

横向思维导图前端样式

追溯记录图路上 代码如下 index.vue <template><div style"margin-left: 5%;margin-top: 6%"> <el-form style"margin-top: -5%; " :inline"true"><el-form-item label"药品名称"><el-select v-model&qu…

清华大学提出Mini-Omni2:开源多模态模型,功能与GPT-4o媲美!

&#x1f310; 在人工智能领域&#xff0c;多模态模型的发展正如火如荼。今天&#xff0c;我们要介绍的是由清华大学提出的Mini-Omni2&#xff0c;这是一个开源的多模态语言模型&#xff0c;它在功能上与GPT-4o相媲美&#xff0c;能够理解和生成视觉、听觉和文本内容&#xff0…

HarmonyOS入门 : 获取网络数据,并渲染到界面上

1. 环境搭建 开发HarmonyOS需要安装DevEco Studio&#xff0c;下载地址 : https://developer.huawei.com/consumer/cn/deveco-studio/ 2. 如何入门 入门HarmonyOS我们可以从一个实际的小例子入手&#xff0c;比如获取网络数据&#xff0c;并将其渲染到界面上。 本文就是基于…

msvcr100.dll丢失怎么解决?高效靠谱的六种解决方法分享

在我们使用电脑的时候&#xff0c;有一种叫动态链接库&#xff08;DLL&#xff09;的文件特别重要。比如&#xff0c;msvcr100.dll是Microsoft Visual C 2010 Redistributable包里的一部分&#xff0c;很多应用程序在运行的时候都需要用到它。但是&#xff0c;有些用户在使用的…

【C++练习】二进制到十进制的转换器

题目&#xff1a;二进制到十进制的转换器 描述 编写一个程序&#xff0c;将用户输入的8位二进制数转换成对应的十进制数并输出。如果用户输入的二进制数不是8位&#xff0c;则程序应提示用户输入无效&#xff0c;并终止运行。 要求 程序应首先提示用户输入一个8位二进制数。…

【SpringBoot】19 文件/图片下载(MySQL + Thymeleaf)

Git仓库 https://gitee.com/Lin_DH/system 介绍 从 MySQL 中&#xff0c;下载保存的 blob 格式的文件。 代码实现 第一步&#xff1a;配置文件 application.yml spring:jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT8datasource:driver-class-name: com.mysql.…

C++——异常

异常是在程序执行的过程中发生了某种错误&#xff0c;异常的处理机制允许我们讲发生的异常抛出给程序的另外一部分&#xff0c;对这个错误进行处理。这个机制让问题检测的环节和问题处理的环节分离。检测环节只需要负责检测即可&#xff0c;无需关系解决的细节问题。在C语言中处…

Linux相关概念和易错知识点(19)(HDD、Block group)

目录 1.HDD &#xff08;1&#xff09;HDD存储描述 &#xff08;2&#xff09;HDD结构图 &#xff08;3&#xff09;磁盘管理的分治思想 &#xff08;4&#xff09;硬盘中文件系统的整体划分图 2.Block group &#xff08;1&#xff09;文件管理 ①文件属性的存储 ②in…

WWDC24(Xcode 16)中全新的 Swift Testing 使用进阶

概述 WWDC 24 祭出的全新单元测试系统着实让苹果开发者们眼前一亮。“原来测试还可以这么爽&#xff01;&#xff1f;”&#xff0c;日渐逼近蟋蟀发型的某位码农如是说。 Swift Testing 在简洁性以及灵活性全面超越老大哥 XCTest 的同时&#xff0c;也让秃头码农们真正见识到了…