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

第四章 kernel函数基础篇

cuda教程目录

第一章 指针篇
第二章 CUDA原理篇
第三章 CUDA编译器环境配置篇
第四章 kernel函数基础篇
第五章 kernel索引(index)篇
第六章 kenel矩阵计算实战篇
第七章 kenel实战强化篇
第八章 CUDA内存应用与性能优化篇
第九章 CUDA原子(atomic)实战篇
第十章 CUDA流(stream)实战篇
第十一章 CUDA的NMS算子实战篇
第十二章 YOLO的部署实战篇
第十三章 基于CUDA的YOLO部署实战篇

cuda教程背景

随着人工智能的发展与人才的内卷,很多企业已将深度学习算法的C++部署能力作为基本技能之一。面对诸多arm相关且资源有限的设备,往往想更好的提速,满足更高时效性,必将更多类似矩阵相关运算交给CUDA处理。同时,面对市场诸多教程与诸多博客岑子不起的教程或高昂教程费用,使读者(特别是小白)容易迷糊,无法快速入手CUDA编程,实现工程化。
因此,我将结合我的工程实战经验,我将在本专栏实现CUDA系列教程,帮助读者(或小白)实现CUDA工程化,掌握CUDA编程能力。学习我的教程专栏,你将绝对能实现CUDA工程化,完全从环境安装到CUDA核函数编程,从核函数到使用相关内存优化,从内存优化到深度学习算子开发(如:nms),从算子优化到模型(以yolo系列为基准)部署。最重要的是,我的教程将简单明了直切主题,CUDA理论与实战实例应用,并附相关代码,可直接上手实战。我的想法是掌握必要CUDA相关理论,去除非必须繁杂理论,实现CUDA算法应用开发,待进一步提高,将进一步理解更高深理论。

cuda教程内容

第一章到第三章探索指针在cuda函数中的作用与cuda相关原理及环境配置;

第四章初步探索cuda相关函数编写(globaldevice、__host__等),实现简单入门;

第五章探索不同grid与block配置,如何计算kernel函数的index,以便后续通过index实现各种运算;

第六、七章由浅入深探索核函数矩阵计算,深入探索grid、block与thread索引对kernel函数编写作用与影响,并实战多个应用列子(如:kernel函数实现图像颜色空间转换);

第八章探索cuda内存纹理内存、常量内存、全局内存等分配机制与内存实战应用(附代码),通过不同内存的使用来优化cuda计算性能;

第九章探索cuda原子(atomic)相关操作,并实战应用(如:获得某些自加索引等);

第十章探索cuda流stream相关应用,并给出相关实战列子(如:多流操作等);

第十一到十三章探索基于tensorrt部署yolo算法,我们首先将给出通用tensorrt的yolo算法部署,该部署的前后处理基于C++语言的host端实现,然后给出基于cuda的前后处理的算子核函数编写,最后数据无需在gpu与host间复制操作,实现gpu处理,提升算法性能。

目前,以上为我们的cuda教学全部内容,若后续读者有想了解知识,可留言,我们将根据实际情况,更新相关教学内容。

大神忽略


文章目录

  • cuda教程目录
  • cuda教程背景
  • cuda教程内容
  • 前言
  • 一、global、device、host的含义
    • 1、global函数
    • 2、device函数
    • 3、host函数
  • 二、host、global、device函数关系
    • 1、host调用global函数
      • 2、global调用device函数
      • 3、host调用特殊device函数
  • 三、host、global、device函数关系结论
    • 1、函数与设备关系结论
    • 2、函数间调用形式结论
  • 四、整体代码


前言

本章开始,我们正式进入编程环节。本章介绍cuda编程基础,host或device端如何调用函数,重点说明global、device与host限定词的使用。


一、global、device、host的含义

CUDA是通过函数类型的限定词区别函数是否为host或device调用函数,主要以下三个函数类型限定词。

1、global函数

global函数:在device上执行,从host中调用,返回类型必须是void,不支持可变参数,不能成为类成员函数。且__global__修饰的函数用<<<>>>的方式调用,注意用__global__定义的kernel是异步的,这意味着host不会等待kernel执行完就执行下一步。
__global__实际为核函数,后面将有大量使用列子。以下说明核函数形式与参数:

运行时API通过在函数名称和参数列表之间插入<<<Dg, Db, Ns, S>>>的形式来指定。

Dg 的类型为dim3,指定网格的维度和大小,Dg.x * Dg.y 等于所发射的块数量;
Db 的类型为dim3,指定各块的维度和大小,Db.x * Db.y *Db.z 等于各块的线程数量;
Ns 的类型为size_t,指定各块为此调用动态分配的共享存储器(除静态分配的存储器之外),这些动态分配的存储器可供声明为动态数组的其他任何变量使用,Ns 是一个可选参数,默认值为0;
S 的类型为cudaStream t,指定相关流;S 是一个可选参数,默认值为0。

2、device函数

device函数:在device上执行,单仅可以从device中调用,不可以和__global__同时用。

3、host函数

host函数:在host上执行,仅可以从host上调用,一般省略不写,不可以和__global__同时用,但可和__device__同时使用,此时函数会在device和host都编译。

二、host、global、device函数关系

结论:host能调用global函数,global能调用device函数

1、host调用global函数

host调用global函数,类似平常普通函数调用方式,但每个global函数需要<<<Dg, Db, Ns, S>>>参数,代码如下:

test_kernel << <dim3(1), dim3(m*n), 0, nullptr >> > (g_a, g_c);

2、global调用device函数

device是设备上使用的函数,一般只能被global核函数调用,代码如下:

float sigmoid_host(float x) {float y= 1 / (1 + exp(-x));return y;
}
__device__  float sigmoid(float x) {float y= 1 / (1 + exp(-x));return y;
}
__global__ void test_kernel(float* a, float* c) {int idx = threadIdx.x ;c[idx] = sigmoid(a[idx]); //正确方式//c[idx] = sigmoid_host(a[idx]);//绝对错误,无法调用,即:global函数无法调用host函数,只能调用devices函数
}

注意:gloabal 函数绝对无法调用host函数

执行结果如下图:
在这里插入图片描述

3、host调用特殊device函数

一般而言,device只能被global函数调用,但有一种特色device函数可被host函数调用,即:函数被host限定词使用,如下sigmod_device_host函数形式,能被host函数调用。具体实现代码如下:

__device__ __host__  float sigmoid_device_host(float x) {float y = 1 / (1 + exp(-x));return y;
}
void host2device(){float y=sigmoid_device_host(1.25);std::cout << y << endl;std::cout << "success:host calling  device+host  " << endl;//以下执行失败   try {float y = sigmoid_host(1.25);throw std::runtime_error("error: fail");   } catch (std::runtime_error err) {std::cout << "fail:host calling device" << endl;}}

执行结果如下:
在这里插入图片描述

三、host、global、device函数关系结论

1、函数与设备关系结论

a、host函数无法调用device函数,但可调用__device__ __host__的2个限定函数。

b、device函数在设备gpu上执行,host函数在cpu上执行;

c、global函数通过cpu调用,而global通常为kernel函数,是需要将数据转到gpu上运行。

2、函数间调用形式结论

a、global函数无法调用host函数,可调用device函数;

b、host函数可调用host函数与global函数,可调用组合__device__ __host__函数(实际调用host函数);

c、device函数可调用device函数;

四、整体代码

函数间调用关系代码如下:
注:附数源码链接[点击这里](https://github.com/tangjunjun966/cuda-tutorial-master)

#include <iostream>
#include <time.h>
#include "opencv2/highgui.hpp"  //实际上在/usr/include下
#include "opencv2/opencv.hpp"
#include "device_launch_parameters.h"
#include <cuda_runtime_api.h>
using namespace cv;
using namespace std;
/*************************************第四节-CUDA函数基础**********************************************/
float sigmoid_host(float x) {float y= 1 / (1 + exp(-x));return y;
}
__device__  float sigmoid(float x) {float y= 1 / (1 + exp(-x));//float y = sigmoid_host(x);return y;
}
__global__ void test_kernel(float* a, float* c) {int idx = threadIdx.x ;c[idx] = sigmoid(a[idx]); //正确方式//c[idx] = sigmoid_host(a[idx]);//绝对错误,无法调用,即:global函数无法调用host函数,只能调用devices函数  
}void Print_dim(float* ptr, int N) {for (int i = 0; i < N; i++){std::cout << "value:\t" << ptr[i] << std::endl;}
}
void init_variables_float(float* a,  int m, int n) {//初始化变量std::cout << "value of a:" << endl;for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {a[i * n + j] = rand()/4089 ;std::cout << "\t" << a[i * n + j];}std::cout << "\n";}
}
void global2device() {const int m = 4;const int n = 2;//分配host内存float* a, * c;cudaMallocHost((void**)&a, sizeof(float) * m * n);cudaMallocHost((void**)&c, sizeof(float) * m * n);//变量初始化init_variables_float(a, m, n);// 分配gpu内存并将host值复制到gpu变量中float* g_a;cudaMalloc((void**)&g_a, sizeof(float) * m * n);cudaMemcpy(g_a, a, sizeof(float) * m * n, cudaMemcpyHostToDevice);float* g_c;cudaMalloc((void**)&g_c, sizeof(float) * m * n);test_kernel << <dim3(1), dim3(m * n), 0, nullptr >> > (g_a, g_c);cudaMemcpy(c, g_c, sizeof(float) * m * n, cudaMemcpyDeviceToHost);Print_dim(c, m * n);
}__device__ __host__  float sigmoid_device_host(float x) {float y = 1 / (1 + exp(-x));return y;
}
void host2device(){float y=sigmoid_device_host(1.25);std::cout << y << endl;std::cout << "success:host calling  device+host  " << endl;//以下执行失败   try {float y = sigmoid_host(1.25);throw std::runtime_error("error: fail");   } catch (std::runtime_error err) {std::cout << "fail:host calling device" << endl;}
}void function_criterion_main() {//global2device();//host<--global<--devicehost2device();
}

相关文章:

第四章 kernel函数基础篇

cuda教程目录 第一章 指针篇 第二章 CUDA原理篇 第三章 CUDA编译器环境配置篇 第四章 kernel函数基础篇 第五章 kernel索引(index)篇 第六章 kenel矩阵计算实战篇 第七章 kenel实战强化篇 第八章 CUDA内存应用与性能优化篇 第九章 CUDA原子(atomic)实战篇 第十章 CUDA流(strea…...

JVM:运行时数据区域(白话文)

最近有时间在看一本<深入了解Java虚拟机>的书籍&#xff0c;这本书是一个中国人&#xff0c;名叫周志明的人写的。相比于其他翻译过来的技术书籍&#xff0c;这本书还是挺通俗易懂的。先前有和彬哥在聊&#xff0c;他说如果是自己一个人看的话会很枯燥&#xff0c;很难坚…...

Go语言并发编程(千锋教育)

Go语言并发编程&#xff08;千锋教育&#xff09; 视频地址&#xff1a;https://www.bilibili.com/video/BV1t541147Bc?p14 作者B站&#xff1a;https://space.bilibili.com/353694001 源代码&#xff1a;https://github.com/rubyhan1314/go_goroutine 1、基本概念 1.1、…...

CSS革命:用Sass/SCSS引领前端创新

目录 前言SCSSSassSass 和 SCSS 的区别 前言 在现代的前端开发中&#xff0c;CSS已成为呈现网页和应用程序样式的核心。然而&#xff0c;原生的CSS语法在大型项目中可能变得混乱、冗长且难以维护。 为了解决这些问题&#xff0c;SCSS&#xff08;Sass CSS&#xff09;和Sass&am…...

MAPPO 算法的深度解析与应用和实现

【论文研读】 The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games 说明&#xff1a; 来源&#xff1a;36th Conference on Neural Information Processing Systems (NeurIPS 2022) Track on Datasets and Benchmarks. 是NIPS文章&#xff0c;质量有保障&…...

API接口的涉及思路以及部分代码

在现代软件开发中&#xff0c;API&#xff08;Application Programming Interface&#xff09;接口扮演了一个至关重要的角色。通过API接口&#xff0c;不同的应用程序、系统或服务之间可以进行数据交换和相互调用&#xff0c;实现功能的扩展和集成。本文将探讨API接口的设计思…...

Stable Diffusion无需代码连接QQ邮箱的方法

Stable Diffusion用户使用场景&#xff1a; 电商商家在产品测试阶段&#xff0c;通过微信社群日常收集用户对产品设计的反馈&#xff0c;包括对产品的修改建议或外观设计等&#xff0c;并将这些反馈上传至集简云小程序。然后&#xff0c;他们使用Stable Diffusion AI工具生成图…...

Excel表格(一)

1.单一栏的宽度和高度设置 2.大标题的跨栏居中 3.让单元格内的文字------自动适应 4.序号递增 5.货币符号 6.日期格式的选择 选到单元格&#xff0c;选中对应的日期格式 7.自动求和的计算 然后在按住回车键即可求出当前行的金额 点击自动求和 8.冻结表格栏 9.排序 1.单栏排序 …...

详细介绍渗透测试与漏洞扫描

一、概念 渗透测试&#xff1a; 渗透测试并没有一个标准的定义&#xff0c;国外一些安全组织达成共识的通用说法&#xff1b;通过模拟恶意黑客的攻击方法&#xff0c;来评估计算机网络系统安全的一种评估方法。这个过程包括对系统的任何弱点、技术缺陷或漏洞的主动的主动分析…...

Scikit-learn聚类方法代码批注及相关练习

一、代码批注 代码来自&#xff1a;https://scikit-learn.org/stable/auto_examples/cluster/plot_dbscan.html#sphx-glr-auto-examples-cluster-plot-dbscan-py import numpy as np from sklearn.cluster import DBSCAN from sklearn import metrics from sklearn.datasets …...

C#程序的启动显示方案(无窗口进程发送消息) - 开源研究系列文章

今天继续研究C#的WinForm的实例显示效果。 我们上次介绍了Winform窗体的唯一实例运行代码(见博文&#xff1a;基于C#的应用程序单例唯一运行的完美解决方案 - 开源研究系列文章 )。这就有一个问题&#xff0c;程序已经打开了&#xff0c;这时候再次运行该应用程序&#xff0c;…...

java泛型和通配符的使用

泛型机制 本质是参数化类型(与方法的形式参数比较&#xff0c;方法是参数化对象)。 优势:将类型检查由运行期提前到编译期。减少了很多错误。 泛型是jdk5.0的新特性。 集合中使用泛型 总结&#xff1a; ① 集合接口或集合类在jdk5.0时都修改为带泛型的结构② 在实例化集合类时…...

【网络】自定义协议 | 序列化和反序列化 | 以tcpServer为例

本文首发于 慕雪的寒舍 以tcpServer的计算器服务为例&#xff0c;实现一个自定义协议 阅读本文之前&#xff0c;请先阅读 tcpServer 本文完整代码详见 Gitee 1.重谈tcp 注意&#xff0c;当下所对tcp的描述都是以简单、方便理解起见&#xff0c;后续会对tcp协议进行深入解读 …...

06-3_Qt 5.9 C++开发指南_多窗体应用程序的设计(主要的窗体类及其用途;窗体类重要特性设置;多窗口应用程序设计)

文章目录 1. 主要的窗体类及其用途2. 窗体类重要特性的设置2.1 setAttribute()函数2.2 setWindowFlags()函数2.3 setWindowState()函数2.4 setWindowModality()函数2.5 setWindowOpacity()函数 3. 多窗口应用程序设计3.1 主窗口设计3.2 QFormDoc类的设计3.3 QFormDoc类的使用3.…...

(力扣)用两个栈实现队列

这里是栈的源代码&#xff1a;栈和队列的实现 当然&#xff0c;自己也可以写一个栈来用&#xff0c;对题目来说不影响&#xff0c;只要符合栈的特点就行。 题目&#xff1a; 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;push、pop、pe…...

【自动化测试框架】关于unitttest你需要知道的事

一、UnitTest单元测试框架提供了那些功能 1.提供用例组织和执行 如何定义一条“测试用例”? 如何灵活地控制这些“测试用例”的执行? 2.提供丰定的断言方法 当测试用例的执行结果与预期结果不一致时&#xff0c;判定测试用例失败。在自动化测试中&#xff0c;通过“断言”…...

手机便签中可以打勾的圆圈或小方块怎么弄?

在日常的生活和工作中&#xff0c;很多网友除了使用手机便签来记录灵感想法、读书笔记、各种琐事、工作事项外&#xff0c;还会用它来记录一些清单&#xff0c;例如待办事项清单、读书清单、购物清单、旅行必备物品清单等。 在按照记录的清单内容来执行的时候&#xff0c;为了…...

【Linux】gdb 的使用

目录 1. 使用 gdb 的前置工作 2. 如何使用 gdb 进行调试 1、如何看到我的代码 2、如何打断点 3、怎么运行程序 4、如何进行逐过程调试 5、如何进行逐语句调试 6、如何监视变量值 7、如何跳到指定位置 8、运行完一个函数 9、怎么跳到下一个断点 10、如何禁用/开启…...

C++11之右值引用

C11之右值引用 传统的C语法中就有引用的语法&#xff0c;而C11中新增了的 右值引用&#xff08;rvalue reference&#xff09;语法特性&#xff0c;所以从现在开始我们之前学习的引用就叫做左值引用&#xff08;lvalue reference&#xff09;。无论左值引用还是右值引用&#…...

【PHP的设计模式】

PHP的设计模式 一、策略模式二、工厂模式三、单例模式四、注册模式五、适配器模式六、观察者模式 一、策略模式 策略模式是对象的行为模式&#xff0c;用意是对一组算法的封装。动态的选择需要的算法并使用。 策略模式指的是程序中涉及决策控制的一种模式。策略模式功能非常强…...

React 之 Redux - 状态管理

一、前言 1. 纯函数 函数式编程中有一个非常重要的概念叫纯函数&#xff0c;JavaScript符合函数式编程的范式&#xff0c;所以也有纯函数的概念 确定的输入&#xff0c;一定会产生确定的输出 函数在执行过程中&#xff0c;不能产生副作用 2. 副作用 表示在执行一个函数时&a…...

集合转数组

首先&#xff0c;我们在看到集合转数组的时候可能第一个想到的就是toArray(),但是我们在调用 toArray()的时候&#xff0c;可能会遇到异常 java.lang.ClassCastException&#xff1b;这是因为 toArray()方法返回的类型是 Obejct[]&#xff0c;如果我们将其转换成其他类型&#…...

使用Python将Word文档转换为PDF的方法

摘要&#xff1a; 文介绍了如何使用Python编程语言将Word文档转换为PDF格式的方法。我们将使用python-docx和pywin32库来实现这个功能&#xff0c;这些库提供了与Microsoft Word应用程序的交互能力。 正文&#xff1a; 在现实生活和工作中&#xff0c;我们可能会遇到将Word文…...

Java 判断一个字符串在另一个字符串中出现的次数

1.split实现 package com.jiayou.peis.official.account.biz.utils;public class Test {public static void main(String[] args) {String k"0110110100100010101111100101011001101110111111000101101001100010101" "011101100101011010100011111010111001001…...

设计模式十三:代理(Proxy Pattern)

代理模式是一种结构型设计模式&#xff0c;它允许通过在对象和其真实服务之间添加一个代理对象来控制对该对象的访问。代理对象充当了客户端和真实服务对象之间的中介&#xff0c;并提供了额外的功能&#xff0c;如远程访问、延迟加载、访问控制等。 代理模式的使用场景包括&a…...

Redis基础 (三十八)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、概述 1.1 NoSQL 1.2 Redis 二、安装 2.1 安装方式 &#xff1a; 三、目录结构 3.1 rpm -ql redis 3.2 /etc/redis.conf 主配置文件 3.3 /var/lib/redis …...

maven中的scope

1、compile&#xff1a;默认值&#xff0c;可省略不写。此值表示该依赖需要参与到项目的编译、测试以及运行周期中&#xff0c;打包时也要包含进去。 2、test&#xff1a;该依赖仅仅参与测试相关的工作&#xff0c;包括测试代码的编译和执行&#xff0c;不会被打包&#xff0c;…...

【网络基础实战之路】实现RIP协议与OSPF协议间路由交流的实战详解

系列文章传送门&#xff1a; 【网络基础实战之路】设计网络划分的实战详解 【网络基础实战之路】一文弄懂TCP的三次握手与四次断开 【网络基础实战之路】基于MGRE多点协议的实战详解 【网络基础实战之路】基于OSPF协议建立两个MGRE网络的实验详解 PS&#xff1a;本要求基于…...

CNN(四):ResNet与DenseNet结合--DPN

&#x1f368; 本文为&#x1f517;365天深度学习训练营中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊|接辅导、项目定制 前面实现了ResNet和DenseNet的算法&#xff0c;了解了它们有各自的特点&#xff1a; ResNet&#xff1a;通过建立前面层与后面层之间的“短路…...

汽车EBSE测试流程分析(四):反思证据及当前问题解决

EBSE专题连载共分为“五个”篇章。此文为该连载系列的“第四”篇章&#xff0c;在之前的“篇章&#xff08;三&#xff09;”中已经结合具体研究实践阐述了“步骤二&#xff0c;通过系统调研确定改进方案”等内容。那么&#xff0c;在本篇章&#xff08;四&#xff09;中&#…...

毕业设计h5网站制作/推广普通话

2019独角兽企业重金招聘Python工程师标准>>> 设置好共享文件夹之后&#xff0c;在/mnt下面建立了一个wwwroot文件夹&#xff0c;然后去欢天喜地的去挂载&#xff0c; mount -t vboxsf www /mnt/wwwroot 结果系统提示&#xff1a; mount: /mnt/wwwroot: wrong fs typ…...

柳州建站/关键词排名

1)您可以给出dagobah的尝试,如其github页面所述&#xff1a;Dagobah是一个简单的基于依赖关系的作业调度程序,用Python编写. Dagobah允许您使用Cron语法安排定期作业.然后,每个作业以依赖图定义的顺序启动一系列任务(子进程),您可以通过Web界面中的点击拖动轻松绘制.这是与以下…...

电子商城网站建设/郑州百度推广外包

Python Python开发 Python语言 python 列表中[ ]中冒号‘&#xff1a;’的作用python中括号[ ]&#xff1a;用于定义列表或引用列表、数组、字符串及元组中元素位置 list1 [physics, chemistry, 1997, 2000] list2 [1, 2, 3, 4, 5, 6, 7] print"list1[0]:", list1[0…...

php做简单网站教程视频教程/网络营销公司简介

JUnit5的测试不是通过名称&#xff0c;而是通过注解来标识的。 测试类与方法 Test Class&#xff1a;测试类&#xff0c;必须包含至少一个test方法&#xff0c;包括&#xff1a; 最外层的classstatic member classNested class Test Method&#xff1a;测试方法&#xff0c;包括…...

电器网站建设目的/专业的网站建设公司

简单介绍这是一个精美的主题&#xff0c;正如作者所说&#xff0c;“书写你的篇章”代码书写规范&#xff0c;具体&#xff0c;基础扎实。有良好的书写习惯&#xff0c;注释&#xff0c;布局都不错。主题功能与特点Material Design 风格19 种主色 & 16 种强调色黑暗模式&am…...

成都网络营销/深圳网站优化哪家好

遇到一个需求&#xff0c;要去重查出某张表的字段一和字段二&#xff0c;但是查出来的结果要按照表中记录的创建时间排序。 于是&#xff0c;第一时间就想到了使用distinct这个去重专用语法了&#xff1a; 1 select distinct col1, col2 from table1 order by create_date; 嗯&…...