【撸码caffe 一】syncedmen.hpp
SyncedMemory类主要负责在主机(CPU)和设备(GPU)之间管理内存分配和数据同步工作,封装了CPU和GPU之间的数据交互操作。
补充一点GPU的相关知识:
对CUDA架构而言,主机端的内存被分为两种,一种是可分页内存(pageable memroy)和页锁定内存(page-lock或
pinned)。可分页内存是由操作系统API malloc()在主机上分配的,页锁定内存是由CUDA函数cudaHostAlloc()在主机内存上分配的,页锁定内存的重要属性是主机的操作系统将不会对这块内存进行分页和交换操作,确保该内存始终驻留在物理内存中。
GPU知道页锁定内存的物理地址,可以通过“直接内存访问(Direct Memory Access,DMA)”技术直接在主机和GPU之间复制数据,速率更快。由于每个页锁定内存都需要分配物理内存,并且这些内存不能交换到磁盘上,所以页锁定内存比使用标准malloc()分配的可分页内存更消耗内存空间。
syncedmen.hpp文件注释:
#ifndef CAFFE_SYNCEDMEM_HPP_
#define CAFFE_SYNCEDMEM_HPP_
#include <cstdlib>
#include "caffe/common.hpp"
//SyncedMemory类也是在caffe命名空间下定义的,主要在Blob类中被调用
namespace caffe {
/*
如果配置为使用GPU,并且GPU可用,则会在主机上分配页锁定内存(Pinned Memory),
与之对应的另一种内存是可分页内存,由主机负责分配和管理,不能由GPU通过地址直接访问
cudaMallocHost函数提供了直接访问主机内存功能(DMA),速率更快
*/
// If CUDA is available and in GPU mode, host memory will be allocated pinned,
// using cudaMallocHost. It avoids dynamic pinning for transfers (DMA).
// The improvement in performance seems negligible in the single GPU case,
// but might be more significant for parallel training. Most importantly,
// it improved stability for large models on many GPUs.
/*
CaffeMallocHost函数是对CUDA中cudaMallocHost函数的封装,用于在主机中分配页锁定内存
函数的参数分别是内存地址指针,大小以及是否使用CUDA的bool量
*/
inline void CaffeMallocHost(void** ptr, size_t size, bool* use_cuda) {
#ifndef CPU_ONLY
//如果没有配置只使用CPU,并且显明配置使用GPU
if (Caffe::mode() == Caffe::GPU) {
//cudaMallocHost函数用于分配页锁定内存,参数是内存在主机上的地址指针和大小
CUDA_CHECK(cudaMallocHost(ptr, size)); //检查CUDA操作返回的异常信息码
*use_cuda = true;
return;
}
#endif
*ptr = malloc(size); //如果定义只使用CPU,则通过C中malloc在主机上分配内存
*use_cuda = false;
//检查是否有内存分配异常信息并输出
CHECK(*ptr) << "host allocation of size " << size << " failed";
}
//caffe中定义的主机内存(包括页锁定内存和可分页内存)释放函数,定义为内联函数
inline void CaffeFreeHost(void* ptr, bool use_cuda) {
#ifndef CPU_ONLY
if (use_cuda) {
CUDA_CHECK(cudaFreeHost(ptr)); //页锁定内存通过CUDA函数cudaFreeHost释放
return;
}
#endif
free(ptr); //主机普通内存通过free释放
}
/**
* @brief Manages memory allocation and synchronization between the host (CPU)
* and device (GPU).
*
* TODO(dox): more thorough description.
*/
//SyncedMemory类完成数据在CPU和GPU间的内存管理和数据同步工作
class SyncedMemory {
public:
//默认的无参构造函数,默认数据状态设置为UNINITIALIZED,初始使用系统默认的GPU设备
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关键字定义的一个显式构造函数,带一个size大小参数
explicit SyncedMemory(size_t size)
: 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) {}
//析构函数,调用CaffeFreeHost或者cudaFree完成内存释放工作
~SyncedMemory();
//获取只读的CPU数据指针,在内部调用了to_CPU函数
const void* cpu_data();
//设置CPU内存数据,如果own_cpu_data有效,则会先释放内存,并把内存地址指向新的data数据
void set_cpu_data(void* data);
//获取只读的GPU数据指针,在内部调用了to_CPU函数
const void* gpu_data();
//设置GPU内存数据,如果own_gpu_data有效,则会先释放内存,并把内存地址指向新的data数据
void set_gpu_data(void* data);
//获取可以修改的CPU内存数据指针
void* mutable_cpu_data();
//获取可以修改的GPU内存数据指针
void* mutable_gpu_data();
//枚举类型,定义了4中数据存放状态,分别是未初始化,存放在CPU,存放在GPU和数据已经同步
enum SyncedHead { UNINITIALIZED, HEAD_AT_CPU, HEAD_AT_GPU, SYNCED };
//获取数据的存放状态
SyncedHead head() { return head_; }
//获取数据大小,以字节为单位
size_t size() { return size_; }
#ifndef CPU_ONLY
//如果没有定义只使用CPU,则异步推送数据到GPU上,完成数据传输之后设置数据状态为已同步
void async_gpu_push(const cudaStream_t& stream);
#endif
private:
void to_cpu(); //实现把数据存放在cpu功能
void to_gpu(); //实现把数据存放在gpu功能
void* cpu_ptr_; //指向cpu上数据的指针
void* gpu_ptr_; //指向gpu上数据的指针
size_t size_; //数据大小,以字节为单位
SyncedHead head_; //数据存放状态
bool own_cpu_data_; //标识是否已经分配cpu内存
bool cpu_malloc_use_cuda_; //标识是否通过cuda分配了主机内存, 即主机内存是否是页锁定内存
bool own_gpu_data_; //标识是否已经分配了gpu内存
int gpu_device_; //gpu设备编号
//禁止使用SyncedMemory类的拷贝和赋值操作
DISABLE_COPY_AND_ASSIGN(SyncedMemory);
}; // class SyncedMemory
} // namespace caffe
#endif // CAFFE_SYNCEDMEM_HPP_
总的来说,SyncedMemory类封装了在主机和设备上申请数据内存,互相之间通信,获取主机和设备上的内存数据指针,主机和设备的数据同步等功能。
【撸码caffe 一】syncedmen.hpp的更多相关文章
- 【撸码caffe 五】数据层搭建
caffe.cpp中的train函数内声明了一个类型为Solver类的智能指针solver: // Train / Finetune a model. int train() { -- shared_ ...
- 【撸码caffe 二】 blob.hpp
Blob类是caffe中对处理和传递的实际数据的封装,是caffe中基本的数据存储单元,包括前向传播中的图像数据,反向传播中的梯度数据以及网络层间的中间数据变量(包括权值,偏置等),训练模型的参数等等 ...
- 【撸码caffe 三】 caffe.cpp
caffe.cpp文件完成对网络模型以及模型配置参数的读入和提取,提供了网络模型训练的入口函数train和对模型的测试入口函数test.文件中使用了很多gflags和glog指令,gflags是goo ...
- 【撸码caffe四】 solver.cpp&&sgd_solver.cpp
caffe中solver的作用就是交替低啊用前向(forward)算法和后向(backward)算法来更新参数,从而最小化loss,实际上就是一种迭代的优化算法. solver.cpp中的Solver ...
- caffe的db_lmdb.hpp文件
先总的说一下: 类:LMDBCursor: 它干了点什么?它需要传入参数为:mdb_txn(传入它是因为用完它,把它absort掉), mdb_cursor;它应该是用来读出数据的: 类:LMDBT ...
- 我和小美的撸码日记--基于MVC+Jqgrid的.Net快速开发框架
前言:以前的帐号没有发首页的权限,特此把这篇文章从另外一个博客移过来,这篇是<我和小美的撸码日记>的序 一转眼务农6年了,呆过大公司也去过小作坊,码农的人生除了抠腚还是抠腚.在所有呆过的公 ...
- 推荐几个IDEA插件,Java开发者撸码利器(转载)
推荐几个IDEA插件,Java开发者撸码利器. 这里只是推荐一下好用的插件,具体的使用方法不一一详细介绍. JRebel for IntelliJ 一款热部署插件,只要不是修改了项目的配置文件,用 ...
- Intellij IDEA 撸码最头大的问题。。
想栈长我当初从 Eclipse 转用 IDEA 真是纠结,放弃然后尝试了N次,不过现在已经算是转型成功了,可以完全脱离 Eclipse 撸码了,虽然说我现在真的撸得非常少了.. 说到 IDEA 的痛点 ...
- 响应国家号召,在家撸码之React迁移记
最近这段时间新型冠状病毒肆虐,上海确诊人数每天都在增加,人人提心吊胆,街上都没人了.为了响应国家号召,近期呆在家里撸码,着手将项目迁移到React中,项目比较朴素,是一张线索提交页面,包含表单.图片滚 ...
随机推荐
- Asp.net MVC Checkbox控件 和 Nullable<bool>, 或bool?类型
@Html.CheckBoxFor() 这个方法生成两个Input HTML标签,不明白为什么这样,如果数据库是Nullable<bool>类型,就会报错. 网上的解决方法是这样: 方法一 ...
- [转]深入javascript——构造函数和原型对象
对象,是javascript中非常重要的一个梗,是否能透彻的理解它直接关系到你对整个javascript体系的基础理解,说白了,javascript就是一群对象在搅..(哔!). 常用的几种对象创建模 ...
- Eclipse的菜单简介
在Eclipse工作台的上方提供了菜单栏,该菜单栏包含了实现Eclipse各项功能的命令,并且与编辑器相关,即菜单栏中的菜单项与当前编辑器内打开的文件是关联的.例如,编辑器内没有打开任何文件,那么,将 ...
- Spring Boot 整合mybatis时遇到的mapper接口不能注入的问题
现实情况是这样的,因为在练习spring boot整合mybatis,所以自己新建了个项目做测试,可是在idea里面mapper接口注入报错,后来百度查询了下,把idea的注入等级设置为了warnin ...
- ASP.NET MD5加密
protected void Button1_Click(object sender, EventArgs e) { string pwd = TextBox2.Text.Trim(); Respon ...
- Appium Desired Capabilities信息配置
编写APPium脚本,必须要配置Desired Capabilities信息 Desired Capabilities 在启动 session 的时候是必须提供的. Desired Capabilit ...
- OSI参考模型(转)
一.OSI参考模型 自下而上:物理层(物理介质,比特流).数据链路层(网卡.交换机).网络层(IP协议).传输层(TCP/UDP协议).会话层(创建/建立/断开连接).表示层(翻译,编码,压缩,加密) ...
- 记录:Ubuntu下升级Python从2.x到3.x
一.安装Python3 在Ubuntu中的终端输入:sudo apt-get install python3 提示资源被锁住,可能有另外一个程序在占用此资源. 解决方法:输入以下指令解锁资源 sudo ...
- vue小白学习笔记
<div id="div"> <h2>{{ key }}</h2> </div> new Vue ({ el : "#di ...
- 洛谷P1583 魔法照片【模拟+排序】
一共有n(n≤20000)个人(以1--n编号)向佳佳要照片,而佳佳只能把照片给其中的k个人.佳佳按照与他们的关系好坏的程度给每个人赋予了一个初始权值W[i].然后将初始权值从大到小进行排序,每人就有 ...