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

深度学习部署笔记(九): CUDA RunTime API-2.1内存管理

1. 前言

  1. 主要理解pinned memory、global memory、shared memory即可

2. 主机内存

  1. 主机内存很多名字: CPU内存,pinned内存,host memory,这些都是储存在内存条上的
  2. Pageable Memory(可分页内存) + Page lock Memory(页锁定内存) 共同组成内存
  3. 你可以理解为Page lock memory是vip房间,锁定给你一个人用。而Pageable memory是普通房间,在酒店房间不够的时候,选择性的把你的房间腾出来给其他人交换用,这就可以容纳更多人了。造成房间很多的假象,代价是性能降低

3. 页锁定内存 (pinned memory/Page lock Memory)

  1. pinned memory具有锁定性,是稳定不会被交换的
  2. pageable memory没有锁定特性,对于第三方设备(比如GPU),去访问时,因为无法感知内存是否被交换,可能得不到正确的数据(每次去房间找,说不准你的房间被人交换了)
  3. pageable memory的性能比pinned memory差,很可能降低你程序的优先级然后把内存交换给别人用
  4. pageable memory策略能使用内存假象,实际8GB但是可以使用15GB,提高程序运行数量(不是速度)
  5. pinned memory太多,会导致操作系统整体性能降低(程序运行数量减少),8GB就只能用8GB。注意不是你的应用程序性能降低,这一点一般都是废话,不用当回事
  6. GPU可以直接访问pinned memory而不能访问pageable memory(因为第二条)

4. 内存总结:

  1. GPU可以直接访问pinned memory,称之为(DMA Direct Memory Access)
  2. 对于GPU访问而言,距离计算单元越近,效率越高,所以PinnedMemory<GlobalMemory<SharedMemory
  3. 代码中,由new、malloc分配的,是pageable memory,由cudaMallocHost分配的是PinnedMemory,由cudaMalloc分配的是GlobalMemory
  4. 尽量多用PinnedMemory储存host数据,或者显式处理Host到Device时,用PinnedMemory做缓存,都是提高性能的关键

5. 案例代码

// CUDA运行时头文件
#include <cuda_runtime.h>#include <stdio.h>
#include <string.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;
}int main(){int device_id = 0;checkRuntime(cudaSetDevice(device_id));// 分配global memoryfloat *memory_device = nullptr;checkRuntime(cudaMalloc(&memory_device, 100 * sizeof(float))); // pointer to device// 分配pageable memoryfloat* memory_host = new float[100];memory_host[2] = 520.25;checkRuntime(cudaMemcpy(memory_device, memory_host, sizeof(float) * 100, cudaMemcpyHostToDevice)); // 返回的地址是开辟的device地址,存放在memory_device// 分配pinned memory page locked memoryfloat* memory_page_locked = nullptr;checkRuntime(cudaMallocHost(&memory_page_locked, 100 * sizeof(float))); // 返回的地址是被开辟的pin memory的地址,存放在memory_page_lockedcheckRuntime(cudaMemcpy(memory_page_locked, memory_device, sizeof(float) * 100, cudaMemcpyDeviceToHost)); // printf("%f\n", memory_page_locked[2]);checkRuntime(cudaFreeHost(memory_page_locked));delete [] memory_host;checkRuntime(cudaFree(memory_device)); return 0;
}

6. 案例代码分段解析

int device_id = 0;
cudaSetDevice(device_id); // 如果不写device_id = 0

是由于set device函数是“第一个执行的需要context的函数”,所以他会执行cuDevicePrimaryCtxRetain。

如果不指定设备ID,则默认使用设备ID为0的设备。在调用其他CUDA API函数之前,通常需要先调用cudaSetDevice来设置当前线程要使用的GPU设备。

float *memory_device = nullptr;
checkRuntime(cudaMalloc(&memory_device, 100 * sizeof(float))); // pointer to device

分配global memory需要使用cudaMalloc() 这里使用cudaMalloc()函数在GPU上分配一块100个float类型元素的内存,返回一个指向设备内存的指针memory_device。

// 分配pageable memory
float* memory_host = new float[100];
memory_host[2] = 520.25;
checkRuntime(cudaMemcpy(memory_device, memory_host, sizeof(float) * 100, cudaMemcpyHostToDevice)); // 返回的地址是开辟的device地址,存放在memory_device

分配pageable memory(主机上的内存), 使用new运算符在主机上分配一块100个float类型元素的内存,返回一个指向主机内存的指针memory_host。使用new运算符在主机上分配一块100个float类型元素的内存,返回一个指向主机内存的指针memory_host。

// 分配pinned memory page locked memory
float* memory_page_locked = nullptr;
checkRuntime(cudaMallocHost(&memory_page_locked, 100 * sizeof(float))); // 返回的地址是被开辟的pin memory的地址,存放在memory_page_locked
checkRuntime(cudaMemcpy(memory_page_locked, memory_device, sizeof(float) * 100, cudaMemcpyDeviceToHost)); 

分配pinned memory page locked memory使用cudaMallocHost()函数在主机上分配一块100个float类型元素的锁页内存(pinned memory),返回一个指向锁页内存的指针memory_page_locked。
将memory_device中的数据复制到memory_page_locked中,使用cudaMemcpy()函数,该函数将memory_device的数据从设备复制到主机的锁页内存。

printf("%f\n", memory_page_locked[2]);
checkRuntime(cudaFreeHost(memory_page_locked));
delete [] memory_host;
checkRuntime(cudaFree(memory_device)); 

输出memory_page_locked[2]的值,即设备内存的第三个元素的值(数组下标从0开始)。

使用cudaFreeHost()函数释放锁页内存。

使用delete[]运算符释放主机内存。

使用cudaFree()函数释放设备内存。

相关文章:

深度学习部署笔记(九): CUDA RunTime API-2.1内存管理

1. 前言 主要理解pinned memory、global memory、shared memory即可 2. 主机内存 主机内存很多名字: CPU内存&#xff0c;pinned内存&#xff0c;host memory&#xff0c;这些都是储存在内存条上的Pageable Memory(可分页内存) Page lock Memory(页锁定内存) 共同组成内存你…...

Idea+maven+spring-cloud项目搭建系列--11-2 dubbo鉴权日志记录数据统一封装

前言&#xff1a;使用dubbo做为通信组件&#xff0c;如果接口需要鉴权&#xff0c;和日志记录需要怎样处理&#xff1b; 1 鉴权&#xff1a; 1.1 在bootstrap.yml 中定义过滤器&#xff1a; dubbo.provider.filter: 过滤器的名字&#xff1a; 1.2 resources 目录下创建配置文…...

SOLIDWORKS免费培训 SW大型装配体模式课程

在SOLIDWORKS的使用过程中&#xff0c;大家经常会遇到大型装配体的处理问题&#xff0c;微辰三维的培训课程中也包含了一些大型装配体的技术培训&#xff0c;下面整理一些常见问题&#xff0c;供参考&#xff1a;大型装配体模式1.当我们打开一个大的装配体时&#xff0c;可能会…...

xxl-job registry fail

解决方法&#xff1a; 1、检查nacos是否正确&#xff0c;一定要注意格式&#xff0c;一般都是addersses的地址问题&#xff0c;一定的要加/不然找不到&#xff0c;本机就不要使用ip了&#xff0c;用localhost。 xxl: job: admin: addresses: http://localhost:8080/xxl-job-ad…...

【C#进阶】C# 反射

序号系列文章11【C#基础】C# 预处理器指令12【C#基础】C# 文件与IO13【C#进阶】C# 特性文章目录前言1&#xff0c;反射的概念2&#xff0c;使用反射访问特性3&#xff0c;反射的用途4&#xff0c;反射的优缺点比较4.1 优点&#xff1a;4.2 缺点&#xff1a;5&#xff0c;System…...

公网NAT网关与VPC NAT网关介绍与实践

NAT网关介绍 NAT网关是一种网络地址转换服务&#xff0c;提供NAT代理&#xff08;SNAT和DNAT&#xff09;能力。 公有云NAT分为公网NAT网关和VPC NAT网关。 1&#xff09;公网NAT网关&#xff1a;提供公网地址转换服务。 2&#xff09;VPC NAT网关&#xff1a;提供私网地址转换…...

Windows中UWP、WPF和Windows窗体的区别

Windows 中开发应用&#xff08;或者可以说客户端&#xff09;有三种方法&#xff1a; UWP&#xff08;Universal Windows Platform&#xff09;、WPF&#xff08;Windows Presentation Foundation&#xff09;和 Windows 窗体&#xff08;Win Forms&#xff09;。这三种方法在…...

Flink从入门到精通系列(一)

1、Flink概述 Apache Flink 是一个框架和分布式处理引擎&#xff0c;用于在&#xff0c; 无边界和有边界数据流上进行有状态的计算 &#xff0c;Flink 能在所有常见集群环境中运行&#xff0c;并能以内存速度和任意规模进行计算。 Apache Flink 功能强大&#xff0c;支持开发…...

云原生应用风险介绍

本博客地址&#xff1a;https://security.blog.csdn.net/article/details/129303616 一、传统风险 传统风险主要是注入、敏感数据泄露、跨站脚本、配置错误等等&#xff0c;这些传统的安全风险在云原生应用中也是存在的&#xff0c;这里就不具体展开说了。 二、云原生应用架…...

什么是测试用例设计?

前言 想要进行测试自动化的团队都会遇到这个问题&#xff1a;自动化的成功和编码能力有多大的关联&#xff1f;现在更多的招聘信息越来越偏重于对测试人员的编程能力的要求&#xff0c;似乎这个问题的答案是极大的正关联性。 测试人员可以将编码能力用于与测试相关的各种目的…...

数据分析:基于K-近邻(KNN)对Pima人糖尿病预测分析

数据分析&#xff1a;基于K-近邻(KNN)对Pima人糖尿病预测分析 作者&#xff1a;AOAIYI 作者简介&#xff1a;Python领域新星作者、多项比赛获奖者&#xff1a;AOAIYI首页 &#x1f60a;&#x1f60a;&#x1f60a;如果觉得文章不错或能帮助到你学习&#xff0c;可以点赞&#x…...

Kettle体系结构及源码解析

介绍 ETL是数据抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;、装载&#xff08;Load&#xff09;的过程。Kettle是一款国外开源的ETL工具&#xff0c;有两种脚本文件transformation和job&#xff0c;transformation完成针对数据的基础转换&…...

大数据 | (二)SSH连接报错Permission denied

大数据 | &#xff08;三&#xff09;centos7图形界面无法执行yum命令&#xff1a;centos7图形界面无法执行yum命令 哈喽&#xff01;各位CSDN的朋友们大家好&#xff01; 今天在执行Hadoop伪分布式安装时&#xff0c;遇到了一个问题&#xff0c;在此跟大家分享&#xff0c; …...

前端——6.文本格式化标签和<div>和<span>标签

这篇文章&#xff0c;我们来讲一下HTML中的文本格式化标签 目录 1.文本格式化标签 1.1介绍 1.2代码演示 1.3小拓展 2.div和span标签 2.1介绍 2.2代码演示 2.3解释 3.小结 1.文本格式化标签 在网页中&#xff0c;有时需要为文字设置粗体、斜体和下划线等效果&#xf…...

浅谈Xpath注入漏洞

目录 知识简介 攻击简介 基础语法 语法演示 漏洞简介 漏洞原理 漏洞复现 Xpath盲注 知识简介 攻击简介 XPath注入攻击是指利用XPath 解析器的松散输入和容错特性&#xff0c;能够在 URL、表单或其它信息上附带恶意的XPath 查询代码&#xff0c;以获得权限信息的访问权…...

Oracle LogMiner分析归档日志

目录&#xff1a;Oracle LogMiner分析归档日志一、准备测试环境1、开启数据库归档日志2、打开数据库最小附加日志3、设置当前session时间日期格式二、创建测试数据1、创建数据2、数据落盘三、日志发掘测试挖掘在上次归档的Redo Log File1.确定最近归档的Redo Log File2.指定要分…...

趣味三角——第15章——傅里叶定理

第15章 傅里叶定理(Fourier’s Theorem) Fourier, not being noble, could not enter the artillery, although he was a second Newton. (傅立叶出生并不高贵&#xff0c;因此按当时的惯例进不了炮兵部队&#xff0c;虽然他是第二个牛顿。) —Franois Jean Dominique Arag…...

市场营销的核心是什么?

之所以写下「市场营销的核心是什么&#xff1f;」这篇文章&#xff0c;是因为这几天刚读完了《经理人参阅&#xff1a;市场营销》这本书。作为一个有着近十年工作经验的市场营销从业人员&#xff0c;看完这本书也产生了很多新的想法&#xff0c;也想记录一下&#xff0c;遂成此…...

c/cpp - 多线程/进程 多进程

c/cpp - 多线程/进程 多进程多进程创建多进程进程等待多进程 宏观上 两个进程完全并发的 父子进程具有互相独立的进程空间 父进程结束&#xff0c;不影响子进程的执行 创建多进程 #include <sys/types.h> #include <unistd.h> #include <stdio.h>int main()…...

MySQL必知必会 | 存储过程、游标、触发器

使用存储过程 存储过程 简单来说就是为了以后的使用而保存的一条或多条MySQL语句的集合。 我觉得就是封装了一组sql语句 为什么需要存储过程&#xff08;简单来说就是&#xff0c;简单、安全、高性能 通过把处理封装在容易使用的单元中&#xff0c;简化复杂操作所有开发人员…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要&#xff1a; 近期&#xff0c;在使用较新版本的OpenSSH客户端连接老旧SSH服务器时&#xff0c;会遇到 "no matching key exchange method found"​, "n…...