2.4 DEVICE GLOBAL MEMORY AND DATA TRANSFER

在当前的CUDA系统中,设备通常是带有自己的动态随机存取存储器(DRAM)的硬件卡。例如,NVIDIA GTX1080具有高达8 GB的DRAM,称为全局内存。我们将互换使用全局内存和设备内存这两个术语。为了在设备上执行内核,程序员需要在设备上分配全局内存,并将相关数据从主机内存传输到分配的设备内存。这与图2.6第1部分相对应。同样,在设备执行后,程序员需要将结果数据从设备内存传输回主机内存,并释放不再需要的设备内存。这与图2.6.第3部分相对应。CUDA运行时系统提供API功能,以代表程序员执行这些活动。从现在开始,我们将简单地说一段数据从主机传输到设备,作为将数据从主机内存复制到设备内存的简写。相反的方向也是如此。

有一种趋势是将CPU和GPU的地址空间集成到统一的内存空间中(第20章)。有新的编程框架,如GMAC,可以利用统一的内存空间并消除数据复制成本。

在这里插入图片描述
图2.7显示了CUDA主机内存和设备内存模型的高级图片,供程序员推理设备内存的分配以及主机和设备之间的数据移动。主机可以访问设备全局内存,以在设备之间传输数据,如图2.7.中这些存储器与主机之间的双向箭头所示。设备内存类型比图2.7.中显示的要多。设备函数可以以只读方式访问常量内存,这将在第7章《并行模式:卷积》中描述。我们还将在第4章“内存和数据局部性”中讨论寄存器和共享内存的使用。感兴趣的读者还可以查看CUDA编程guide,了解纹理内存的功能。目前,我们将专注于全局内存的使用。

内置变量
许多编程语言都有内置变量。这些变量具有特殊的含义和目的。这些变量的值通常由运行时系统预先初始化,在程序中通常是只读的。程序员应避免将这些变量用于任何其他目的。

在图2.6中,vecAdd函数的第1部分和第3部分需要使用CUDA API函数为A、B和C分配设备内存,将A和B从主机内存传输到设备内存,在矢量添加结束时将C从设备内存传输到主机内存,并为A、B和C释放设备内存。我们将首先解释内存分配和自由函数。

图2.8显示了用于分配和释放设备全局内存的两个API功能。可以从主机代码调用cudaMalloc函数,为对象分配一块设备全局内存。读者应该注意到cudaMalloc和标准C运行时库malloc函数之间的惊人相似性。这是故意的;CUDA是最小扩展的C。CUDA使用标准C运行时库malloc函数来管理主机内存,并添加cudaMalloc作为C运行时库的扩展。通过使接口尽可能靠近原始C运行时库,CUDA最大限度地减少了C程序员重新学习使用这些扩展所花费的时间。

在这里插入图片描述
cudaMalloc函数的第一个参数是指针变量的地址,该变量将被设置为指向分配的对象。指针变量的地址应转换为(void **),因为该函数需要一个通用指针;内存分配函数是一个通用函数,不限于任何特定类型的对象。此参数允许cudaMalloc函数将分配内存的地址写入指针变量。启动内核的主机代码将此指针值传递给需要访问分配的内存对象的内核。cudaMalloc函数的第二个参数给出了要分配的数据大小,以字节数为单位。第二个参数的使用与C malloc函数的大小参数一致。

cudaMalloc返回一个通用对象的事实使动态分配的多维数组的使用更加复杂。我们将在第3.2节中解决这个问题。
请注意,cudaMalloc的格式与C malloc函数不同。C malloc函数返回一个指向分配对象的指针。它只需要一个参数来指定所分配对象的大小。cudaMalloc函数写入指针变量,其地址作为第一个参数。因此,cudaMalloc函数需要两个参数。cudaMalloc的双参数格式允许它以与其他CUDA API函数相同的方式使用返回值来报告任何错误。

我们现在使用一个简单的代码示例来说明cudaMalloc的使用。这是图2.6.中示例的延续。为了清楚起见,我们将用字母“d_”启动一个指针变量,以指示它指向设备内存中的对象。程序在将指针d_A(即&d_A)的地址传递给无效指针后作为第一个参数。也就是说,d_A将指向为A向量分配的设备内存区域。分配区域的大小将是单精度foating数的n倍,在今天的大多数计算机中为4字节。计算后,使用指针d_A作为输入调用cudaFree,以从设备全局内存中释放A向量的存储空间。请注意,cudaFree不需要更改指针变量d_A的内容;它只需使用d_A的值即可将分配的内存输入可用池。因此,只有值,而不是d_A的地址,作为参数传递。
在这里插入图片描述
d_A、d_B和d_C中的地址是设备内存中的地址。这些地址不应在计算的主机代码中取消引用。它们应该主要用于调用APl函数和内核函数。取消引用主机代码中的设备内存点可能会导致执行期间异常或其他类型的运行时错误。

读者应完成图2.6中vecAdd示例的第1部分具有d_B和d_C指针变量的类似声明以及相应的cuda-Malloc调用。此外,图2.6中的第3部分。可以通过d_B和d_C的cudaFree调用完成。

一旦主机代码为数据对象分配了设备内存,它就可以请求将数据从主机传输到设备。这是通过调用CUDA API函数之一来实现的。图2.9显示了这样的API函数,cudaMemcpy。cudaMemcpy函数需要四个参数。第一个参数是指向要复制的数据对象的目标位置的指针。第二个参数指向源位置。第三个参数指定要复制的字节数。第四个参数表示副本中涉及的内存类型:**从主机内存到主机内存,从主机内存到设备内存,从设备内存到主机内存,以及从设备内存到设备内存。**例如,内存复制功能可用于将数据从设备内存的一个位置复制到设备内存的另一个位置。

请注意,cudaMemcpy目前不能用于在多GPU系统中的不同GPU之间进行复制。

在这里插入图片描述
vecAdd函数调用cudaMemcpy函数,在添加h_A和h_B向量之前将h_A和h_B向量从主机复制到设备,并在添加完成后将h_C向量从设备复制到主机。假设h_A、h_B、d_A、d_B和size的值已经像我们之前讨论的那样设置好了,三个cudaMemcpy调用如下所示。两个符号常量,cudaMemcpyHostToDevice和cudaMemcpyDeviceToHost,是CUDA编程环境的可识别预定义常数请注意,通过正确排序源指针和目标指针并使用传输类型的适当常量,可以使用相同的功能双向传输数据。
在这里插入图片描述
总而言之,图2.5中的主要程序调用vecAdd,它也在主机上执行。vecAdd函数,如图2.6所示,分配设备内存,请求数据传输,并启动执行实际向量加法的内核。**我们经常将这种类型的主机代码称为启动内核的 stub function **。内核完成执行后,vecAdd还会将结果数据从设备复制到主机。我们在图2.10中展示了vecAdd函数的更完整版本。
在这里插入图片描述

CUDA中的错误检查和处理
一般来说,程序检查和处理错误非常重要。
CUDA API函数返回标志,指示它们在处理请求时是否发生了错误。大多数错误是由于调用中使用的参数值不恰当。
为了简洁,我们不会在示例中显示错误检查代码。例如,图。2.10显示了对cudaMalloc的呼叫:
cudaMalloc((void **) &d_A, size);
在实践中,我们应该用测试错误条件的代码包围呼叫,并打印出错误消息,以便用户能够意识到发生错误的事实。此类检查代码的简单版本如下:
cudaError_t err=cudaMalloc((void **) &d_A, size);
if (error !=cudaSuccess) {
printf(“%s in %s at line %d\n”, cudaGetErrorString(err),__
FILE__,LINE);
exit(EXIT_FAILURE);
}
这样,如果系统没有设备内存,用户将被告知情况。这可以节省许多小时的调试时间。
可以定义一个C宏,使检查代码在源代码中更加简洁。

与图2.6相比,图2.10中的vecAdd函数第1部分和第3部分完成。第1部分为d_A、d_B和d_C分配设备内存,并将h_A传输到d_A,h_B传输到d_B。这是通过调用cudaMalloc和cudaMemcpy函数来完成的。鼓励读者使用适当的参数值编写自己的函数调用,并将他们的代码与图中显示的代码进行比较。2.10.第2部分调用内核,并将在后续小节中描述。第3部分将总和数据从设备内存复制到主机内存,以便其值在主函数中可用。这是通过调用cudaMemcpy函数来完成的。然后,它从设备内存中释放d_A、d_B和d_C的内存,这是通过调用cudaFree函数完成的。

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

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

相关文章

西电期末1032.模式匹配

一.题目 二.分析与思路 遍历判断 三.代码实现 #include<bits/stdc.h>//万能头 int main() {int n;scanf("%d",&n);int num[n];for(int i0;i<n;i){scanf("%d",&num[i]);}int ans0;//个数for(int i0;i<n-2;i){if(num[i]3&&nu…

【Docker】数据卷容器

多个容器进行数据交换 这里引入一个数据卷容器的概念 以下介绍容器A与容器B进行数据交换的原理 假如容器A要与容器 B 进行数据交换&#xff0c; 首先创建一个容器C&#xff0c;将他挂载到数据卷&#xff0c;然后再将容器A与容器B挂载到容器C&#xff0c;这样做相当于容器A与…

【EAI 006】ChatGPT for Robotics:将 ChatGPT 应用于机器人任务的提示词工程研究

论文标题&#xff1a;ChatGPT for Robotics: Design Principles and Model Abilities 论文作者&#xff1a;Sai Vemprala, Rogerio Bonatti, Arthur Bucker, Ashish Kapoor 作者单位&#xff1a;Scaled Foundations, Microsoft Autonomous Systems and Robotics Research 论文原…

YOLOv5改进 | 注意力篇 | ACmix注意力与卷积混合的模型(轻量化注意力机制)

一、本文介绍 本文给大家带来的改进机制是ACmix自注意力机制的改进版本,它的核心思想是,传统卷积操作和自注意力模块的大部分计算都可以通过1x1的卷积来实现。ACmix首先使用1x1卷积对输入特征图进行投影,生成一组中间特征,然后根据不同的范式,即自注意力和卷积方式,分别…

使用 MONAI 加载和保存各种格式的医学图像

本教程属于实战&#xff0c;手把手教你加载各种医学图像数据&#xff08;nii.gz, .dcm, .png等&#xff09;。并学会查看医学图像数据的元数据&#xff08;shape, affine, orientation&#xff09;。学会使用monai全方位了解你的数据&#xff0c;并把它用于之后的深度学习训练。…

Leetcod面试经典150题刷题记录 —— 链表篇

Leetcod面试经典150题刷题记录-系列Leetcod面试经典150题刷题记录——数组 / 字符串篇Leetcod面试经典150题刷题记录 —— 双指针篇Leetcod面试经典150题刷题记录 —— 矩阵篇Leetcod面试经典150题刷题记录 —— 滑动窗口篇Leetcod面试经典150题刷题记录 —— 哈希表篇Leetcod面…

pytorch安装

pytoch安装 1. 准备工作1.1 需要提前安装的软件 2. 安装pyTorch我遇到的问题 3. 显卡测试4. CPU与GPU切换方法4.1 创建张量4.2 第一种切换方法4.3 第二种切换方法 1. 准备工作 1.1 需要提前安装的软件 Anaconda 史上最全最详细的Anaconda安装教程CUDA CUDA安装教程&#xff0…

让充电器秒供多个快充口,乐得瑞推出1拖2功率分配快充线方案

随着PD3.1协议的市场应用越来越多&#xff0c;一些充电器的Type-C接口的输出功率达到百瓦及以上&#xff0c;如何充分利用好这类充电器设备&#xff0c;乐得瑞电子推出1拖2快充线缆解决方案&#xff0c;支持智能功率分配策略支持私有快充协议。 如上图是乐得瑞1拖2功率分配快充…

WWDG---窗口看门狗

一.简介 窗口看门狗跟独立看门狗一样&#xff0c;也是一个递减计数器不断的往下递减计数&#xff0c;必须在一个窗口的上限值&#xff08;用户定义&#xff09;和下限值&#xff08;0X40&#xff0c;固定不能变&#xff09;之间喂狗不会复位&#xff0c;在上限值之前和下限值之…

Flink自定义Source模拟数据流

maven依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.…

OpenCV | 光流估计

光流估计 光流是空间运动物体在观测成像平面上的像素运动的“瞬时速度”&#xff0c;根据各个像素点的速度的速度矢量特征&#xff0c;可以对图像进行动态分析&#xff0c;例如目标跟踪 高度恒定&#xff1a;同一点随着时间的变化&#xff0c;其亮度不会发生改变。小运动&…

ProtoBuf一些踩坑记录

一、Protobuf学习基础 学习的资料很多也很全&#xff0c;这里添加几个链接进行Protobuf的基础学习的链接&#xff0c;链接中的案例使用C编辑&#xff1a; 链接&#xff1a;Protobuf介绍及简单使用(上&#xff09;_google_protobuf_version-CSDN博客 Protobuf介绍及简单使用(下&…

MFC综合实验二学习记录

文章目录 如何确定消息映射宏中命令对应的菜单项资源虚函数和纯虚函数的区别&#xff1f;MFC中什么是UPDATE_COMMAND_UI 消息如何查看控件对应的成员变量模态对话框的理解HGDIOBJ" 类型的值不能用于初始化 "CBrush *" 类型的实体错误MFC编程中CDC类型和HDC类型有…

TOP 9 安卓手机系统和应用程序修复工具,可修复各种Android 系统问题

您的新 Android 手机可能因其令人兴奋的性能而印象深刻。然而&#xff0c;随着时间的推移&#xff0c;您可能会发现系统有些地方与以前不太一样。您可能会遇到屏幕无响应、 Android应用程序崩溃、连接问题、电池耗尽等现象。 好吧&#xff0c;在这些情况下您不必感到不安&…

centos通过yum安装redis

1. 安装yum添加epel源(此步根据环境&#xff0c;如果有源则可跳过&#xff0c;在阿里去可跳过&#xff09; yum install epel-release 2 使用yum安装Redis yum install redis 出现如下图所示的内容&#xff0c;默认的安装路径是在 /usr/bin目录下&#xff1a; 文件安装路径…

uniapp 微信小程序跳转至其他小程序

一、背景&#xff1a; 需要在目前的小程序中跳转到另一个小程序&#xff0c;跳转的目标小程序需要已经发布上线了 二、具体实现 使用uni.navigateToMiniProgram打开另一个小程序 官网指引&#x1f449;&#xff1a;uni.navigateToMiniProgram(OBJECT) | uni-app官网 <t…

iview 选择框远程搜索 指定筛选的参数

问题&#xff1a;开启了filterable之后&#xff0c;选择框是允许键盘输入的&#xff0c;但是会对选择列表进行过滤&#xff0c;如果不想使用再次过滤&#xff0c;可以试下下面这个方法。 场景&#xff1a;输入加密前的关键字筛选&#xff0c;选择框显示加密后的数据 说明一&a…

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK实现相机的高速图像保存(C++)

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK实现相机的高速图像保存&#xff08;C&#xff09;&#xff09; Baumer工业相机Baumer工业相机的图像高速保存的技术背景Baumer工业相机通过NEOAPI SDK函数图像高速保存在NEOAPI SDK里实现线程高速图像保存&#xff1a;工业相机高…

rke2 offline install kubernetes v1.26

文章目录 1. 准备2. 安装 ansible3. 基础配置3.1 配置 hosts3.2 安装软件包3.3 内核参数3.4 连接数限制3.5 关闭swap 、selinux、防火墙3.6 时间同步 4. RKE2 安装4.1 下载安装4.2 配置其他管理节点4.3 新增 worker 节点 1. 准备 7 台主机 主机名ipcpu内存diskos角色user密码…

11.3编写Linux串口驱动

编写串口驱动主要步骤 构建并初始化 struct console 对象&#xff0c;若串口无需支持 console 可省略此步骤 //UART驱动的console static struct uart_driver virt_uart_drv; static struct console virt_uart_console {//console 的名称&#xff0c;配合index字段使用&…