转载于:http://blog.csdn.net/zhangpinghao/article/details/21046435

当为了提高CUDA程序的主机内存和设备内存传输消耗时,可以尝试一下两种方案

一:使用分页锁定内存,分页锁定内存和显存之间的拷贝速度大约是6GB/s,普通的分页内存和GPU间的速度大约是3GB/s,(另外:GPU内存间速度是30G,CPU间内存速度是10GB/s),但是这种方法会带来额外的cpu内存间的拷贝时间

二:使用内存映射(Zero Copy)让GPU直接使用CPU的内存,减少主机和设备间内存传输的时间,但是这种方法对于2.2以后的cuda版本未必管用

三:通过函数cudaHostRegister()把普通内存改为分页锁定内存,和一的方法类似,但不会带来额外的cpu内存拷贝时间,实验证明该方法有效果。

========================================================================================================

cuda运行时提供了使用分页锁定主机存储器(也称为pinned)的函数(与常规的使用malloc()分配的可分页的主机存储器不同):

cudaHostAlloc()和cudaFreeHost()分配和释放分页锁定主机存储器;
cudaHostRegister()分页锁定一段使用malloc()分配的存储器。
如前文(可阅读以上文章)提到的,在某些设备上,设备存储器和分页锁定主机存储器间数据拷贝可与内核执行并发进行;
  在一些设备上,分页锁定主机内存可映射到设备地址空间,减少了和设备间的数据拷贝,详见3.2.4.3节;
  在有前端总线的系统上,如果主机存储器是分页锁定的,主机存储器和设备存储器间的带宽会高些,如果再加上3.2.4.2节所描述的写结合(write-combining)的话,带宽会更高。

  然而分页锁定主机存储器是稀缺资源,所以可分页内存分配得多的话,分配会失败。另外由于减少了系统可分页的物理存储器数量,分配太多的分页锁定内存会降低系统的整体性能。 SDK中的simple zero-copy例子中有分页锁定API的详细文档

1、可分享存储器(portable memory)
  一块分页锁定存储器可被系统中的所有设备使用(参看前文以了解更多的多设备系统细节),但是默认的情况下,上面说的使用分布锁定存储器的好处只有分配它时,正在使用的设备可以享有(如果可能的话,所有的设备共享同一个地址空间,参见“相关阅读”中的文章)。为了让所有线程可以使用分布锁定共享存储器的好处,可以在使用cudaHostAlloc()分配时传入cudaHostAllocPortable标签,或者在使用cudaHostRegister()分布锁定存储器时,传入cudaHostRegisterPortable标签。
  2、写结合存储器
  默认情况下,分页锁定主机存储器是可缓存的。可以在使用cudaHostAlloc()分配时传入cudaHostAllocWriteCombined标签使其被分配为写结合的。写结合存储器没有一级和二级缓存资源,所以应用的其它部分就有更多的缓存可用。另外写结合存储器在通过PCI-e总线传输时不会被监视(snoop),这能够获得高达40%的传输加速。 从主机读取写结合存储器极其慢,所以写结合存储器应当只用于那些主机只写的存储器。
  3、被映射存储器
  在一些设备上,在使用cudaHostAlloc()分配时传入cudaHostAllocMapped标签或者在使用cudaHostRegister()分布锁定一块主机存储器时使用cudaHostRegisterMapped标签,可分配一块被映射到设备地址空间的分页锁定主机存储器。这块存储器有两个地址:一个在主机存储器上,一个在设备存储器上。主机指针是从cudaHostAlloc()或malloc()返回的,设备指针可通过cudaHostGetDevicePointer()函数检索到,可以使用这个设备指针在内核中访问这块存储器。唯一的例外是主机和设备使用统一地址空间时,参见前文(可阅读“相关阅读”的文章)。
        从内核中直接访问主机存储器有许多优点:
  ①无须在设备上分配存储器,也不用在这块存储器和主机存储器间显式传输数据;数据传输是在内核需要的时候隐式进行的。
  ②无须使用流(参见3.2.5.4节)重叠数据传输和内核执行;数据传输和内核执行自动重叠。
  由于被映射分页锁定存储器在主机和设备间共享,应用必须使用流或事件(参见3.2.5节)来同步存储器访问以避免任何潜在的读后写,写后读,或写后写危害。
  为了在给定的主机线程中能够检索到被映射分页锁定存储器的设备指针,必须在调用任何CUDA运行时函数前调用cudaSetDeviceFlags(),并传入cudaDeviceMapHost标签。否则,cudaHostGetDevicePointer()将会返回错误。
  一块分页锁定存储器可同时分配为被映射的和可分享的(前面的文章中提过),这种情况下,每个要映射这块存储器的主机线程必须调用cudaHostGetDevicePointer()检索设备指针,因为每个主机线程持有的设备指针一般不同。
  如果设备不支持被映射分页锁定存储器,cudaHostGetDevicePointer()将会返回错误。应用可以检查canMapHostMemory属性应用以查询这种能力,如果支持映射分页锁定主机存储器,将会返回1。 注意:从主机和其它设备的角度看,操作被映射分页锁定存储器的原子函数不是原子的

cuda中pinned memory(page-locked memory)相关推荐

  1. Cuda中Global memory中coalescing例程解释

    Global memory是cuda中最常见的存储类型,又叫做Device memory,位于Host主机区域上,它的生命周期是在整个Grid里面,大约具有500个cycle latency.在cud ...

  2. centos7 修改 max locked memory

    centos7 修改 max locked memory 环境: centos7.6, linux 内核 3.10 可以修改 /etc/security/limits.conf,2.6版本的内核默认是 ...

  3. pytorch在调用GPU的时候出现cuda runtime error (2) : out of memory at ..\aten\src\THC\THCGeneral.cpp:50

    这是因为GPU中的显存占满了,在任务管理器中关闭程序即可 @[TOC](pytorch在调用GPU的时候出现cuda runtime error (2) : out of memory at -\at ...

  4. 在计算机英语中memory,memory是什么 memory什么意思

    不知道亲爱的你们有没有听说过memory这个英文单词呢?你们知道它真正的意思是什么吗?如果你对这个英文单词也很感兴趣的话,下面我们一起来看看memory什么意思 memory是什么. memory什么 ...

  5. CUDA中grid、block、thread、warp与SM、SP的关系

    首先概括一下这几个概念.其中SM(Streaming Multiprocessor)和SP(streaming Processor)是硬件层次的,其中一个SM可以包含多个SP.thread是一个线程, ...

  6. java如何给一个链表定义和传值_如何在CUDA中为Transformer编写一个PyTorch自定义层...

    如今,深度学习模型处于持续的演进中,它们正变得庞大而复杂.研究者们通常通过组合现有的 TensorFlow 或 PyTorch 操作符来发现新的架构.然而,有时候,我们可能需要通过自定义的操作符来实现 ...

  7. [原]CUDA中grid、block、thread、warp与SM、SP的关系

    [原]CUDA中grid.block.thread.warp与SM.SP的关系 2015-3-27阅读209 评论0 首先概括一下这几个概念.其中SM(Streaming Multiprocessor ...

  8. CUDA中并行规约(Parallel Reduction)的优化

    Parallel Reduction是NVIDIA-CUDA自带的例子,也几乎是所有CUDA学习者的的必看算法.在这个算法的优化中,Mark Harris为我们实现了7种不同的优化版本,将Bandwi ...

  9. CUDA中SM对线程块的调度

    sm流处理器簇对blocks的调度策略 在cuda中,GPU中的SM(比如GTX650有两个SM处理器)被CPU调度器把线程块逐个分配到SM上,每个SM同时处理这个被分配的线程块,但是每次每个时刻只能 ...

  10. System memory,AGP memory和video memory

    在学习图形学.GPU编程的时候的时候,经常遇到这三种存储区,下面简要总结一下. system   memory  (main memory) : 就是电脑的内存条上的,一般都很大.显卡不能访问 . v ...

最新文章

  1. vim 成“神“之路 (一)
  2. Weex控制Android返回键解决方案
  3. (Linux 2.6设备管理机制)kobject和kset
  4. php查看表创建结构,MySQL 查看表结构简单命令
  5. vs 窗体连接mysql_vs2008 c#开发windows窗体程序,怎么连接数据库?
  6. 用java单源最短路径问题_单源最短路径-贪心算法
  7. android EditText光标位置,光标样式,EditText限制输入内容,软键盘遮挡的EditText,搜索框,限制输入表情
  8. python模拟http请求
  9. Java技术系列文章汇集(长期更新)
  10. Kotlin学习笔记20 阶段复习2
  11. 韩顺平 java笔记 第8讲 this 类变量 第9讲 类方法
  12. 淘淘商城第107讲——添加购物车
  13. 如何保持福禄克CFP2-100-Q、OFP2-100-Q等光纤测试仪器的洁净?
  14. 卸载steam 桌面图标消失异常
  15. LiteFlowNet3:解决对应歧义以获得更准确的光流估计
  16. win10光盘刻录linux镜像,解决win10系统刻录iso镜像系统光盘的技巧
  17. 细数SuperComputer最新排名和常见Benchmark类型
  18. Java的来源和基础语法
  19. Windows10 java JDK1.8安装及环境配置
  20. 【科普向】LaTeX简介(一篇极简的 LaTeX 介绍文章)

热门文章

  1. Unity3D 制作游戏简单“跑马灯”功能
  2. 单盘黑群晖更换硬盘实操记录
  3. Mysql 锁机制详解
  4. 怎么设计制作简洁实用的App交互界面
  5. CTF 实验吧 天网管理系统
  6. Java 给PDF文件添加水印
  7. Python 导出微信电子相册中的照片
  8. php 容器源码分析,Pimple运行流程浅析(PHP容器)
  9. D3D9利用顶点缓冲区绘制三角形
  10. Scanner类、Random类、ArrayList 类