CUDA入门系列课程,从最基础着手

news2024/11/17 15:46:47

CUDA入门系列课程,从最基础着手,突出的就是一个字“细”!!
github项目包含代码、博客、课件pdf下载地址:https://github.com/sangyc10/CUDA-code!
在这里插入图片描述

CUDA编程基础入门系列

https://github.com/sangyc10/CUDA-code

CUDA入门

    • CUDA 概论
    • CUDA安装
    • nvidia-smi 工具
    • CUDA编程
    • CUDA 线程模型
    • 线程索引计算
    • nvcc 编译流程和GPU计算能力
    • CUDA 程序兼容性问题
    • CUDA 矩阵加法运算
    • CUDA 错误检查


CUDA 概论

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

CUDA安装

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
把上述命令依次执行就可以安装了,安装好执行:nvcc -V, nvidia-smi
在这里插入图片描述
测试代码
在这里插入图片描述
编译执行,
在这里插入图片描述
使用了4*4=16个线程,所以会打印16次

nvidia-smi 工具

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

CUDA编程

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
cudaDeviceSynchronize()是设备同步函数,等待核函数执行。

CUDA 线程模型

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

线程索引计算

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

nvcc 编译流程和GPU计算能力

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

CUDA 程序兼容性问题

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
不要被下面的—误解了,应该是ppt的问题
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

CUDA 矩阵加法运算

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注意上面函数前面的__host__ device
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
示例代码

/*********************************************************************************************
 * file name  : matrixSum1D_GPU.cu
 * author     : 权 双
 * date       : 2023-08-04
 * brief      : 矩阵求和程序,通过调用核函数在GPU执行
***********************************************************************************************/

#include <stdio.h>
#include "../tools/common.cuh"

__global__ void addFromGPU(float *A, float *B, float *C, const int N)
{
    const int bid = blockIdx.x;
    const int tid = threadIdx.x;
    const int id = tid + bid * blockDim.x; 

    C[id] = A[id] + B[id];
    
}

void initialData(float *addr, int elemCount)
{
    for (int i = 0; i < elemCount; i++)
    {
        addr[i] = (float)(rand() & 0xFF) / 10.f;
    }
    return;
}

int main(void)
{
    // 1、设置GPU设备
    setGPU();

    // 2、分配主机内存和设备内存,并初始化
    int iElemCount = 512;                               // 设置元素数量
    size_t stBytesCount = iElemCount * sizeof(float);   // 字节数
    
    // (1)分配主机内存,并初始化
    float *fpHost_A, *fpHost_B, *fpHost_C;
    fpHost_A = (float *)malloc(stBytesCount);
    fpHost_B = (float *)malloc(stBytesCount);
    fpHost_C = (float *)malloc(stBytesCount);
    if (fpHost_A != NULL && fpHost_B != NULL && fpHost_C != NULL)
    {
        memset(fpHost_A, 0, stBytesCount);  // 主机内存初始化为0
        memset(fpHost_B, 0, stBytesCount);
        memset(fpHost_C, 0, stBytesCount);
    }
    else
    {
        printf("Fail to allocate host memory!\n");
        exit(-1);
    }

    // (2)分配设备内存,并初始化
    float *fpDevice_A, *fpDevice_B, *fpDevice_C;
    cudaMalloc((float**)&fpDevice_A, stBytesCount);
    cudaMalloc((float**)&fpDevice_B, stBytesCount);
    cudaMalloc((float**)&fpDevice_C, stBytesCount);
    if (fpDevice_A != NULL && fpDevice_B != NULL && fpDevice_C != NULL)
    {
        cudaMemset(fpDevice_A, 0, stBytesCount);  // 设备内存初始化为0
        cudaMemset(fpDevice_B, 0, stBytesCount);
        cudaMemset(fpDevice_C, 0, stBytesCount);
    }
    else
    {
        printf("fail to allocate memory\n");
        free(fpHost_A);
        free(fpHost_B);
        free(fpHost_C);
        exit(-1);
    }

    // 3、初始化主机中数据
    srand(666); // 设置随机种子
    initialData(fpHost_A, iElemCount);
    initialData(fpHost_B, iElemCount);
    
    // 4、数据从主机复制到设备
    cudaMemcpy(fpDevice_A, fpHost_A, stBytesCount, cudaMemcpyHostToDevice); 
    cudaMemcpy(fpDevice_B, fpHost_B, stBytesCount, cudaMemcpyHostToDevice); 
    cudaMemcpy(fpDevice_C, fpHost_C, stBytesCount, cudaMemcpyHostToDevice);


    // 5、调用核函数在设备中进行计算
    dim3 block(32);
    dim3 grid(iElemCount / 32);

    addFromGPU<<<grid, block>>>(fpDevice_A, fpDevice_B, fpDevice_C, iElemCount);    // 调用核函数
    // cudaDeviceSynchronize();

    // 6、将计算得到的数据从设备传给主机
    cudaMemcpy(fpHost_C, fpDevice_C, stBytesCount, cudaMemcpyDeviceToHost);


    for (int i = 0; i < 10; i++)    // 打印
    {
        printf("idx=%2d\tmatrix_A:%.2f\tmatrix_B:%.2f\tresult=%.2f\n", i+1, fpHost_A[i], fpHost_B[i], fpHost_C[i]);
    }

    // 7、释放主机与设备内存
    free(fpHost_A);
    free(fpHost_B);
    free(fpHost_C);
    cudaFree(fpDevice_A);
    cudaFree(fpDevice_B);
    cudaFree(fpDevice_C);

    cudaDeviceReset();
    return 0;
}

在这里插入图片描述
在这里插入图片描述

__device__ float add(const float x, const float y)
{
    return x + y;
}

__global__ void addFromGPU(float *A, float *B, float *C, const int N)
{
    const int bid = blockIdx.x;
    const int tid = threadIdx.x;
    const int id = tid + bid * blockDim.x; // 513  32*17=544

    if (id >= N) return;
    C[id] = add(A[id], B[id]);
    
}

CUDA 错误检查

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

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

相关文章

Java冲突

本身 父类 接口(多) 如果出现同样名字的方法,就会出现冲突 * 情况描述1: * 当一个类,继承了父类,实现了某接口,父类中的成员方法和接口中的方法重名 * 解决方法: * 子类就近选择父类成员方法 亲爹优先原则 * *使用格式: * 父类:super.方法名 * 父接口:父接口名.super.方…

指针学习总结

当指针本身定义的类型不同十&#xff0c;指向的一次性取值长度也不同 数组元素的指针 数组存放字符串 数组存放字符串时存放在栈区&#xff0c;sizeof(str1) 128字节 字符指针指向字符串 str2此时存放的是h的地址&#xff0c;因此sizeof(str2) 4字节或者8字节 并且文字常量…

快速回复app是什么样

在电商领域&#xff0c;掌握一些必备的软件工具是提高工作效率、优化运营流程以及提升用户体验的关键。本文将为您介绍做电商必备的几个软件&#xff0c;帮助您更好地开展电商业务。 ​ 快速回复APP&#xff1a;重新定义沟通效率 在快节奏的现代社会中&#xff0c;人们对于沟通…

Python实现“黑猫投诉平台,舆论监控系统”

黑猫投诉平台&#xff0c;舆论监控系统 BuzzMonitor https://github.com/nangongchengfeng/BuzzMonitor.git 简介 "黑猫投诉"舆论监控系统是一款专为快速识别和响应网络投诉而设计的应用&#xff0c;旨在帮助企业或机构第一时间掌握公众意见和反馈。通过实时监控网…

C++:运算符重载和“const”成员

hello&#xff0c;各位小伙伴&#xff0c;本篇文章跟大家一起学习《C&#xff1a;运算符重载》&#xff0c;感谢大家对我上一篇的支持&#xff0c;如有什么问题&#xff0c;还请多多指教 &#xff01; 文章目录 赋值运算符重载1. 运算符重载2.赋值运算符重载第一个点第二个点&…

C++感受5-HelloWorld 函数版

借助 Hello (std::string_view XXX) 函数&#xff0c;快速向你心目中的女神问好。 视频 ffls08-HelloWorld-函数版 函数简述 函数用于封装程序中需要反复执行的事情。事情每一次执行时&#xff0c;所需要的初始数据的变化&#xff0c;由函数参数体现。 定义函数时所写的参数&…

小孩子不懂事,写着玩的

目录 Web攻防 特有漏洞 ASP安全 ASPX&#xff08;.NET&#xff09;安全 PHP安全 JavaWeb安全 JS&#xff0c;Node.js安全 Java安全 Python安全 通用漏洞 SQL注入 MySQL-root高权限读写注入 PostgreSQL-高权限读写注入 MSSQL-sa高权限读写执行注入 SQL注入体系 o…

虹科Pico汽车示波器 | 免拆诊断案例 | 2006 款林肯领航员车发动机怠速抖动

故障现象 一辆2006款林肯领航员车&#xff0c;搭载5.4 L发动机&#xff0c;累计行驶里程约为26万km。该车因发动机怠速抖动故障进厂维修&#xff0c;维修人员更换了火花塞、点火线圈及凸轮轴位置传感器&#xff0c;清洗了积炭和喷油器&#xff0c;故障依旧&#xff0c;于是向笔…

Linux系统硬盘读写慢,如何排查

若服务器硬盘读写慢&#xff0c;导致处理性能降低&#xff0c;用户响应慢&#xff08;例如&#xff1a;ssh登录操作文件&#xff0c;处理很慢说明磁盘很慢&#xff09; 1.查看硬盘是否繁忙 top 若值比较大&#xff0c;说明当前硬盘比较繁忙&#xff0c;有大量读写操作&#x…

PO框架【自动化测试】

对象&#xff1a;Tpshop商城 需求&#xff1a;更换头像 操作步骤&#xff1a; 个人信息–头像–上传图片–图片确认–确认保存 核心代码&#xff1a; # 进入frame框架[不熟] driver.switch_to.frame(driver.find_element_by_xpath(//*[id"layui-layer-iframe1"]))…

链式存储的特点与设计由来

简介 案例引入 相关术语 两种结构的区别与实现 注&#xff1a; 特点

迪拜Token2049展会圆满落幕,MVP成唯一MEMECOIN项目,闪耀全场!

近日&#xff0c;据多家媒体报道&#xff0c;于全球财富聚集地迪拜举行的全球性大型区块链会议TOKEN2049圆满落幕。来自全球的5000多家公司和100多个国家10000名参与者共同参会&#xff0c;讨论未来30年至50年关于区块链行业的宏大未来。 新晋MEMECOIN项目MAGA VP&#xff08;…

希捷HDD最新财报:销售同比下降11%,环比增长6%,4Q24前景看好

Seagate Technology Holdings plc公布了截至2024年3月29日的第三财季财务业绩。 “随着云需求改善、我们强大的运营纪律和价格执行&#xff0c;希捷3月季度的营收增长了6%&#xff0c;非GAAP每股收益较上一季度翻了一番多。这种组合为我们市场复苏时回归目标利润率奠定了基础。…

【C++】string常用函数总结及其模拟实现

目录 一、String的构造 二、String的大小和容量 三、String的字符串比较 四、string的访问 五、String的字符插入 六、string拼接字符串 七、string的删除 八、string的查找 九、string的分割 模拟实现 一、String的构造 string()&#xff1a;生成空字符串&#xff1…

Llama3 中文通用 Agent 微调模型来啦!(附手把手微调实战教程)

节前&#xff0c;我们组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂朋友、参加社招和校招面试的同学&#xff0c;针对算法岗技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备、面试常考点分享等热门话题进行了深入的讨论。 基于大家…

文本语音互相转换系统设计

title: 文本语音互相转换系统设计 date: 2024/4/24 21:26:15 updated: 2024/4/24 21:26:15 tags: 需求分析模块化设计性能优化系统安全智能化跨平台区块链 第一部分&#xff1a;导论 第一章&#xff1a;背景与意义 文本语音互相转换系统的定义与作用 文本语音互相转换系统是…

js进行数据移除性能比较(splice,map)

当使用 splice() 方法处理大量数据时&#xff0c;确实会遇到性能问题&#xff0c;因为它涉及到移动数组中的元素&#xff0c;导致操作的时间复杂度为 O(n)。对于大量数据&#xff0c;频繁的插入和删除可能会导致性能下降。 1、设置数组数据为10000&#xff0c;使用splice移除数…

linux——yum工具详解

yum是linux中自动解决软件包依赖关系的管理器 同时&#xff0c;yum也是一个rpm软件 这里使用yum install nginx安装nginx

前缀和 求数列的子序列的K倍区间

(直接截图比复制文字要好多了) 不会做的时候我去看了之前做的关于这道题目的笔记&#xff0c; &#xff08;Ak 1&#xff09;% k 1 &#xff08;Ak 1 Ak&#xff09;% k 1 只要发现了同余数的情况就说明有一个区间满足了题目的要求。 这个方法的精妙之处就在于前缀和包括了…

窗函数的选择

不同的窗函数实质上时对矩形窗进行了不同程度的加权得到的不同类型的窗函数。 将模拟角频率转换为了数字角频率 矩形窗旁瓣过大&#xff0c;两个频率的峰值相差较大&#xff0c;因此无法识别&#xff0c;可以使用旁瓣非常小的窗函数来进行分辨&#xff0c;只是想要达到相同的分…