CUDA 内核函数

news2024/9/22 15:49:42

文章目录

  • 一、简介
  • 二、实现代码
  • 三、实现效果
  • 参考资料

一、简介

CUDA为我们提供了可扩展的编程模型:它的核心是三个关键的抽象——线程组的层次结构、共享内存和阻塞同步——它们只是作为一组最小的语言扩展暴露给外部使用人员。这些抽象提供细粒度数据并行性和线程并行性,嵌套在粗粒度数据并行性和任务并行性中。它们引导程序员将问题划分为可以由线程块独立并行解决的粗子问题,并将每个子问题划分为可以由线程块内的所有线程并行协作解决的细子问题。这种分解通过允许线程在解决每个子问题时进行协作来保持语言的表达性,同时支持自动可伸缩性。实际上,每个线程块都可以在GPU内任何可用的多处理器上调度,以任何顺序,并发或顺序,以便编译后的CUDA程序可以在下图所示的任意数量的多处理器上执行,并且只有运行时系统需要知道物理多处理器计数。这种可扩展的编程模型允许GPU架构通过简单地扩展多处理器和内存分区的数量来跨越广泛的市场范围:从高性能爱好者的GeForce GPU和专业的Quadro和Tesla计算产品到各种廉价的主流GeForce GPU(参见支持cuda的GPU以获得所有支持cuda的GPU的列表)。

GPU是围绕一组流多处理器(SMs)构建的(详见硬件实现)。一个多线程程序被分割成相互独立执行的线程块,这样多处理器的GPU会比少处理器的GPU在更短的时间内自动执行程序。

OK,说了这么多也只是说了一些CUDA的设计理念,对于我们真正使用上来讲,还是要聚焦于代码方面。我们首先要明确一个概念CUDA c++扩展了c++语言,它允许我们定义CUDA c++函数,只不过这种函数通过供多个线程使用,称为内核函数,当调用时,它由N个不同的CUDA线程并行执行N次,而不是像常规的c++函数那样只执行一次。

使用方式:内核是使用__global__声明说明符定义的,对于给定的内核调用,执行该内核的CUDA线程数是使用新的<<<…>>>执行配置语法(参见c++语言扩展)。每个执行内核的线程都有一个唯一的线程ID,可以通过内置变量在内核中访问。这里我们举一个简单的例子。

二、实现代码

#include <iostream>
#include <vector>

#include <cuda_runtime.h>
#include <device_launch_parameters.h>

//定义内核函数
__global__ void VecAdd(float* A, float* B, float* C)
{
    int i = threadIdx.x;
    C[i] = A[i] + B[i];
}

int main()
{
    const int N = 1024; // 假设我们处理1024个元素的向量  
    size_t size = N * sizeof(float);

    // 1. 分配主机内存
    std::vector<float> dataA(size), dataB(size), dataC(size);
    for (int i = 0; i < N; ++i) {
        dataA[i] = rand() / (float)RAND_MAX;
        dataB[i] = rand() / (float)RAND_MAX;
    }

    float* h_A = dataA.data();
    float* h_B = dataB.data();
    float* h_C = dataC.data();

    // 2. 分配设备内存  
    float* d_A, * d_B, * d_C;
    cudaMalloc(&d_A, size);
    cudaMalloc(&d_B, size);
    cudaMalloc(&d_C, size);

    // 3. 复制数据到设备  
    cudaMemcpy(d_A, h_A, size, cudaMemcpyHostToDevice);
    cudaMemcpy(d_B, h_B, size, cudaMemcpyHostToDevice);

    // 4. 启动内核  
    VecAdd <<<1, N >> > (d_A, d_B, d_C);      //这里我们只使用一个线程块,N个线程

    // 等待GPU完成工作  
    cudaDeviceSynchronize();

    // 5. 复制结果回主机  
    cudaMemcpy(h_C, d_C, size, cudaMemcpyDeviceToHost);

    // 6. 验证结果(这里只是打印第一个元素作为示例)  
    std::cout << "A[0] = " << h_A[0] << std::endl 
        << "B[0] = " << h_B[0] << std::endl
        << "C[0] = " << h_C[0] << std::endl;

    // 7. 释放资源  
    cudaFree(d_A);
    cudaFree(d_B);
    cudaFree(d_C);
}

三、实现效果

在这里插入图片描述

参考资料

[1]https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html

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

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

相关文章

MyBatis的学习————上篇

目录 一、MyBatis简介 1、MyBatis的历史 2、MyBatis的特性 3、和其它持久化层技术的比较 二、搭建MyBatis 1、开发环境 ​编辑2、创建Maven工程 3、创建MyBatis核心配置文件 4、创建mapper接口 5、创建Mybatis的映射文件 6、测试功能 7、功能优化 8、修改和删除方…

重生奇迹MU最合适PK的几个职业

重生奇迹MU是一款备受玩家青睐的经典游戏&#xff0c;其中的PK系统更是吸引了众多玩家的关注。在众多职业中&#xff0c;哪些职业最适合PK呢&#xff1f; PK作为重生奇迹MU的一种娱乐方式&#xff0c;已成为该游戏核心系统之一&#xff0c;并在多年的流行中仍能带给玩家许多乐…

python正则表达式的一些问题

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

Matplotlib中twinx() 函数的用法

ax1.twinx() 是 Matplotlib 库中的一个函数&#xff0c;用于在同一个图中创建一个共享 x 轴但具有独立 y 轴的双 y 轴图表。这个函数非常适合用来在同一张图中绘制两组具有不同 y 轴度量的变量&#xff0c;使得它们可以共享 x 轴&#xff0c;但彼此之间有不同的 y 轴尺度。 ax…

SpringBoot日常:Spring扩展接口之InitializingBean

文章目录 简介源码分析应用场景代码示例运行示例 简介 这篇文章主要介绍了Spring中InitializingBean的使用详细解析&#xff0c;InitializingBean是Spring提供的拓展性接口&#xff0c;提供了属性初始化后的处理方法,它只有一个afterPropertiesSet方法&#xff0c;凡是继承该接…

中断的引入

中断系统是为使CPU具有对外界紧总事件的实时处理能力而设置的 当中央处理机CPU正在处理某件事的时候外界发生了紧急事件请求&#xff0c;要求CPU暂停当前的工作&#xff0c;转而去处理这个紧急事件&#xff0c;处理完以后&#xff0c;再回到原来被中断的地方&#xff0c;继续原…

进程间的同步与互斥

1、计数信号量及其初始化 由于事件发生的次数可能不止一次&#xff0c;或者资源可用的数量可能不止一个&#xff0c;因此&#xff0c;信号量内部会维护一个计数器&#xff0c;用于表示某种事件发生的次数或者某种资源可用的数量。 信号量至少提供两种操作&#xff1a;一种等待…

flutter 手写时钟

前言&#xff1a; 之前看过别人写的 js实现的 时钟表盘 挺有意思的&#xff0c;看着挺好 这边打算自己手动实现以下。顺便记录下实现过程&#xff1a;大致效果如下&#xff1a; 主要技术点&#xff1a; 表盘内样 倒角&#xff1a; 表盘下半部分是有一点倒角的感觉&#xff0c;…

YOLOv8独家改进:轻量化改进 | 高效移动应用的卷积加性自注意Vision Transformer

💡💡💡本文独家改进:轻量化改进之高效移动应用的卷积加性自注意Vision Transformer,构建了一个新颖且高效实现方式——卷积加性相似度函数,并提出了一种名为卷积加性标记混合器(CATM) 的简化方法来降低计算开销 💡💡💡性能比较:计算量参数量均有一定程度降低…

别盲目选择!2024年超级兔子与TOP3数据恢复,效率比拼全记录

在现在这个数字化的社会里&#xff0c;数据对我们来说太重要了。不管是家里的照片、工作文件&#xff0c;还是那些记录着美好时光的视频&#xff0c;要是弄丢了&#xff0c;肯定特别着急。不过别担心&#xff0c;今天咱们就来聊聊几款Windows系统上的数据恢复好帮手——超级兔子…

布局容器Grid、StackPanel、GroupBox、DockPanel、WrapPanel

Grid——网格布局&#xff0c;其中控件或容器需指定位置 StackPanel——堆叠面板&#xff0c;其中的控件水平布局、竖直布局 DockPanel——停靠面板&#xff0c;内部控件或容器可以放置在上、下、左、右 WrapPanel——可以看作是具有自动换行功能的StackPanel容器。窗体太小…

360杀毒恢复查杀的软件

360的查杀恢复区不太好找&#xff0c;特此记录&#xff1a; 主界面/管理中心面板/安全操作中心 安全操作中心/可恢复区&#xff1a;

UE5蓝图 抽卡出货概率

SSR概率0.1 SR概率0.2 R概率0.7 ps&#xff1a;数组内相加为1。且从小到大排序。

单片机相关面试问题精选

1. 基础概念类问题 什么是单片机&#xff1f;它有哪些主要应用&#xff1f; 答案要点&#xff1a;单片机是一种集成在单一芯片上的微型计算机&#xff0c;包含CPU、存储器、输入输出接口等&#xff0c;广泛应用于工业自动化、智能家居、汽车电子、医疗设备等领域。它能够实现复…

黑神话:悟空热背后的散热秘密:无压烧结银

黑神话&#xff1a;悟空热背后的散热秘密&#xff1a;无压烧结银 随着《黑神话:悟空》这款高画质、高性能要求的游戏在全球范围内的火爆&#xff0c;玩家们对于游戏设备的性能需求也达到了前所未有的高度。为了满足这种对极致游戏体验的追求&#xff0c;游戏主机和高端显卡等硬…

谷歌首页快捷方式变为一行的解决办法

也挺离谱的&#xff0c;今早上班刚打开谷歌浏览器&#xff0c;首页快捷方式就变成一排了&#xff0c;对于而且快捷方式还不能拖拽自定义排序&#xff0c;这使得我这位用习惯6年的双排老用户完全不能忍&#xff0c;打工人上班的怨气更重了。 经过几番周折中关于找到如下解决方案…

高级测试进阶 Centos7安装 Docker容器

前言 OS 安装环境要求 要安装 Docker Engine&#xff0c;需要 CentOS 7 的维护版本&#xff0c;不支持或未测试存档版本&#xff08;一句话&#xff1a;需要正常迭代版本的 Centos 7 系统&#xff0c;其他系统都不行&#xff09; 必须启用 centos-extras 存储库&#xff0c;…

Mysql 巧秒避开 varchar 类型的 max()、min() 函数的坑

比如&#xff0c;有一个这样的表&#xff0c; 里面存储的 数字 但是数据库表类型 是varchar 比如这个表的 nums &#xff1a; 样例数据&#xff1a; 如果我现在需要查询出这表里面&#xff0c;nums 最大的值 &#xff1a; 很多人可能不注意就会去使用 max &#xff08;&#…

08--kubernetes可视化界面与Daemonset

前言&#xff1a;前几章写的内容太多了&#xff0c;后面打算写k8s持久化篇幅也不小&#xff0c;这一章算作过度章节&#xff0c;内容简单一些&#xff0c;主要是K8S_web界面与Daemonset控制器。 1、Dashboard Dashboard是一个图形化界面&#xff0c;用于汇总和展示来自不同数…

酶荧光底物;Ac-ESEN-AMC;Ac-Glu-Ser-Glu-Asn-AMC;CAS:896420-43-2

【Ac-ESEN-AMC 简介】 Ac-Glu-Ser-Glu-Asn-AMC 通常用作酶的荧光底物&#xff0c;特别是作为溶酶体处理酶&#xff08;Vacuolar Processing Enzyme, VPE&#xff09;的选择性底物。在生物化学研究中&#xff0c;这类底物可以用于检测和定量特定酶的活性&#xff0c;因为当底物被…