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

深度学习部署(十六): CUDA RunTime API _vector-add 使用cuda核函数实现向量加法

1. 知识点

  1. nthreads的取值,不能大于block能取值的最大值。一般可以直接给512、256,性能就是比较不错的
    • (input_size + block_size - 1) / block_size;是向上取整
  2. 对于一维数组时,采用只定义layout的x维度,若处理的是二维,则可以考虑定义x、y维度,例如处理的是图像
  3. 关于把数据视作一维时,索引的计算
    • 以下是通用的计算公式
    Pseudo code:
    position = 0
    for i in range(6):position *= dims[i]position += indexs[i]
    
    • 例如当只使用x维度时,实际上dims = [1, 1, gd, 1, 1, bd],indexs = [0, 0, bi, 0, 0, ti]
      • 因为0和1的存在,上面的循环则可以简化为:idx = threadIdx.x + blockIdx.x * blockDim.x
      • 即:idx = ti + bi * bd

2. main.cpp文件

#include <cuda_runtime.h>
#include <stdio.h>#define checkRuntime(op)  __check_cuda_runtime((op), #op, __FILE__, __LINE__)bool __check_cuda_runtime(cudaError_t code, const char* op, const char* file, int line){if(code != cudaSuccess){    const char* err_name = cudaGetErrorName(code);    const char* err_message = cudaGetErrorString(code);  printf("runtime error %s:%d  %s failed. \n  code = %s, message = %s\n", file, line, op, err_name, err_message);   return false;}return true;
}void vector_add(const float* a, const float* b, float* c, int ndata);int main(){const int size = 3;float vector_a[size] = {2, 3, 2};float vector_b[size] = {5, 3, 3};float vector_c[size] = {0};float* vector_a_device = nullptr;float* vector_b_device = nullptr;float* vector_c_device = nullptr;checkRuntime(cudaMalloc(&vector_a_device, size * sizeof(float)));checkRuntime(cudaMalloc(&vector_b_device, size * sizeof(float)));checkRuntime(cudaMalloc(&vector_c_device, size * sizeof(float)));checkRuntime(cudaMemcpy(vector_a_device, vector_a, size * sizeof(float), cudaMemcpyHostToDevice));checkRuntime(cudaMemcpy(vector_b_device, vector_b, size * sizeof(float), cudaMemcpyHostToDevice));vector_add(vector_a_device, vector_b_device, vector_c_device, size);checkRuntime(cudaMemcpy(vector_c, vector_c_device, size * sizeof(float), cudaMemcpyDeviceToHost));for(int i = 0; i < size; ++i){printf("vector_c[%d] = %f\n", i, vector_c[i]);}checkRuntime(cudaFree(vector_a_device));checkRuntime(cudaFree(vector_b_device));checkRuntime(cudaFree(vector_c_device));return 0;
}

先定义三个数组: a, b, c 再用cudaMalloc()在GPU上开辟三个内存,在GPU上让a + b 并且让结果存储进c上,再把c的内存从GPU上放到Host上输出

3. 案例.cu文件

#include <stdio.h>
#include <cuda_runtime.h>__global__ void vector_add_kernel(const float* a, const float* b, float* c, int ndata){int idx = threadIdx.x + blockIdx.x * blockDim.x;if(idx >= ndata) return;/*    dims                 indexsgridDim.z            blockIdx.zgridDim.y            blockIdx.ygridDim.x            blockIdx.xblockDim.z           threadIdx.zblockDim.y           threadIdx.yblockDim.x           threadIdx.xPseudo code:position = 0for i in 6:position *= dims[i]position += indexs[i]*/c[idx] = a[idx] + b[idx];
}void vector_add(const float* a, const float* b, float* c, int ndata){const int nthreads = 512;int block_size = ndata < nthreads ? ndata : nthreads;  // 如果ndata < nthreads 那block_size = ndata就够了int grid_size = (ndata + block_size - 1) / block_size; // 其含义是我需要多少个blocks可以处理完所有的任务printf("block_size = %d, grid_size = %d\n", block_size, grid_size);vector_add_kernel<<<grid_size, block_size, 0, nullptr>>>(a, b, c, ndata);// 在核函数执行结束后,通过cudaPeekAtLastError获取得到的代码,来知道是否出现错误// cudaPeekAtLastError和cudaGetLastError都可以获取得到错误代码// cudaGetLastError是获取错误代码并清除掉,也就是再一次执行cudaGetLastError获取的会是success// 而cudaPeekAtLastError是获取当前错误,但是再一次执行cudaPeekAtLastError或者cudaGetLastErro拿到的还是那个错cudaError_t code = cudaPeekAtLastError();if(code != cudaSuccess){    const char* err_name    = cudaGetErrorName(code);    const char* err_message = cudaGetErrorString(code);  printf("kernel error %s:%d  test_print_kernel failed. \n  code = %s, message = %s\n", __FILE__, __LINE__, err_name, err_message);   }
}

两个注意的点

  1. 像这个案例他就三个数相加,其实启动三个线程就足够了,但是一般block给的是512, 256,所以要设定一下,如果数组的长度小于256/512, 就直接用数组的长度的线程数就好。这里就是3个线程

  2. 如果线程索引大于了数组的长度就直接返回了,不然就访问了不知道在哪里的内存了

相关文章:

深度学习部署(十六): CUDA RunTime API _vector-add 使用cuda核函数实现向量加法

1. 知识点 nthreads的取值&#xff0c;不能大于block能取值的最大值。一般可以直接给512、256&#xff0c;性能就是比较不错的 (input_size block_size - 1) / block_size;是向上取整 对于一维数组时&#xff0c;采用只定义layout的x维度&#xff0c;若处理的是二维&#xff…...

堆结构的两个应用

堆排序 堆结构很大的一个用处&#xff0c;就是用于堆排序了&#xff0c;堆排序的时间复杂度是O(n∗log2n)O(n*log_2n)O(n∗log2​n)量级的&#xff0c;在众多排序算法中所处的地位也是高手级别的了。 但很多人在使用堆排序的时候&#xff0c;首先认为我必须得有一个堆数据结构…...

Java中的 static

1 static 静态变量 1.1 静态变量的使用 static变量也称作静态变量&#xff0c;也叫做类变量 静态变量被所有的对象所共享&#xff0c;在内存中只有一个副本 当且仅当在类初次加载时会被初始化 静态变量属于类 通过类名就可以直接调用静态变量 也可以通过对象名.静态变量…...

基于Vision Transformer的图像去雾算法研究与实现(附源码)

基于Vision Transformer的图像去雾算法研究与实现 0. 服务器性能简单监控 \LOG_USE_CPU_MEMORY\文件夹下的use_memory.py文件可以实时输出CPU使用率以及内存使用率&#xff0c;配合nvidia-smi监控GPU使用率 可以了解服务器性能是否足够&#xff1b;运行时在哪一步使用率突然…...

服务器相关常用的命令

cshell语法 https://www.doc88.com/p-4985161471426.html domainname命令 1&#xff09;查看当前系统域名 domainname2&#xff09;设置并查看当前系统域名 domainname example.com3&#xff09;显示主机ip地址 domainname -Iwhich命令 which 系统命令在 PATH 变量指定的…...

今天是国际数学日,既是爱因斯坦的生日又是霍金的忌日

目录 一、库函数计算 π 二、近似值计算 π 三、无穷级数计算 π 四、割圆术计算 π 五、蒙特卡罗法计算 π 六、计算800位精确值 从2020年开始&#xff0c;每年的3月14日又被定​为国际数学日​&#xff0c;是2019年11月26日​联合国教科文组织​第四十届大会上正式宣布…...

Qt Quick - StackLayout 堆布局

StackLayout 堆布局一、概述二、attached 属性三、例子1. 按钮切换 StackLayout 页面一、概述 StackLayout 其实就是说&#xff0c;在同一个时刻里面&#xff0c;只有一个页面是展示出来的&#xff0c;类似QStackWidget 的功能&#xff0c;主要就是切换界面的功能。这个类型我…...

C/C++网络编程笔记Socket

https://www.bilibili.com/video/BV11Z4y157RY/?vd_sourced0030c72c95e04a14c5614c1c0e6159b上面链接是B站的博主教程&#xff0c;源代码来自上面视频&#xff0c;侵删&#xff0c;这里只是做笔记&#xff0c;以供复习和分享。上一篇博客我记录了配置环境并且跑通了&#xff0…...

RK3568平台开发系列讲解(网络篇)什么是Socket套接字

🚀返回专栏总目录 文章目录 一、什么是socket ?二、socket 理解为电话机三、socket 的发展历史四、套接字地址格式4.1、通用套接字地址格式4.2、IPv4 套接字格式地址4.3、IPv6 套接字地址格式4.4、几种套接字地址格式比较沉淀、分享、成长,让自己和他人都能有所收获!😄 …...

2022年全国职业院校技能大赛(中职组)网络安全竞赛试题——渗透测试解析(详细)

渗透测试 任务环境说明: 服务器场景:Server9服务器场景操作系统:未知(关闭连接)系统用户名:administrator密码:123456通过本地PC中渗透测试平台Kali对靶机场景进行系统服务及版本扫描渗透测试,以xml格式向指定文件输出信息(使用工具Nmap),将以xml格式向指定文件输出…...

尚融宝03-mybatis-plus基本CRUD和常用注解

目录 一、通用Mapper 1、Create 2、Retrieve 3、Update 4、Delete 二、通用Service 1、创建Service接口 2、创建Service实现类 3、创建测试类 4、测试记录数 5、测试批量插入 三、自定义Mapper 1、接口方法定义 2、创建xml文件 3、测试条件查询 四、自定义Serv…...

vue多行显示文字展开

这几天项目里面有一个需求&#xff0c;多行需要进行展开文字&#xff0c;类似实现这种效果 难点就在于页面布局 一开始就跟无头苍蝇似的&#xff0c;到处百度 &#xff0c;后面发现网上的都不适合自己&#xff0c;最终想到了解决方案 下面是思路&#xff1a; 需求是超过3行&a…...

SpringBoot:SpringBoot 的底层运行原理解析

声明原文出处&#xff1a;狂神说 文章目录1. pom.xml1 . 父依赖2 . 启动器 spring-boot-starter2. 主启动类的注解1. 默认的主启动类2. SpringBootApplication3. ComponentScan4. SpringBootConfiguration5. SpringBootApplication 注解6. spring.factories7. 结论8. 简单图解3…...

哪些场景会产生OOM?怎么解决?

文章目录 堆内存溢出方法区(运行时常量池)和元空间溢出直接内存溢出栈内存溢出什么时候会抛出OutOfMemery异常呢?初看好像挺简单的,其实深究起来考察的是对整个JVM的了解,而这个问题从网上可以翻到一些乱七八糟的答案,其实在总结下来基本上4个场景可以概括下来。 堆内存溢出…...

金三银四、金九银十 面试宝典 Spring、MyBatis、SpringMVC面试题 超级无敌全的面试题汇总(超万字的面试题,让你的SSM框架无可挑剔)

Spring、MyBatis、SpringMVC 框架 - 面试宝典 又到了 金三银四、金九银十 的时候了&#xff0c;是时候收藏一波面试题了&#xff0c;面试题可以不学&#xff0c;但不能没有&#xff01;&#x1f941;&#x1f941;&#x1f941; 一个合格的 计算机打工人 &#xff0c;收藏夹里…...

JAVA开发(Spring框架详解)

javaweb项目几乎已经离不开spring框架了&#xff0c;spring 是一个典型的分层架构框架&#xff0c;它包含一系列的功能并被分为多个功能模块&#xff0c;springboot对spring框架又做了一层封装&#xff0c;以至于很多人对原来的spring框架越来越不了解。 要谈Spring的历史&…...

自学大数据第八天~HDFS命令(二)

嗨喽,好久不见,最近抽空复习了一下hadoop,书读百遍,其意自现这句话还真是; 继续学习HDFS常用命令 改变文件 拥有者~chown hdfs dfs -chown -R hadoop /user/hadoop使用 -R 将使改变在目录结构下递归进行。命令的使用者必须是超级用户。 改变文件所属组-chgrp hdfs dfs -chgr…...

贪心算法(几种常规样例)

贪心算法&#xff08;几种常规样例&#xff09; 贪心算法&#xff0c;指在对问题进行求解的时候&#xff0c;总是做出当前看来是最好的选择。也就是说不从整体上最优上考虑&#xff0c;算法得到的结果是某种意义上的局部最优解 文章目录贪心算法&#xff08;几种常规样例&…...

【数据结构】基础知识总结

系列综述&#xff1a; &#x1f49e;目的&#xff1a;本系列是个人整理为了数据结构复习用的&#xff0c;由于牛客刷题发现数据结构方面和王道数据结构的题目非常像&#xff0c;甚至很多都是王道中的&#xff0c;所以将基础知识进行了整理&#xff0c;后续会将牛客刷题的错题一…...

宣布推出 .NET 社区工具包 8.1!

我们很高兴地宣布 .NET Community Toolkit 8.1 版正式发布&#xff01;这个新版本包括呼声很高的新功能、bug 修复和对 MVVM 工具包源代码生成器的大量性能改进&#xff0c;使开发人员在使用它们时的用户体验比以往更好&#xff01; 就像在我们之前的版本中一样&#xff0c;我…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

SpringCloudGateway 自定义局部过滤器

场景&#xff1a; 将所有请求转化为同一路径请求&#xff08;方便穿网配置&#xff09;在请求头内标识原来路径&#xff0c;然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计

随着大语言模型&#xff08;LLM&#xff09;参数规模的增长&#xff0c;推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长&#xff0c;而KV缓存的内存消耗可能高达数十GB&#xff08;例如Llama2-7B处理100K token时需50GB内存&a…...

Caliper 配置文件解析:fisco-bcos.json

config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...

解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist

现象&#xff1a; android studio报错&#xff1a; [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决&#xff1a; 不要动CMakeLists.…...

【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验

Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...

DAY 26 函数专题1

函数定义与参数知识点回顾&#xff1a;1. 函数的定义2. 变量作用域&#xff1a;局部变量和全局变量3. 函数的参数类型&#xff1a;位置参数、默认参数、不定参数4. 传递参数的手段&#xff1a;关键词参数5 题目1&#xff1a;计算圆的面积 任务&#xff1a; 编写一…...