caffe-SyncedMemory

结构:caffe命名空间中包含两个inline函数和类SyncedMemory的声明。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#ifndef CAFFE_SYNCEDMEM_HPP_
#define CAFFE_SYNCEDMEM_HPP_

#include <cstdlib>

#ifdef USE_MKL
#include "mkl.h" // 使用intel数学运算库MKL
#endif

#include "caffe/common.hpp"

namespace caffe {

// 使用cudaMallocHost()方法从Host内存开辟空间。从这里开辟空间对于单个GPU性能提升不明显,但是对于大的模型在多GPU上的训练,有较大的性能提升。
inline void CaffeMallocHost(void** ptr, size_t size, bool* use_cuda) {
#ifndef CPU_ONLY // 如果没有指明CPU_ONLY,则:
if (Caffe::mode() == Caffe::GPU) {
CUDA_CHECK(cudaMallocHost(ptr, size));
*use_cuda = true;
return;
}
#endif
#ifdef USE_MKL // 如果使用MKL,则:
*ptr = mkl_malloc(size ? size:1, 64);
#else // 否则:
*ptr = malloc(size);
#endif
*use_cuda = false;
CHECK(*ptr) << "host allocation of size " << size << " failed";
}

// 与开辟空间对应,用于释放内存。
inline void CaffeFreeHost(void* ptr, bool use_cuda) {
#ifndef CPU_ONLY
if (use_cuda) {
CUDA_CHECK(cudaFreeHost(ptr));
return;
}
#endif
#ifdef USE_MKL
mkl_free(ptr);
#else
free(ptr);
#endif
}


// 负责Host和Device内存的分配,和两者间内存同步
class SyncedMemory {
public:
// 构造和析构函数
SyncedMemory();
explicit SyncedMemory(size_t size);
~SyncedMemory();
// 只读方式只读数据
const void* cpu_data();
const void* gpu_data();
// 设置数据
void set_cpu_data(void* data);
void set_gpu_data(void* data);
// 读写方式读取数据
void* mutable_cpu_data();
void* mutable_gpu_data();
// 状态变量:未初始化,CPU数据有效,GPU数据有效,已同步
enum SyncedHead { UNINITIALIZED,
HEAD_AT_CPU,
HEAD_AT_GPU,
SYNCED };
// 获取当前状态变量值
SyncedHead head() const { return head_; }
// 返回当前存储空间的大小
size_t size() const { return size_; }

#ifndef CPU_ONLY
void async_gpu_push(const cudaStream_t& stream);
#endif

private:
void check_device();

void to_cpu(); // 同步数据到host
void to_gpu(); // 同步数据到Device
void* cpu_ptr_; // 位于Host的数据指针
void* gpu_ptr_; // 位于Device的数据指针
size_t size_; // 存储空间的大小
SyncedHead head_; // 当前状态变量
bool own_cpu_data_; // 是否有cpu数据的所有权
bool cpu_malloc_use_cuda_; // 是否
bool own_gpu_data_; // 是否有gpu数据的所有权
int device_; // 设备号

DISABLE_COPY_AND_ASSIGN(SyncedMemory);
}; // class SyncedMemory

} // namespace caffe

#endif // CAFFE_SYNCEDMEM_HPP_

补充,条件编译预编译指令

#define
#undef
#if
#ifdef
#ifndef
#elif
#else
#endif
defined:与#if, #elif配合使用,判断某个宏是否被定义

USE_MKL的定义在文件include/caffe/util/mkl_alternate.hpp中。
CPU_ONLY的定义在文件``?????