NEURON
arraypool.h
Go to the documentation of this file.
1 #ifndef arraypool_h
2 #define arraypool_h
3 
4 // create and manage a vector of arrays as a memory pool of those arrays
5 // the idea is to allow the possibility of some extra cache efficiency
6 
7 // the chain of ArrayPool
8 // is only for extra items in a pool_ and no other fields are used.
9 // The arraypool can be inceased in size by calling grow(ninc) which
10 // will chain a new ArrayPool of that size. Note that threads using
11 // distinct ArrayPool chain items will not have a problem with cache
12 // line sharing.
13 // When the arraypool needs to grow itself then it
14 // doubles in size every time a chain ArrayPool is added.
15 // maxget() tells the most number of arraypool items used at once.
16 // note that grow_(ninc) implicitly assumes all existing space is in use
17 // (i.e. put == get) and hence put ends up as put+ninc. On the other
18 // hand the user callable grow(ninc) assumes NO space is in use,
19 // so also put == get and put is set back to get.
20 
21 template<typename T>
22 class ArrayPool {
23 public:
24  ArrayPool(long count, long d2);
25  ~ArrayPool();
26  T* alloc();
27  void hpfree(T*);
28  int maxget() { return maxget_;}
29  int size() { return count_;}
30  void free_all();
31  T* pool() { return pool_; }
32  long get() { return get_; }
33  long put() { return put_; }
34  long nget() { return nget_; }
35  long ntget() { return ntget_; }
36  long d2() { return d2_; }
37  T* element(long i) { return pool_ + i*d2_; }
38  T** items() { return items_; }
39  void grow(long ninc);
40  ArrayPool* chain() { return chain_; }
41  long chain_size() { return pool_size_; }
42 private:
43  void grow_(long ninc);
44 private:
45  T** items_;
46  T* pool_;
47  long pool_size_;
48  long count_;
49  long get_;
50  long put_;
51  long nget_;
52  long ntget_;
53  long maxget_;
54  long d2_;
57 };
58 
59 
60 template<typename T>
61 ArrayPool<T>::ArrayPool(long count, long d2) {
62  count_ = count;
63  d2_ = d2;
64  pool_ = (T*)nrn_cacheline_calloc((void**)&pool_, count_*d2_, sizeof(T));
65  pool_size_ = count;
66  items_ = new T*[count_];
67  for (long i = 0; i < count_; ++i) {
68  items_[i] = pool_ + i*d2_;
69  }
70  get_ = 0;
71  put_ = 0;
72  nget_ = 0;
73  ntget_ = 0;
74  maxget_ = 0;
75  chain_ = 0;
76  chainlast_ = this;
77 }
78 
79 template<typename T>
80 void ArrayPool<T>::grow(long ninc) {
81  grow_(ninc);
82  put_ = get_;
83 }
84 
85 template<typename T>
86 void ArrayPool<T>::grow_(long ninc) {
87  assert(get_ == put_);
88  ArrayPool* p = new ArrayPool(ninc, d2_);
89  chainlast_->chain_ = p;
90  chainlast_ = p;
91  long newcnt = count_ + ninc;
92  T** itms = new T*[newcnt];
93  long i, j;
94  put_ += ninc;
95  for (i = 0; i < get_; ++i) {
96  itms[i] = items_[i];
97  }
98  for (i = get_, j = 0; j < ninc; ++i, ++j) {
99  itms[i] = p->items_[j];
100  }
101  for (i = put_, j = get_; j < count_; ++i, ++j) {
102  itms[i] = items_[j];
103  }
104  delete [] items_;
105  delete [] p->items_;
106  p->items_ = 0;
107  items_ = itms;
108  count_ = newcnt;
109 }
110 
111 template<typename T>
113  if (chain_) {
114  delete chain_;
115  }
116  free(pool_);
117  if (items_) {
118  delete [] items_;
119  }
120 }
121 
122 template<typename T>
124  if (nget_ >= count_) { grow_(count_); }
125  T* item = items_[get_];
126  get_ = (get_+1)%count_;
127  ++nget_;
128  ++ntget_;
129  if (nget_ > maxget_) { maxget_ = nget_; }
130  return item;
131 }
132 
133 template<typename T>
134 void ArrayPool<T>::hpfree(T* item) {
135  assert(nget_ > 0);
136  items_[put_] = item;
137  put_ = (put_ + 1)%count_;
138  --nget_;
139 }
140 
141 template<typename T>
143  ArrayPool* pp;
144  long i;
145  nget_ = 0;
146  get_ = 0;
147  put_ = 0;
148  for(pp = this; pp; pp = pp->chain_) {
149  for (i=0; i < pp->pool_size_; ++i) {
150  items_[put_++] = pp->pool_ + i*d2_;
151  }
152  }
153  assert(put_ == count_);
154  put_ = 0;
155 }
156 
157 #endif
long d2()
Definition: arraypool.h:36
#define assert(ex)
Definition: hocassrt.h:26
double T
Definition: rbtqueue.cpp:25
int size()
Definition: arraypool.h:29
ArrayPool(long count, long d2)
Definition: arraypool.h:61
long ntget_
Definition: arraypool.h:52
size_t p
long d2_
Definition: arraypool.h:54
T ** items()
Definition: arraypool.h:38
long nget()
Definition: arraypool.h:34
ArrayPool * chain_
Definition: arraypool.h:55
long put()
Definition: arraypool.h:33
long nget_
Definition: arraypool.h:51
long get_
Definition: arraypool.h:49
T * alloc()
Definition: arraypool.h:123
ArrayPool * chain()
Definition: arraypool.h:40
void hpfree(T *)
Definition: arraypool.h:134
T * pool_
Definition: arraypool.h:46
void grow_(long ninc)
Definition: arraypool.h:86
void grow(long ninc)
Definition: arraypool.h:80
void free_all()
Definition: arraypool.h:142
size_t j
ArrayPool * chainlast_
Definition: arraypool.h:56
~ArrayPool()
Definition: arraypool.h:112
long count_
Definition: arraypool.h:48
void * nrn_cacheline_calloc(void **memptr, size_t nmemb, size_t size)
Definition: symbol.cpp:242
T * pool()
Definition: arraypool.h:31
long ntget()
Definition: arraypool.h:35
T ** items_
Definition: arraypool.h:45
long pool_size_
Definition: arraypool.h:47
#define i
Definition: md1redef.h:12
T * element(long i)
Definition: arraypool.h:37
long put_
Definition: arraypool.h:50
long maxget_
Definition: arraypool.h:53
int maxget()
Definition: arraypool.h:28
long chain_size()
Definition: arraypool.h:41