热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

梳理caffe代码syncedmem(二)

梳理caffe代码syncedmem(二)接着最重要的就是内存分配和Caffe的底层数据的切换(cpu模式和gpu模式),需要用到内存同步模块。这类个类的代码比较少,但是作用是非常

梳理caffe代码syncedmem(二)

接着最重要的就是内存分配和Caffe的底层数据的切换(cpu模式和gpu模式),需要用到内存同步模块。这类个类的代码比较少,但是作用是非常明显的。文件对应着syncedmem.hpp,着syncedmem.cpp首先是两个全局的内联函数。如果机器是支持GPU的并且安装了cuda,通过cudaMallocHost分配的host memory将会被pinned,pinned的意思就是内存不会被paged out,我们知道内存里面是由页作为基本的管理单元。分配的内存可以常驻在内存空间中对效率是有帮助的,空间不会被别的进程所抢占。同样如果内存越大,能被分配的Pinned内存自然也越大。还有一点是,对于单一的GPU而言提升并不会太显著,但是对于多个GPU的并行而言可以显著提高稳定性。这里是两个封装过的函数,内部通过cuda来分配主机和释放内存的接口.

 

[cpp] view plain copy
 
 梳理caffe代码syncedmem(二)梳理caffe代码syncedmem(二)
  1. #ifndef CAFFE_SYNCEDMEM_HPP_  
  2. #define CAFFE_SYNCEDMEM_HPP_  
  3.   
  4. #include   
  5.   
  6. #include "caffe/common.hpp"  
  7. #include "caffe/util/math_functions.hpp"  
  8.   
  9. namespace caffe {  
  10.   
  11. // Theoretically, CaffeMallocHost and CaffeFreeHost should simply call the  
  12. // cudaMallocHost and cudaFree functions in order to create pinned memory.  
  13. // However, those codes rely on the existence of a cuda GPU (I don't know  
  14. // why that is a must since allocating memory should not be accessing the  
  15. // GPU resource, but it just creates an error as of Cuda 5.0) and will cause  
  16. // problem when running on a machine without GPU. Thus, we simply define  
  17. // these two functions for safety and possible future change if the problem  
  18. // of calling cuda functions disappears in a future version.  
  19. //  
  20. // In practice, although we are creating unpinned memory here, as long as we  
  21. // are constantly accessing them the memory pages almost always stays in  
  22. // the physical memory (assuming we have large enough memory installed), and  
  23. // does not seem to create a memory bottleneck here.  
  24. //分别是分配和释放内存,这里指的是CPU内存。  
  25. inline void CaffeMallocHost(void** ptr, size_t size) {  
  26.   *ptr = malloc(size);  
  27.   CHECK(*ptr) << "host allocation of size " << size << " failed";  
  28. }  
  29.   
  30. inline void CaffeFreeHost(void* ptr) {  
  31.   free(ptr);  
  32. }  
  33.   
  34.   
  35. /** 
  36.  * @brief Manages memory allocation and synchronization between the host (CPU) 
  37.  *        and device (GPU). 
  38.  * 
  39.  * TODO(dox): more thorough description. 
  40.  */  
  41. //功能:Caffe的底层数据的切换(cpu模式和gpu模式),需要用到内存同步模块。  
  42. class SyncedMemory {  
  43.  public:  
  44. /* 
  45. 第一个为简单初始化,第二个只是把 size (大小)设置了,并未申请内存。 
  46. 然后是析构函数,主要就是释放数据。own_gpu_data和own_cpu_data这两个成员变量 
  47. 的作用表示是否拥有该数据,也即在cpu或gpu中是否 
  48. 有其他指针指向该数据。 
  49. */  
  50.   SyncedMemory()  
  51.       : cpu_ptr_(NULL), gpu_ptr_(NULL), size_(0), head_(UNINITIALIZED),  
  52.         own_cpu_data_(false) {}  
  53.   explicit SyncedMemory(size_t size)  
  54.       : cpu_ptr_(NULL), gpu_ptr_(NULL), size_(size), head_(UNINITIALIZED),  
  55.         own_cpu_data_(false) {}  
  56.   ~SyncedMemory();  
  57. /* 
  58. 分别是获取cpu,gpu中数据的指针,需要说明的一点是,该过程会同步数据。 
  59. 有获取,就有设置,下面两个函数就是设置数据了。这里设置后就不是拥有该数据, 
  60. 即own_cpu_data或own_gpu_data就为false,因为还有data指向该数据。 
  61. 一般来说,只有当同步后才会为true。也即to_cpu()或者to_gpu()后。 
  62. */  
  63.   const void* cpu_data();//获取cpu数据,返回void * 指针  
  64.   void set_cpu_data(void* data);//用一个void * 指针修改指针,功能:清空CPU的数据  
  65.   const void* gpu_data();//获取gpu数据,返回void * 指针  
  66.   
  67.   
  68.   void* mutable_cpu_data();//获取可以更改cpu数据,返回void * 指针,并改变数据的状态为HEAD_AT_CPU  
  69.   void* mutable_gpu_data();//获取可以更改gpu数据,返回void * 指针,并改变数据的状态为HEAD_AT_GPU  
  70. //关于SymceHead,有四种状态,分别是未初始化,数据在 cpu 中,数据在 gpu 中,  
  71. //数据在 cpu和 gpu 中都有  
  72.   enum SyncedHead { UNINITIALIZED, HEAD_AT_CPU, HEAD_AT_GPU, SYNCED };//enum枚举值  
  73. /* 
  74. 返回数据状态和大小。 
  75. */  
  76.   SyncedHead head() { return head_; }//获得枚举值  
  77.   size_t size() { return size_; }//获得数据大小  
  78.   
  79.  private:  
  80. /* 
  81. 功能:把数据放到cpu上 
  82. 1.数据未初始化,则在cpu申请内存(申请为0)。此时状态为HEAD_AT_CPU 
  83. 2.数据本来在gpu,则从gpu拷贝内存到cpu。此时状态为SYNCED 
  84. 3.数据本来在cpu,不做处理 
  85. 4.数据在cpu和gpu都有,不做处理 
  86. */  
  87.   void to_cpu();  
  88. /* 
  89. 功能:把数据放到gpu上 
  90. 1.数据未初始化,在gpu申请内存(申请为0)。此时状态为HEAD_AT_GPU 
  91. 2.数据在cpu,从cpu拷贝到gpu。此时状态为SYNCED 
  92. 3.数据在gpu,不做操作。 
  93. 4.数据在cpu和gpu都有,不做操作。 
  94. */  
  95.   void to_gpu();   
  96.   void* cpu_ptr_;//指向cpu的指针  
  97.   void* gpu_ptr_;//指向gpu的指指针  
  98.   size_t size_; //大小  
  99.   SyncedHead head_; //数据存放的位置,枚举值之一  
  100.   bool own_cpu_data_;//是否有cpu数据  
  101. /*DISABLE_COPY_AND_ASSIGN是一个宏,用来把该类的拷贝函数和等号操作符给禁止掉,如果想让你的类 
  102. 不能使用 copy 构造函数和赋值操作符,只要将该类的 copy 构造函数和赋值操作符函数定义为 private  
  103. 即可,并且只是声明,不用实现 . 
  104. */  
  105.   DISABLE_COPY_AND_ASSIGN(SyncedMemory);  
  106. };  // class SyncedMemory  
  107.   
  108. }  // namespace caffe  
  109.   
  110. #endif  // CAFFE_SYNCEDMEM_HPP_  

推荐阅读
  • 使用nodejs爬取b站番剧数据,计算最佳追番推荐
    本文介绍了如何使用nodejs爬取b站番剧数据,并通过计算得出最佳追番推荐。通过调用相关接口获取番剧数据和评分数据,以及使用相应的算法进行计算。该方法可以帮助用户找到适合自己的番剧进行观看。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • 本文介绍了三种方法来实现在Win7系统中显示桌面的快捷方式,包括使用任务栏快速启动栏、运行命令和自己创建快捷方式的方法。具体操作步骤详细说明,并提供了保存图标的路径,方便以后使用。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • 本文介绍了最长上升子序列问题的一个变种解法,通过记录拐点的位置,将问题拆分为左右两个LIS问题。详细讲解了算法的实现过程,并给出了相应的代码。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
author-avatar
一个醒不来的梦zyc
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有