《CUDA高性能并行计算》----3.4 简化操作流程

本文涉及的产品
数据传输服务 DTS,数据迁移 small 3个月
推荐场景:
MySQL数据库上云
数据传输服务 DTS,数据同步 small 3个月
推荐场景:
数据库上云
数据传输服务 DTS,数据同步 1个月
简介: 上面所述的标准操作流是主流的工作方式,然而其中的部分过于死板和烦琐,因此一些NVIDIA专家一起努力提供了一个可替代的流式方案,叫作统一内存(unified memory)。这个方法打破了主机内存和设备内存的围墙,因此你可以只用一个可以从主机端和设备端共同访问的数组(至少看起来是这样的)。

本 节 书 摘 来 自 华 章 出 版 社 《CUDA高性能并行计算》 一 书 中 的 第3章,第3.4节, 作 者 CUDA for Engineers: An Introduction to High-Performance Parallel Computing[美] 杜安·斯托尔蒂(Duane Storti)梅特·尤尔托卢(Mete Yurtoglu) 著,苏统华 项文成 李松泽 姚宇鹏 孙博文 译 , 更 多 章 节 内 容 可 以 访 问 云 栖 社 区 “华 章 计 算 机” 公 众 号 查 看。

3.4 简化操作流程

上面所述的标准操作流是主流的工作方式,然而其中的部分过于死板和烦琐,因此一些NVIDIA专家一起努力提供了一个可替代的流式方案,叫作统一内存(unified memory)。这个方法打破了主机内存和设备内存的围墙,因此你可以只用一个可以从主机端和设备端共同访问的数组(至少看起来是这样的)。

3.4.1 统一内存和托管数组

有一个好消息是统一内存把你从创建一个数组的不同拷贝(在主机和设备中)和显式的CPU和GPU间传输数据中解放出来。你可以建立一个设备和主机都能访问的托管数组来代替以前的工作。实际上,数组中的数据仍然需要在主机和设备间传输,但是CUDA系统会调度并执行这些操作,而不需要你去管理。注意托管内存数组会带来一个开发效率和执行效率的折衷。让系统去管理数据传输可能会简化并加速你的应用开发进程,但是自动管理的数据传输不能保证会像你手工管理得一样好。在开发过程中,你可能会发现编码的瓶颈在数据传输部分,这时决定进行显式的分配内存和传输数据是明智的。关于这个话题的更多内容我们会在后面详细讨论性能时提及,但现在我们只关心最基本的统一内存知识并实现一个托管内存版本的距离计算应用。
关于统一内存的一些重要事项:

统一内存对系统有特殊的要求。包括计算能力3.0以上的GPU和64位的Linux或者Windows系统[1](目前OS X系统不支持统一内存)。

另一个可能的巨大收益是对于那些喜欢面向对象C++编程的读者,统一内存更适合于处理传输结构数据并有助于避免深拷贝(deep copy)问题[2]。

目前统一内存访问还是从软件层面进行模拟,当GPU转成硬件层面实现时,托管数组的性能损耗可能会降低。

3.4.2 使用cudaMallocManaged()实现的距离应用

当我们并行化dist_v2来创建dist_v2_cuda时,我们遵循了主流的范式:创建一些额外的数组并显式地使用cudaMemcpy()函数在主机和设备间通过PCIe总线进行数据的输入和输出。

这里我们来看一下流式实现的细节。它可以使得一个数组在设备和主机上都能访问统一内存。CUDA的C语言拓展中最关键的部分是函数cudaMallocManaged(),我们将使用这个函数来为托管内存分配空间(在定义了指针以后,与cudaMalloc()函数使用方法类似)。

我们再次简化讨论的内容,直接浏览一个使用统一内存优化的距离应用的代码,代码参见代码清单3.7,其中有一些修改之处值得注意:

distanceArray()函数的代码量被大大减少了,因为我们不需要再分配内存并显式地进行数据传输,所有必须做的事情就是启动一个计算用的核函数(并且调用cudaDeviceSynchronize()保证在返回之前计算已经完成)。

只在一个地方创建了所有相关的数组。在main()函数中,定义in和out指针。

使用cudaMallocManaged()函数为数组分配统一内存,然后在计算完成后使用cudaFree()函数来释放内存。

为了简化介绍,我们选择将所有的代码放在一个文件中。这一次我们创建一个.cu文件,而不是像第1章中那样使用不包含CUDA语言拓展的只包含纯C代码的.cpp文件。

注意每个函数的修饰符:
scale()在CPU执行的for循环内调用,来生成输入数据。合适的修饰符是__host__但是我们可以不添加它,因为它是默认的标识符。

distance()函数将从核函数中调用并在GPU上执行,因此需要添加__device__标识。

distanceKernel()如所有的核函数一样,是从主机上调用而在设备上执行,因此需要使用修饰符__global__,并且设置返回类型是void


865a142a81a5c29faedead3d80e3708c0a39bc89


e2a9700dbb349a6d5c2598618619abd3fbc8e904

又到了需要编译并运行应用的时候,我们可以检查运算结果是否正确。(Linux下使用的Makefile文件参见代码清单3.2,也可以用来构建这个项目。)我们在第22行中包含一个printf()语句来在控制台上打印结果,你也可以通过debug工具来观察结果。

在Linux下,也可以使用cuda-gbd命令来观察托管数组中的值,就像观察任何一个变量的值一样(使用print out [0]@64)。

使用Windows下的Visual Studio,你可以在Locals窗口中看到,但是在那里只能查看一个值。你可以使用如下的步骤查看其他的值:

1.在第47行设置一个断点,正好处于释放内存之前。
2.开始调试(或按F5功能键)。
3.选择DEBUGQuickWatch(或按下Shift+F9组合键)。
4.当QuickWatch窗口打开时,输入out, 64。
5.点击名称旁边的三角形按钮来打开out数组中的成员列表。
关于CUDA专用的调试工具,请参见附录D。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
Sqoop 企业级大数据迁移方案实战
Sqoop是一个用于在Hadoop和关系数据库服务器之间传输数据的工具。它用于从关系数据库(如MySQL,Oracle)导入数据到Hadoop HDFS,并从Hadoop文件系统导出到关系数据库。 本课程主要讲解了Sqoop的设计思想及原理、部署安装及配置、详细具体的使用方法技巧与实操案例、企业级任务管理等。结合日常工作实践,培养解决实际问题的能力。本课程由黑马程序员提供。
相关文章
|
2月前
|
并行计算 算法 调度
自研分布式训练框架EPL问题之提高GPU利用率如何解决
自研分布式训练框架EPL问题之提高GPU利用率如何解决
|
机器学习/深度学习 存储 NoSQL
X-SIMD高性能跨平台向量化加速库
X-SIMD是平头哥基于开源SIMDe开发的一个header-only C程序库,提供了一种简单易用的跨平台SIMD程序优化方案,旨在为不支持SIMD指令集的平台提供SIMD支持。X-SIMD可以帮助开发者快速完成应用软件迁移arm平台,减少用户重新编写SIMD算法工作量。
|
并行计算 API
《并行计算的编程模型》一2.5.1 GASNet工具
本节书摘来华章计算机《并行计算的编程模型》一书中的第2章 ,第2.5.1节, [(美)帕万·巴拉吉(Pavan Balaji)编著;张云泉等译,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
995 0
|
并行计算
《并行计算的编程模型》一1.10 MPI开发心得
本节书摘来华章计算机《并行计算的编程模型》一书中的第1章 ,第1.10节, [(美)帕万·巴拉吉(Pavan Balaji)编著;张云泉等译,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
1880 0
|
并行计算
《并行计算的编程模型》一2.4.4 批量与单个
本节书摘来华章计算机《并行计算的编程模型》一书中的第2章 ,第2.4.4节, [(美)帕万·巴拉吉(Pavan Balaji)编著;张云泉等译,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
846 0
|
并行计算
《CUDA高性能并行计算》----3.3 标准操作流程
看过以上典型的程序流程,我们来分析一下流程哪些部分是CUDA带来的开销,哪些能带来收益。开销应该是十分明显的:创建镜像数组并且在设备端和主机端传输数据,这些都是在串行计算中不需要进行的额外工作。为了抵消这些内存操作的“额外开销”,我们能从GPU成百上千的处理器核心上得到运算上的收益。
1200 0
|
Web App开发 并行计算 异构计算
《CUDA高性能并行计算》----2.4 推荐项目
1.去CUDA Zone注册并加入到CUDA开发者中(如果读者还没有这样做的话)。 2.观看 www.nvidia.com/object/nvision08_gpu_v_cpu.html的视频,体会关于并行和串行执行的有趣的对比。
1856 0
|
并行计算
《CUDA高性能并行计算》----1.4 推荐项目
项目1~5是关于运行其他CUDA样例程序的练习。
1403 0
下一篇
无影云桌面