当前位置: 首页 > news >正文

一文学会CUDA编程:深入了解CUDA编程与架构(一)

前言:

CUDA(Compute Unified Device Architecture,统一计算设备架构)是由NVIDIA公司开发的一种并行计算平台和编程模型。CUDA于2006年发布,旨在通过图形处理器(GPU)解决复杂的计算问题。在早期,GPU主要用于图像处理和游戏渲染,但随着技术的发展,其并行计算能力被广泛应用于科学计算、工程仿真、深度学习等领域。

CUDA的工作原理

CUDA的核心思想是将计算任务分配给GPU上的大量线程,这些线程可以并行地执行任务,从而实现高性能计算。CUDA将GPU划分为多个独立的计算单元,称为“流处理器”(Streaming Processor),这些流处理器可以独立地执行指令,互相加不干扰。

硬件层面

1、CUDA核心 (CUDA Core)

CUDA核心是执行线程计算的基本硬件单元。每个CUDA核心可以执行一个线程的计算任务。

图片

2、SM (Streaming Multiprocessor)

流多处理器 (SM) 是由多个CUDA核心组成的集成单元。每个SM负责管理和执行一个或多个线程块。SM内部有共享内存和缓存,用于加速数据访问和计算。

3、设备 (Device)

设备指的是整个GPU硬件。一个设备包含多个SM,能够处理大量并行计算任务。设备通过高带宽的内存和数据传输机制与主机(如CPU)进行数据交换。

图片

软件层面

1、线程 (Thread)

在CUDA编程中,线程是执行基本计算任务的最小单位。每个线程执行相同的程序代码,但可以处理不同的数据。

图片

2、线程块 (Thread Block)

线程块是由多个线程组成的集合。线程块中的线程可以共享数据,并且可以通过同步机制来协调彼此的工作。线程块的大小在程序执行时是固定的。

图片

3、网格 (Grid)

网格是由多个线程块组成的更大集合。网格中的所有线程块并行执行任务,网格的大小也在程序执行时固定。

图片

示例

实现两个向量相加 arr_c[] = arr_a[] +arr_b[]

#include <cuda.h>
#include <cuda_runtime_api.h>#include <cmath>
#include <iostream>#define CUDA_CHECK(call)                                           \{                                                              \const cudaError_t error = call;                            \if (error != cudaSuccess) {                                \fprintf(stderr, "Error: %s:%d, ", __FILE__, __LINE__); \fprintf(stderr, "code: %d, reason: %s\n", error,       \cudaGetErrorString(error));                    \exit(1);                                               \}                                                          \}__global__ void addKernel(float *pA, float *pB, float *pC, int size)
{int index = blockIdx.x * blockDim.x + threadIdx.x; // 计算当前数组中的索引if (index >= size)return;pC[index] = pA[index] + pB[index];
}int main()
{float a[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};float b[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};int arr_len = 16;float *dev_a, *dev_b, *dev_c;CUDA_CHECK(cudaMalloc(&dev_a, sizeof(float) * arr_len));CUDA_CHECK(cudaMalloc(&dev_b, sizeof(float) * arr_len));CUDA_CHECK(cudaMalloc(&dev_c, sizeof(float) * arr_len));CUDA_CHECK(cudaMemcpy(dev_a, a, sizeof(float) * arr_len, cudaMemcpyHostToDevice));CUDA_CHECK(cudaMemcpy(dev_b, b, sizeof(float) * arr_len, cudaMemcpyHostToDevice));int *count;CUDA_CHECK(cudaMalloc(&count, sizeof(int)));CUDA_CHECK(cudaMemset(count, 0, sizeof(int)));addKernel<<<arr_len + 512 - 1, 512>>>(dev_a, dev_b, dev_c, arr_len);float *output = (float *)malloc(arr_len * sizeof(float));CUDA_CHECK(cudaMemcpy(output, dev_c, sizeof(float) * arr_len, cudaMemcpyDeviceToHost));std::cout << " output add" << std::endl;for (int i = 0; i < arr_len; i++) {std::cout << " " << output[i];}std::cout << std::endl;return 0;
}

代码理解

addKernel<<<arr_len + 512 - 1, 512>>>

函数类型如下

addKernel<<<dim3 grid, dim3 block>>>

前面的表达等价于

addKernel<<<(dim3 grid(arr_len + 512 - 1), 1, 1), dim3 block(512, 1, 1)>>>

grid 与block 理解

假设只使用16个元素, arr_len =16

1、使用调整block的参数:

1.1只有x:

dim3 grid(1, 1, 1), block(arr_len, 1, 1); // 一个block里面有16个线程                   // 设置参数

图片

此时遍历的代码如下:

__global__ void addKernel(float *pA, float *pB, float *pC, int size){// block是一维的    int index = threadIdx.x; // 计算当前数组中的索引    if (index >= size)        return;    pC[index] = pA[index] + pB[index];}

1.2 含有x, y

dim3 grid(1, 1, 1), block(8, 2, 1); //每个block x方向有8个线程,总共2组。 

图片

__global__ void addKernel(float *pA, float *pB, float *pC, int size){  // block是二维的    int index = threadIdx.x + blockDim.x* threadIdx.y; // 计算当前数组中的索引    if (index >= size)        return;    pC[index] = pA[index] + pB[index];}

2、更改grid 参数

2.1 只更改x方向的参数

dim3 grid(16, 1, 1), block(1, 1, 1);   //还有16个block, 每个block就一个线程                 // 设置参数

图片

__global__ void addKernel(float *pA, float *pB, float *pC, int size){  // grid.x是一维的    int index = blockIdx.x; // 计算当前数组中的索引    if (index >= size)        return;    pC[index] = pA[index] + pB[index];}

3、grid, block参数都改

3.1 grid block各改一个

dim3 grid(4, 1, 1), block(4, 1, 1) // 代码还有4个x方向block, 每个block x方向有4个线程

图片

__global__ void addKernel(float *pA, float *pB, float *pC, int size){  // grid.x是一维的    int index = blockIdx.x*gridDim.x + threadIdx.x; // 计算当前数组中的索引    if (index >= size)        return;    pC[index] = pA[index] + pB[index];}

3.2 grid block更改两个

dim3 grid(2, 2, 1), block(2, 2, 1) // 代码还有2个X方向block,Y方向上有两组, 每个block x方向有2个线程, y方向上有两组

图片

__global__ void addKernel(float *pA, float *pB, float *pC, int size){      // 在第几个块中 * 块的大小 + 块中的x, y维度(几行几列)    int index = (blockIdx.y * gridDim.x + blockIdx.x) * (blockDim.x * blockDim.y) + threadIdx.y * blockDim.y + threadIdx.x;    if (index >= size)        return;    pC[index] = pA[index] + pB[index];}

总结

CUDA作为一种强大的并行计算平台和编程模型,极大地推动了高性能计算、深度学习等领域的快速发展。通过掌握CUDA,开发者可以充分利用GPU的并行计算能力,显著提升程序的运行效率和性能。无论是科学研究还是商业应用,CUDA都提供了广阔的可能性和机遇。

关注我的公众号auto_driver_ai(Ai fighting), 第一时间获取更新内容。

相关文章:

一文学会CUDA编程:深入了解CUDA编程与架构(一)

前言&#xff1a; CUDA&#xff08;Compute Unified Device Architecture&#xff0c;统一计算设备架构&#xff09;是由NVIDIA公司开发的一种并行计算平台和编程模型。CUDA于2006年发布&#xff0c;旨在通过图形处理器&#xff08;GPU&#xff09;解决复杂的计算问题。在早期…...

Jquery判断图片加载失败,显示默认图片

//加载图片 出现404状态时触发 $(img).error(function () { //将加载不到的图片的src属性时&#xff0c;修改成默认图片&#xff0c;注意&#xff1a;默认图片必须保证存在&#xff0c;否则会一直调用此函数&#xff0c;造成死循环。$(this).attr("src", "Imag…...

App 自动化测试调研

App 自动化测试调研 App 自动化测试的价值 App 自动化测试在软件开发过程中扮演着重要的角色&#xff0c;具有以下几个方面的价值&#xff1a; 1.提高测试效率和覆盖率&#xff1a;自动化测试可以执行大量的测试用例&#xff0c;覆盖各种功能和场景&#xff0c;相比手动测试…...

Java 后端已经过时的技术,也是我逝去的青春

最近这段时间收到了一些读者的私信&#xff0c;问我某个技术要不要学&#xff0c;还有一些的同学竟然对 Java 图形化很感兴趣&#xff0c;还想找这方面的工作。 我接触 Java 已近 10多年了&#xff0c;见证了许多 Java 技术变迁&#xff0c;包括&#xff1a; JavaEE 框架&…...

释放自动化测试潜能:性能优化策略与实战技巧!

引言 在当今追求软件快速迭代的环境下&#xff0c;自动化测试的性能瓶颈正成为制约开发流程加速的主要障碍。本文将深入探讨如何通过策略和实践&#xff0c;优化自动化测试的性能&#xff0c;实现测试执行速度的质的飞跃。 自动化性能瓶颈的识别与突破 首先&#xff0c;识别并…...

如何理解代码的跨平台?

跨平台性&#xff1a; 跨平台性意味着&#xff0c;在多个平台都兼容运行 那么是怎么做到跨平台&#xff1f; 一般来说&#xff0c;window的操作系统和Linux的操作系统肯定是不一样的 那么提供的系统调用接口和诸多细节也是不一样的 但是&#xff0c;我们的c语言和c语言&#xf…...

dp:221. 最大正方形

221. 最大正方形 看到这个题目真能立马想到dp吗&#xff1f;貌似很难&#xff0c;即使知道是一个dp题也很难想到解法。 直观来看&#xff0c;使用bfs以一个点为中点进行遍历&#xff0c;需要的时间复杂度为 O ( n 2 m 2 ) O(n^2m^2) O(n2m2) 但是可以很容易发现&#xff0c;…...

花10分钟写个漂亮的后端API接口模板!

你好&#xff0c;我是田哥 在这微服务架构盛行的黄金时段&#xff0c;加上越来越多的前后端分离&#xff0c;导致后端API接口规范变得越来越重要了。 比如&#xff1a;统一返回参数形式、统一返回码、统一异常处理、集成swagger等。 目的主要是规范后端项目代码&#xff0c;以及…...

评估分类机器学习模型的指标

欢迎来到雲闪世界。一旦我们训练了一个监督机器学习模型来解决分类问题&#xff0c;如果这就是我们工作的结束&#xff0c;我们会很高兴&#xff0c;我们可以直接向他们输入新数据。我们希望它能正确地对所有内容进行分类。然而&#xff0c;实际上&#xff0c;模型做出的预测并…...

农机自动化:现代农业的未来趋势

随着人口的增长和农业生产的需求不断增加&#xff0c;提高农业生产效率成为现代农业的重要目标。农机自动化作为一种新兴技术&#xff0c;可以大幅度提升农机的使用效率和生产能力。农机自动化是指利用先进的传感技术、数据处理和人工智能技术&#xff0c;使农机能够自动完成农…...

25考研操作系统复习·1.1/1.2/1.3 操作系统的基本概念/发展历程/运行环境

目录 操作系统的基本概念 概念&#xff08;定义&#xff09; 功能和目标 资源的管理者 向上层提供服务 给普通用户的 给软件/程序员的 对硬件机器的拓展 操作系统的特征 操作系统的发展历程 操作系统的运行环境 操作系统的运行机制 中断和异常 中断的作用 中断的…...

如何培养学生的创新意识和实践能力

培养学生的创新意识和实践能力是一个复杂而系统的过程&#xff0c;涉及多个方面的努力和措施。以下是一些具体的做法&#xff1a; 一、培养学生的创新意识 提供创新环境&#xff1a; 为学生创造一个开放、自由、支持创新的学习环境&#xff0c;让他们能够自由地表达自己的想法…...

四、GD32 MCU 常见外设介绍(15)CAN 模块介绍

CAN是控制器局域网络(Controller Area Network)的简称&#xff0c;它是由研发和生产汽车电子产品著称的德国BOSCH公司开发的&#xff0c;并最终成为国际标准&#xff08;ISO11519&#xff09;&#xff0c;是国际上应用最广泛的现场总线之一。 CAN总线协议已经成为汽车计算机控…...

AIGC大模型产品经理高频面试大揭秘‼️

近期有十几个学生在面试大模型产品经理&#xff08;薪资还可以&#xff0c;详情见下图&#xff09;&#xff0c;根据他们面试&#xff08;包括1-4面&#xff09;中出现高频大于3次的问题汇总如下&#xff0c;一共32道题目&#xff08;有答案&#xff09;。 29.讲讲T5和Bart的区…...

【嵌入式笔记】【C语言】struct union

结构体(Struct)定义: struct 结构体名 {member1; // 成员1,可以是任何基本数据类型或复合类型member2; // 成员2... };//例如: struct Point {float x;float y;...

【初学人工智能原理】【9】深度学习:神奇的DeepLearning

前言 本文教程均来自b站【小白也能听懂的人工智能原理】&#xff0c;感兴趣的可自行到b站观看。 代码及工具箱 本专栏的代码和工具函数已经上传到GitHub&#xff1a;1571859588/xiaobai_AI: 零基础入门人工智能 (github.com)&#xff0c;可以找到对应课程的代码 正文 深度…...

[RoarCTF 2019]Easy Calc1

打开题目 查看源码&#xff0c;看到 看到源代码有 calc.php&#xff0c;构造url打开 看到php审计代码&#xff0c; 由于页面中无法上传num&#xff0c;则输入 num&#xff0c;在num前加入一个空格可以让num变得可以上传&#xff0c;而且在进行代码解析时&#xff0c;php会把前…...

安卓APK安装包arm64-v8a、armeabi-v7a、x86、x86_64有何区别?如何选择?

在GitHub网站下载Android 安装包&#xff0c;Actions资源下的APK文件通常有以下版本供选择&#xff1a; 例如上图是某Android客户端的安装包文件&#xff0c;有以下几个版本可以选择&#xff1a; mobile-release.apk&#xff08;通用版本&#xff0c;体积最大&#xff09;mobi…...

【AI大模型】通义千问:开启语言模型新篇章与Function Call技术的应用探索

文章目录 前言一、大语言模型1.大模型介绍2.大模型的发展历程3.大模型的分类a.按内容分类b.按应用分类 二、通义千问1.通义千问模型介绍a.通义千问模型介绍b.应用场景c.模型概览 2.对话a.对话的两种方式通义千问API的使用 b.单轮对话Vue页面代码&#xff1a;Django接口代码 c.多…...

详细教程 MySQL 数据库 下载 安装 连接 环境配置 全面

数据库就是储存和管理数据的仓库&#xff0c;对数据进行增删改查操作&#xff0c;其本质是一个软件。 首先数据有两种&#xff0c;一种是关系型数据库&#xff0c;另一种是非关系型数据库。 关系型数据库是以表的形式来存储数据&#xff0c;表和表之间可以有很多复杂的关系&a…...

微信支付回调通知收不到的5个隐藏坑(附.NET Core实战解决方案)

微信支付回调通知失效的深度排查与.NET Core实战指南 当支付流程顺利完成但回调通知却神秘消失时&#xff0c;这种"薛定谔式的支付成功"往往让开发者陷入调试泥潭。本文将揭示五个容易被忽视的技术暗礁&#xff0c;并提供可直接集成到生产环境的.NET Core解决方案。 …...

深入解析FOC电机控制:从理论到实践的无传感器实现

1. 无传感器FOC控制的核心原理 磁场定向控制&#xff08;FOC&#xff09;本质上是在模拟直流电机的控制方式。想象一下小时候玩的四驱车——直流电机通过改变电压就能直接控制转速&#xff0c;简单粗暴。但三相交流电机就像个傲娇的艺术家&#xff0c;需要我们把三相电流"…...

重新定义数据标注:Label Studio如何让AI训练效率提升300%?

重新定义数据标注&#xff1a;Label Studio如何让AI训练效率提升300%&#xff1f; 【免费下载链接】label-studio Label Studio is a multi-type data labeling and annotation tool with standardized output format 项目地址: https://gitcode.com/GitHub_Trending/la/labe…...

SLAM Toolbox应用宝典:从技术原理到实战落地的全面指南

SLAM Toolbox应用宝典&#xff1a;从技术原理到实战落地的全面指南 【免费下载链接】slam_toolbox Slam Toolbox for lifelong mapping and localization in potentially massive maps with ROS 项目地址: https://gitcode.com/gh_mirrors/sl/slam_toolbox SLAM Toolbox…...

3月17枚举

package com.fangfa.day05.Enum;public class EnurmerDemo1 {public static void main(String[] args) {//为什么其他类里可以类名.对象名 因为这个对象名被static修饰了//若不修饰不行System.out.println(Season.SPRING);} } class Season{/*** Description* author Mao Ree…...

python-flask-djangol框架的婚恋相亲交友网站

目录技术选型与框架对比核心功能模块设计数据库模型示例&#xff08;Django ORM&#xff09;安全防护措施部署方案开发路线图项目技术支持源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作技术选型与框架对比 Flask&#xff1a;轻量级框架&a…...

用MATLAB从零实现六足机器人步态:交替三角与波动步态代码详解

用MATLAB从零实现六足机器人步态&#xff1a;交替三角与波动步态代码详解 六足机器人因其卓越的稳定性和地形适应能力&#xff0c;在野外勘探、灾难救援等领域展现出巨大潜力。而步态规划作为机器人运动控制的核心&#xff0c;直接决定了机器人的移动效率和稳定性。本文将带您从…...

AI短剧的风口来了!无需编程,全程技术支持,助你快速贴牌部署私有化系统

&#x1f525; AI短剧爆火&#xff0c;但你还在因为“没有技术团队”而错失风口&#xff1f; 2024-2025年&#xff0c;AI短剧无疑是内容创业最大的黑马。从AI换脸、AI配音到一键生成剧本&#xff0c;市场的需求呈指数级爆发。 然而&#xff0c;对于大多数手握流量渠道、有客户…...

效率飙升:用快马平台一键生成项目模板,告别重复的vscode环境配置

作为一个经常需要在新设备上配置开发环境的前端开发者&#xff0c;我深刻体会到重复搭建项目的痛苦。每次换电脑或者开新项目&#xff0c;都要从头安装VSCode插件、配置构建工具、集成UI库……这些琐碎工作至少会浪费半小时。最近发现InsCode(快马)平台能完美解决这个问题&…...

手把手教你为i.MX6ULL开发板适配非标准分辨率LCD(以1024x600 OV5640为例)

i.MX6ULL开发板非标准分辨率LCD适配实战&#xff1a;从寄存器配置到图像稳定输出 在嵌入式视觉系统开发中&#xff0c;摄像头与显示设备的适配往往成为项目落地的关键瓶颈。当面对非标准分辨率的LCD屏幕时&#xff0c;开发者需要深入理解图像采集与显示的全链路原理&#xff0c…...