1. 程式人生 > >caffe原始碼閱讀——SyncedMemory.cpp

caffe原始碼閱讀——SyncedMemory.cpp

SyncedMemory的主要功能是實現CPU和GPU中的資料進行同步。

SyncedMemory的建構函式

//SyncedMemory的建構函式
SyncedMemory::SyncedMemory()
  : cpu_ptr_(NULL), gpu_ptr_(NULL), size_(0), head_(UNINITIALIZED),
    own_cpu_data_(false), cpu_malloc_use_cuda_(false), own_gpu_data_(false) {
#ifndef CPU_ONLY
#ifdef DEBUG
  CUDA_CHECK(cudaGetDevice(&device_));
#endif
#endif } SyncedMemory::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) { #ifndef CPU_ONLY #ifdef DEBUG CUDA_CHECK(cudaGetDevice(&device_)); #endif #endif }

SyncedMemory的解構函式

SyncedMemory::~SyncedMemory() {
  check_device();
  if (cpu_ptr_ && own_cpu_data_) {
    CaffeFreeHost(cpu_ptr_, cpu_malloc_use_cuda_);//釋放CPU資料記憶體
  }

#ifndef CPU_ONLY
  if (gpu_ptr_ && own_gpu_data_) {
    CUDA_CHECK(cudaFree(gpu_ptr_));//釋放GPU資料記憶體
  }
#endif  // CPU_ONLY
}

SyncedMemory::to_cpu()

inline void SyncedMemory::to_cpu() {    //實現把資料存入cpu
  check_device();
  switch (head_) {
  case UNINITIALIZED:    //資料未初始化,則在cpu申請記憶體
    CaffeMallocHost(&cpu_ptr_, size_, &cpu_malloc_use_cuda_);//申請記憶體
    caffe_memset(size_, 0, cpu_ptr_);//申請記憶體的初始化工作
    head_ = HEAD_AT_CPU;
    own_cpu_data_ = true;
    break;
  case HEAD_AT_GPU:     //資料在GPU上儲存時,把資料拷貝到CPU
#ifndef CPU_ONLY
    if (cpu_ptr_ == NULL) {
      CaffeMallocHost(&cpu_ptr_, size_, &cpu_malloc_use_cuda_);
      own_cpu_data_ = true;
    }
    caffe_gpu_memcpy(size_, gpu_ptr_, cpu_ptr_);
    head_ = SYNCED;
#else
    NO_GPU;
#endif
    break;
  case HEAD_AT_CPU:   //資料儲存在CPU時,不做任何處理
  case SYNCED:        //資料在CPU和gpu上時不做任何處理
    break;
  }
}

SyncedMemory::to_gpu()

和SyncedMemory::to_cpu()類似,主要實現在GPU上的資料儲存。

SyncedMemory::cpu_data()

const void* SyncedMemory::cpu_data() {  //返回指向儲存cpu資料的指標cpu_ptr_
  check_device();
  to_cpu();
  return (const void*)cpu_ptr_;
}

SyncedMemory::set_cpu_data(void* data)

void SyncedMemory::set_cpu_data(void* data) {//指向cpu記憶體的指標cpu_ptr_指向新的地方,並釋放原先申請的記憶體
  check_device();
  CHECK(data);
  if (own_cpu_data_) {//如果申請過CPU記憶體則釋放
    CaffeFreeHost(cpu_ptr_, cpu_malloc_use_cuda_);
  }
  cpu_ptr_ = data;//指標指向新的區域
  head_ = HEAD_AT_CPU;
  own_cpu_data_ = false;
}

SyncedMemory::gpu_data()

和SyncedMemory::cpu_data()類似,主要功能為返回指向儲存gpu資料的指標gpu_ptr_。

SyncedMemory::set_gpu_data(void* data)

和SyncedMemory::set_cpu_data(void* data)類似,主要功能釋放GPU儲存的資料。

SyncedMemory::mutable_cpu_data()

void* SyncedMemory::mutable_cpu_data() {//返回指向CPU資料的指標,並把head_的狀態設定為HEAD_AT_CPU
  check_device();
  to_cpu();
  head_ = HEAD_AT_CPU;
  return cpu_ptr_;
}

SyncedMemory::mutable_gpu_data()

void* SyncedMemory::mutable_gpu_data() {
  check_device();
#ifndef CPU_ONLY
  to_gpu();
  head_ = HEAD_AT_GPU;
  return gpu_ptr_;
#else
  NO_GPU;
  return NULL;
#endif
}//返回指向GPU資料的指標,並把head_的狀態設定為HEAD_AT_GPU