作者:一个醒不来的梦zyc | 来源:互联网 | 2023-09-24 20:41
梳理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来分配主机和释放内存的接口.
- #ifndef CAFFE_SYNCEDMEM_HPP_
- #define CAFFE_SYNCEDMEM_HPP_
-
- #include
-
- #include "caffe/common.hpp"
- #include "caffe/util/math_functions.hpp"
-
- namespace caffe {
-
- inline void CaffeMallocHost(void** ptr, size_t size) {
- *ptr = malloc(size);
- CHECK(*ptr) << "host allocation of size " << size << " failed";
- }
-
- inline void CaffeFreeHost(void* ptr) {
- free(ptr);
- }
-
-
- class SyncedMemory {
- public:
- SyncedMemory()
- : cpu_ptr_(NULL), gpu_ptr_(NULL), size_(0), head_(UNINITIALIZED),
- own_cpu_data_(false) {}
- explicit SyncedMemory(size_t size)
- : cpu_ptr_(NULL), gpu_ptr_(NULL), size_(size), head_(UNINITIALIZED),
- own_cpu_data_(false) {}
- ~SyncedMemory();
- const void* cpu_data();
- void set_cpu_data(void* data);
- const void* gpu_data();
-
-
- 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_; }
-
- private:
- void to_cpu();
- void to_gpu();
- void* cpu_ptr_;
- void* gpu_ptr_;
- size_t size_;
- SyncedHead head_;
- bool own_cpu_data_;
- DISABLE_COPY_AND_ASSIGN(SyncedMemory);
- };
-
- }
-
- #endif // CAFFE_SYNCEDMEM_HPP_