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
|
#ifndef ZnnjWYk20gszrSSZENMjL1hM9gI
#define ZnnjWYk20gszrSSZENMjL1hM9gI
#include <inttypes.h>
#include <iostream>
#include <assert.h>
#include <boost/static_assert.hpp>
#include <boost/mpl/if.hpp>
#include <string>
#include "bit_access.hpp"
#include "mempool.hpp"
#include "scalar.hpp"
#include "string_helpers.hpp"
#include "template_helpers.hpp"
namespace VectorImpl {
using std::string;
using namespace boost::mpl;
template<
typename RawPayload,
uint32_t width = 8 * sizeof(RawPayload),
typename Writable = true_> // true_ or false_
class Vector {
public:
typedef uint64_t ptr_t;
typedef typename if_<Writable,
RawPayload,
const RawPayload>::type Payload;
Vector(const string name, const ptr_t size) :
mem((size * width + 7) / 8, name),
barrierRead("barrier_read_" + name),
barrierWrite("barrier_write_" + name),
size(size)
{}
// Vector(Vector&&) = default;
// direct access
Payload & operator() (const ptr_t id) const {
BOOST_STATIC_ASSERT((width >= 8));
assert(id < size);
return *((RawPayload*) (((char*) mem()) + (width / 8) * id));
}
// reader and writer
Payload get(const ptr_t id) const {
assert(id < size);
if (width < 8) {
return (uint8_t) bit_extract(mem(), width, id);
}else{
return *((RawPayload*) (((char*) mem()) + (width / 8) * id));
}
}
void set(const ptr_t id, const RawPayload value) const {
if (!Writable::value) DO_NOT_CALL;
assert(id < size);
if (width < 8) {
bit_insert(mem(), (uint8_t) width, id, value);
}else{
*((RawPayload*) (((char*) mem()) + (width / 8) * id)) = value;
}
}
void sync() const {
if (Writable::value) {
mem.sync();
barrierRead.sync();
barrierWrite.sync();
}
}
void advise(const ptr_t base, const ptr_t length, int adv) {
mem.advise(base * (width / 8), length * (width / 8), adv);
}
// associated memory container
MemPool mem;
// associated r/w-barrier
// WARN: these barriers are not checked/updated in Vector but only
// by iterators/ranges using them; Vector checks only against
// the given size and nothing more
Scalar<ptr_t> barrierRead, barrierWrite;
// maximal number of elements
const ptr_t size;
// garantuee that size = 2^n
STATIC_ASSERT_IS_POWER_OF_TWO(width);
private:
Vector();
};
} // namespace VectorImpl
using VectorImpl::Vector;
#endif // ZnnjWYk20gszrSSZENMjL1hM9gI
|