Caffe源码分析-syncedmem内存

2020-04-20  本文已影响0人  陈泽_06aa

Caffe为了简化CPU主机和GPU内存管理,采用了一个syncedmem类来封装了这两部分的内存管理,其中它主要有以下功能:

在详细了解这些之前我们先介绍几个cuda内存管理函数,完成链接参考CUDA Memory Management

__host__​cudaError_t cudaMallocHost ( void** ptr, size_t size )
分配一个host cpu内存。
__host__​cudaError_t cudaFreeHost ( void* ptr )
释放由cudaMallocHost分配的Host主机内存
__host__​__device__​cudaError_t cudaMalloc ( void** devPtr, size_t size )
在GPU设备上分配一个GPU设备内存
__host__​__device__​cudaError_t cudaFree ( void* devPtr )
释放由cudaMalloc分配的GPU设备内存
__host__​cudaError_t cudaMemcpy ( void* dst, const void* src, size_t count, cudaMemcpyKind kind )
用于Host和设备内存之间复制。

其中有一个很重要点就是,如果启用了CUDA,Host主机上的CPU内存是采用cudaMallocHost/cudaFreeHost进行申请和释放,而不是采用传统的malloc/free,在CUDA产品文档是这样描述:

The cuda driver tracks the virtual memory ranges allocated with cudaMallocHost and automatically accelerates calls to functions such as cudaMemcpy*(). Since the memory can be accessed directly by the device, it can be read or written with much higher bandwidth than pageable memory obtained with functions such as malloc().

因此就有了下面两个基础函数的实现

inline void CaffeMallocHost(void** ptr, size_t size, bool* use_cuda) {
#ifndef CPU_ONLY
  if (Caffe::mode() == Caffe::GPU) {
    CUDA_CHECK(cudaMallocHost(ptr, size));
    *use_cuda = true;
    return;
  }
#endif
  *ptr = malloc(size);
  *use_cuda = false;
}

inline void CaffeFreeHost(void* ptr, bool use_cuda) {
#ifndef CPU_ONLY
  if (use_cuda) {
    CUDA_CHECK(cudaFreeHost(ptr));
    return;
  }
#endif
  free(ptr);
}

有了以上基础知识以后,我们看看syncedmem如何实现。首先看看syncedmem的主类

class SyncedMemory {
 public:
  SyncedMemory();
  ~SyncedMemory();
  const void* cpu_data();
  void set_cpu_data(void* data);
  const void* gpu_data();
  void set_gpu_data(void* data);
  void* mutable_cpu_data();
  void* mutable_gpu_data();
  enum SyncedHead { UNINITIALIZED, HEAD_AT_CPU, HEAD_AT_GPU, SYNCED };
  SyncedHead head() const { return head_; }
  size_t size() const { return size_; }
 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 device_;
}; 

整体上就这些关键点,END

上一篇下一篇

猜你喜欢

热点阅读