转载请注明出处,楼燚(yì)航的blog,http://www.cnblogs.com/louyihang loves baiyan/

看到SyncedMem就知道,这是在做内存同步的操作。这类个类的代码比较少,但是作用是非常明显的。文件对应着syncedmem.hpp,着syncedmem.cpp

首先是两个全局的内联函数。如果机器是支持GPU的并且安装了cuda,通过cudaMallocHost分配的host memory将会被pinned,这里我谷歌了一下,pinned的意思就是内存不会被paged out,我们知道内存里面是由页作为基本的管理单元。分配的内存可以常驻在内存空间中对效率是有帮助的,空间不会被别的进程所抢占。同样如果内存越大,能被分配的Pinned内存自然也越大。还有一点是,对于单一的GPU而言提升并不会太显著,但是对于多个GPU的并行而言可以显著提高稳定性。

这里是两个封装过的函数,内部通过cuda来分配主机和释放内存的接口

inline void CaffeMallocHost(void** ptr, size_t size, bool* use_cuda) {
#ifndef CPU_ONLY
if (Caffe::mode() == Caffe::GPU) {
CUDA_CHECK(cudaMallocHost(ptr, size));// GPU模式下cuda分配内存
*use_cuda = true;
return;
}
#endif
*ptr = malloc(size);//如果没有cuda则通过c的malloc函数分配
*use_cuda = false;
CHECK(*ptr) << "host allocation of size " << size << " failed";
} inline void CaffeFreeHost(void* ptr, bool use_cuda) {
#ifndef CPU_ONLY
if (use_cuda) {
CUDA_CHECK(cudaFreeHost(ptr));//cuda的主机内存释放操作
return;
}
#endif
free(ptr);//c的释放操作
}

SyncedMemory类,首先是构造函数和析构函数

class SyncedMemory {
public:
SyncedMemory() //参数构造函数,负责初始化
: cpu_ptr_(NULL), gpu_ptr_(NULL), size_(0), head_(UNINITIALIZED),
own_cpu_data_(false), cpu_malloc_use_cuda_(false), own_gpu_data_(false),
gpu_device_(-1) {}
explicit SyncedMemory(size_t size)//带explicit关键字的,单个参数构造函数,explicit禁止单参数构造函数的隐式转换
: cpu_ptr_(NULL), gpu_ptr_(NULL), size_(size), head_(UNINITIALIZED),
own_cpu_data_(false), cpu_malloc_use_cuda_(false), own_gpu_data_(false),
gpu_device_(-1) {}
~SyncedMemory();//其在析构时调用的也是CaffeFreeHost

这几个函数分别是

  const void* cpu_data();
void set_cpu_data(void* data);
const void* gpu_data();
void set_gpu_data(void* data);

cpu_data()主要是获得cpu上data的地址,set_cpu_data是将cpu的data指针指向一个新的区域由data指针传入,并且将原来申请的内存释放。下面两个同理,分别是获得gpu数据地址和set gpu数据地址。

  void* mutable_cpu_data();
void* mutable_gpu_data();
enum SyncedHead { UNINITIALIZED, HEAD_AT_CPU, HEAD_AT_GPU, SYNCED };
SyncedHead head() { return head_; }
size_t size() { return size_; }

前两个分别是返回cpu和gpu上的data指针,并且置状态为head_ = HEAD_AT_CPU和响应的gpu版本。SyncedHead主要是个枚举类型,用来设定head_的状态,head()函数即返回相应的数据状态,而size()函数返回数据大小

#ifndef CPU_ONLY
void async_gpu_push(const cudaStream_t& stream);
#endif

这是一个cuda拷贝的异步传输,从数据从cpu拷贝到gpu,异步传输是已经假定caller会在使用之前做同步操作。

 private:
void to_cpu();
void to_gpu();
void* cpu_ptr_;
void* gpu_ptr_;
size_t size_;
SyncedHead head_;
bool own_cpu_data_;
bool cpu_malloc_use_cuda_;
bool own_gpu_data_;
int gpu_device_; DISABLE_COPY_AND_ASSIGN(SyncedMemory);//禁止该类的拷贝与赋值
}; // class SyncedMemory

其实这里的东西也不多了,to_cpu(),to_gpu()这个看名字就知道了,需要注意的是,如果head 是未被初始化的状态,那么首先需要先分配内存,这个根据cpu和gpu视情况而定,之后再将数据从cpu或者gpu拷贝到另一处。之后函数会重新标记Head的状态,数据是否在cpu或者在gpu中,cpu这里是简称,其实是主机。

cpu_ptr和gpu_ptr分别是在cpu和gpu中的数据指针,size_这就不再说了,head_之前也液晶提到过了,后面都是几个相应的标记为,以及gpu的ID号

Caffe源码解析2:SycedMem的更多相关文章

  1. Caffe源码解析7:Pooling_Layer

    转载请注明出处,楼燚(yì)航的blog,http://home.cnblogs.com/louyihang-loves-baiyan/ Pooling 层一般在网络中是跟在Conv卷积层之后,做采样 ...

  2. Caffe源码解析6:Neuron_Layer

    转载请注明出处,楼燚(yì)航的blog,http://home.cnblogs.com/louyihang-loves-baiyan/ NeuronLayer,顾名思义这里就是神经元,激活函数的相应 ...

  3. Caffe源码解析5:Conv_Layer

    转载请注明出处,楼燚(yì)航的blog,http://home.cnblogs.com/louyihang-loves-baiyan/ Vision_layer里面主要是包括了一些关于一些视觉上的操 ...

  4. Caffe源码解析4: Data_layer

    转载请注明出处,楼燚(yì)航的blog,http://home.cnblogs.com/louyihang-loves-baiyan/ data_layer应该是网络的最底层,主要是将数据送给blo ...

  5. Caffe源码解析3:Layer

    转载请注明出处,楼燚(yì)航的blog,http://home.cnblogs.com/louyihang-loves-baiyan/ layer这个类可以说是里面最终的一个基本类了,深度网络呢就是 ...

  6. Caffe源码解析1:Blob

    转载请注明出处,楼燚(yì)航的blog,http://www.cnblogs.com/louyihang-loves-baiyan/ 首先看到的是Blob这个类,Blob是作为Caffe中数据流通的 ...

  7. caffe源码解析

    http://blog.csdn.net/lanxuecc/article/details/53186613

  8. caffe源码阅读

    参考网址:https://www.cnblogs.com/louyihang-loves-baiyan/p/5149628.html 1.caffe代码层次熟悉blob,layer,net,solve ...

  9. 【Caffe】源码解析----caffe.proto (转载)

    分析caffe源码,看首先看caffe.proto,是明智的选择.好吧,我不是创造者,只是搬运工. 原文地址:http://blog.csdn.net/qq_16055159/article/deta ...

随机推荐

  1. MesaSQLite数据库的简单使用方法

    前言部分 本文非原创 文章摘自:http://m.blog.csdn.net/blog/wsxzk123/17282325 数据库工具:MesaSQLite 一.创建数据库 1.创建数据库 MesaS ...

  2. Entity Framework 代码先行之约定配置

    要更改EF中的默认配置有两个方法,一个是用Data Annotations(在命名空间System.ComponentModel.DataAnnotations;),直接作用于类的属性上面;还有一个就 ...

  3. What does "size" in int(size) of MySQL mean?

    What does "size" in int(size) of MySQL mean? https://alexander.kirk.at/2007/08/24/what-doe ...

  4. ImFire即时通讯系统构建(前言)

    缘起termtalk 一切起源于我对蘑菇街termtalk开源IM系统源代码的好奇,termtalk简称tt.无论如何,都应该先向tt致敬,开源实属不易.看了一些分析tt架构的文章,感觉还不错,说是能 ...

  5. Storm的BaseBasicBolt源码解析ack机制

    我们在学习ack机制的时候,我们知道Storm的Bolt有BaseBasicBolt和BaseRichBolt.在BaseBasicBolt中,BasicOutputCollector在emit数据的 ...

  6. logstash VS splunk

    web 系统是典型的分布式部署,由此对其运行状况,硬件运转情况监控也显得尤为重要,这些监控数据表面上对业务运行没有多大的用处(属于基础数据),但正是这些基础数据形成了业务“流”.比如,用户搜索爱好,浏 ...

  7. 用childNodes获取子元素 换行会产生一个子元素

    <div id='div1'> <div id='div2'> <div id='div3'></div> </div> <div c ...

  8. 【转】自定义UITableViewCell(registerNib: 与 registerClass: 的区别)

    自定义UITableViewCell大致有两类方法: 使用nib 1.xib中指定cell的Class为自定义cell类型(注意不是设置File's Owner的class) 2.调用 tableVi ...

  9. iOS开发之聊天模块--内容保存逻辑实现

    需求详解: 在实际开发中,有可能是在后期优化的时候,会有这么需要优化的需求:聊天输入框保存之前输入的文本,提高用户的良好体验. 在聊天模块中,用户可能会在输入框输入若干字符,但是没有点击发送就点击退出 ...

  10. select、poll、epoll区别总结

    1 本质上都是同步I/O 三者都是I/O复用,本质上都属于同步I/O.因为三者只是负责通知应用程序什么时候数据准备好了,实际的I/O操作还是在由应用程序处理:如果是异步I/O的话,实际I/O由内核处理 ...