forked from zhangmeishan/EGN3LDG
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMem.h
118 lines (105 loc) · 2.33 KB
/
Mem.h
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#ifndef N3L_MEM_H
#define N3L_MEM_H
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#if !_WINDOWS
#include <sys/shm.h>
#include <sys/mman.h>
#endif
#include <fcntl.h>
#if !_WINDOWS
#include <mm_malloc.h>
#endif
//This is the code copied from dynet: only CPU model
class AlignedMemoryPool {
private:
const static int align = 32;
const static size_t unit_size = 1 << 30;
private:
char** mem;
public:
size_t capacity;
size_t used, index;
float required; // orcale required size
private:
inline std::size_t round_up_align(std::size_t n) const {
if (align < 2) return n;
return ((n + align - 1) / align) * align;
}
void malloc(std::size_t n) {
capacity = n;
mem = new char*[capacity];
for (int idx = 0; idx < capacity; idx++) {
mem[idx] = (char*)_mm_malloc(unit_size, align);
if (!mem[idx]) {
std::cerr << "CPU memory allocation failed capacity=" << idx << " align=" << align << std::endl;
}
zero((void*)(mem[idx]), unit_size);
}
}
void free() {
for (int idx = 0; idx < capacity; idx++) {
_mm_free((void*)mem[idx]);
}
delete[] mem;
mem = NULL;
}
public:
AlignedMemoryPool(size_t cap) {
used = 0;
index = 0;
capacity = cap;
if (capacity > 0) {
malloc(capacity);
}
required = 0;
}
~AlignedMemoryPool() {
if (capacity > 0) {
free();
}
capacity = 0;
used = 0;
index = 0;
}
public:
inline void zero(void* p, std::size_t n) {
memset(p, 0, n);
}
void* allocate(size_t n, size_t& aligned) {
aligned = round_up_align(n);
required += aligned * 1.0 / unit_size; //never mind if the memory is allocated successfully.
if (used == capacity || aligned > unit_size) {
//std::cout << "allocated size bigger than unit size!" << std::endl;
return NULL;
}
void* res = NULL;
if (aligned + index <= unit_size) {
//std::cout << "aligned memory is full: " << capacity << ")\n";
res = mem[used] + index;
index += aligned;
if (index == unit_size) {
used++;
index = 0;
}
}
else if (used + 1 < capacity) {
used++;
index = 0;
res = mem[used] + index;
index += aligned;
}
return res;
}
// zeros out the amount of allocations
void zero_allocated_memory() {
if (used == 0 && index == 0) return;
for (int idx = 0; idx < used; idx++) {
zero((void*)(mem[idx]), unit_size);
}
zero((void*)(mem[used]), unit_size);
}
};
#endif