【撸码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中,项目比较朴素,是一张线索提交页面,包含表单.图片滚 ...
随机推荐
- Gradle sync failed: Could not find method android() for arguments 错误的解决办法
这个问题本质上是Android-gradle的一个使用限制. 对应的英文文档android_tool文档 如果你的App包含了多个Android模块, 应该尽量避免给每个模块手动指定编译SDK版本. ...
- chm文件打开无显示解决办法
右键单击chm文件---属性---在该页面选择“解除锁定”---ok!
- [WIFI插座][阅读记录][SoC][RT5350] 00.目录 RALINK AP SDK 4.1.0.0 USER’s MANUAL
来源是CSDN,百度网盘下载地址 http://pan.baidu.com/share/link?shareid=3504767505&uk=3426044377 授权声明,略过 免责声明 ...
- ★Java语法(二)——————————数据类型及装换
整数类型: 1.byte型:8位(1字节) 范围:-128~127 用法:byte x = 35 : 2.short型:16位(2字节) 范围:-32768~32767 用法:short x = ...
- 推荐几个好用的windows软件
好久没上了,= = 之前用了一段MAC,感觉好用的地方就是 spotlight和触摸板,哈哈 然后在用回windows之后就找了一下,我之前有用Launchy这个软件,但是他是用来启动程序的,当然你也 ...
- (1)dotnet开源电商系统-brnshop&brnMall 和老外开发的nopCommerce(dotnet两套电商来PK--第一篇)
一直想做电商软件,但是实在不想学PHP了,所以前后关注了这两个开源电商系统.一个是国人出品的,一个据说是俄罗斯人写得(不知道对不对).目前两个开源软件都在学习了解中,以下的博文可能会涉及到这两套系统, ...
- (转)基于Metronic的Bootstrap开发框架经验总结(7)--数据的导入、导出及附件的查看处理
http://www.cnblogs.com/wuhuacong/p/4777720.html 在很多系统模块里面,我们可能都需要进行一定的数据交换处理,也就是数据的导入或者导出操作,这样的批量处理能 ...
- Challenge–response authentication 挑战(询问)应答机制
In computer security, challenge–response authentication is a family of protocols in which one party ...
- C# 带Cookies发送请求
#region --来自黄聪 void F1() { #region --创建cookies容器 添加Cookies和对应的URl(Hots主) CookieContainer cc = new Co ...
- element ui table(表格)点击一行展开
element ui是一个非常不错的vue的UI框架,element对table进行了封装,简化了vue对表格的渲染. element ui表格中有一个功能是展开行,在2.0版本官网例子中,只可以点击 ...