/[escript]/trunk/escript/src/Taipan.cpp
ViewVC logotype

Contents of /trunk/escript/src/Taipan.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 797 - (show annotations)
Thu Aug 3 02:03:18 2006 UTC (13 years, 3 months ago) by gross
File size: 8184 byte(s)
function added to manually free unused memory in the memory manager
1 /*
2 ************************************************************
3 * Copyright 2006 by ACcESS MNRF *
4 * *
5 * http://www.access.edu.au *
6 * Primary Business: Queensland, Australia *
7 * Licensed under the Open Software License version 3.0 *
8 * http://www.opensource.org/licenses/osl-3.0.php *
9 * *
10 ************************************************************
11 */
12
13 #include "Taipan.h"
14
15 #include <iostream>
16 #include <cassert>
17
18 #ifdef _OPENMP
19 #include <omp.h>
20 #endif
21
22 using namespace std;
23
24 namespace escript {
25
26 Taipan::Taipan() :
27 memTable_Root(0),
28 totalElements(0)
29 {
30 // create and initialise a new StatTable
31 statTable = new Taipan_StatTable;
32 clear_stats();
33 }
34
35 Taipan::~Taipan() {
36
37 long len=0;
38 Taipan_MemTable *tab;
39 Taipan_MemTable *tab_next;
40
41 // dump memory usage statistics
42 dump_stats();
43
44 // deallocate StatTable object
45 delete statTable;
46
47 // deallocate all managed arrays and the memTable
48 tab = memTable_Root;
49 while (tab != 0) {
50 tab_next = tab->next;
51 len = tab->dim * tab->N;
52 totalElements -= len;
53 delete[] tab->array;
54 delete tab;
55 tab = tab_next;
56 }
57
58 assert(totalElements == 0);
59
60 // clear the MemTable root node
61 memTable_Root = 0;
62
63 // reset totalElements counter
64 totalElements = -1;
65 }
66
67 void
68 Taipan::release_unused_arrays()
69 {
70 long len=0;
71 Taipan_MemTable *tab;
72 Taipan_MemTable *tab_next, *tab_prev=0;
73 tab = memTable_Root;
74 while (tab != 0) {
75 tab_next = tab->next;
76 if (tab->free) {
77 delete[] tab->array;
78 len += tab->dim * tab->N;
79 if (tab_prev != 0) {
80 tab_prev->next = tab->next;
81 } else {
82 memTable_Root = tab->next;
83 }
84 delete tab;
85 // increment count of arrays dealloced
86 statTable->deallocations++;
87 } else {
88 tab_prev = tab;
89 }
90 tab = tab_next;
91 }
92 totalElements -= len;
93 statTable->deallocated_elements += len;
94 cout << len*8./1048576 << " Mbytes unused memory has been released." << endl;
95 }
96
97
98 double*
99 Taipan::new_array(int dim, int N) {
100
101 assert(totalElements >= 0);
102
103 int len = 0;
104 #ifdef _OPENMP
105 int numThreads = omp_get_num_threads();
106 #else
107 int numThreads = 1;
108 #endif
109
110 Taipan_MemTable *tab;
111 Taipan_MemTable *new_tab;
112 Taipan_MemTable *tab_prev;
113
114 // increment count of alloc operations called
115 statTable->requests++;
116
117 // is a suitable array already available?
118 if (memTable_Root != 0) {
119 tab = memTable_Root;
120 while (tab != 0) {
121 if (tab->dim == dim &&
122 tab->N == N &&
123 tab->free &&
124 tab->numThreads == numThreads) {
125 tab->free = false;
126 return tab->array;
127 }
128 tab_prev = tab;
129 tab = tab->next;
130 }
131 }
132
133 // otherwise a new array must be allocated
134
135 // create the corresponding memTable entry
136 len = dim * N;
137 new_tab = new Taipan_MemTable;
138 new_tab->dim = dim;
139 new_tab->N = N;
140 new_tab->numThreads = numThreads;
141 new_tab->free = false;
142 new_tab->next = 0;
143 if (memTable_Root == 0) {
144 memTable_Root = new_tab;
145 } else {
146 tab_prev->next = new_tab;
147 }
148
149 // allocate and initialise the new array
150 new_tab->array = new double[len];
151 int i,j;
152 if (N==1) {
153 for (j=0; j<dim; j++)
154 new_tab->array[j]=0.0;
155 } else if (N>1) {
156 #pragma omp parallel for private(i,j) schedule(static)
157 for (i=0; i<N; i++) {
158 for (j=0; j<dim; j++)
159 new_tab->array[j+dim*i]=0.0;
160 }
161 }
162
163 totalElements += len;
164
165 // update maximum table size
166 statTable->max_tab_size = (statTable->max_tab_size < totalElements) ? totalElements : statTable->max_tab_size;
167
168 // increment count of arrays allocated
169 statTable->allocations++;
170
171 // increment count of elements allocated
172 statTable->allocated_elements += len;
173
174 return new_tab->array;
175 }
176
177 void
178 Taipan::delete_array(double* array) {
179
180 assert(totalElements >= 0);
181
182 int N;
183 int len = 0;
184 bool found = false;
185
186 Taipan_MemTable *tab;
187 Taipan_MemTable *tab_next;
188 Taipan_MemTable *tab_prev = 0;
189
190 // increment count of free operations called
191 statTable->frees++;
192
193 if (array == 0) {
194 // have been given an empty array, so quit now
195 return;
196 }
197
198 if (memTable_Root != 0) {
199
200 // find the table entry for this array and mark it as free
201 tab = memTable_Root;
202 while (tab != 0) {
203 if (tab->array == array) {
204 N = tab->N;
205 tab->free = true;
206 found = true;
207 break;
208 }
209 tab = tab->next;
210 }
211 if (!found) {
212 // this wasn't an array under management, so quit now
213 return;
214 }
215
216 if (N<=1) {
217 // we never deallocate arrays with N<=1, so quit now
218 return;
219 }
220
221 // are there any N block arrays still in use?
222 tab = memTable_Root;
223 while (tab != 0) {
224 if (tab->N==N && !tab->free)
225 return;
226 tab = tab->next;
227 }
228
229 // if not, all N block arrays are deallocated
230 tab = memTable_Root;
231 while (tab != 0) {
232 tab_next = tab->next;
233 if (tab->N == N) {
234 delete[] tab->array;
235 len += tab->dim * N;
236 if (tab_prev != 0) {
237 tab_prev->next = tab->next;
238 } else {
239 memTable_Root = tab->next;
240 }
241 delete tab;
242 // increment count of arrays dealloced
243 statTable->deallocations++;
244 } else {
245 tab_prev = tab;
246 }
247 tab = tab_next;
248 }
249
250 totalElements -= len;
251
252 // increment count of elements deallocated
253 statTable->deallocated_elements += len;
254
255 } else {
256 // what to do if no arrays under management?
257 }
258 }
259
260 int
261 Taipan::num_arrays() {
262
263 assert(totalElements >= 0);
264
265 int num_arrays = 0;
266
267 Taipan_MemTable *tab;
268
269 // count all managed arrays in the memTable
270 tab = memTable_Root;
271 while (tab != 0) {
272 num_arrays++;
273 tab = tab->next;
274 }
275
276 return num_arrays;
277 }
278
279 int
280 Taipan::num_arrays(int N) {
281
282 assert(totalElements >= 0);
283
284 int num_arrays = 0;
285
286 Taipan_MemTable *tab;
287
288 // count all managed arrays of N blocks in the memTable
289 tab = memTable_Root;
290 while (tab != 0) {
291 if (tab->N == N) {
292 num_arrays++;
293 }
294 tab = tab->next;
295 }
296
297 return num_arrays;
298 }
299
300 int
301 Taipan::num_free(int N) {
302
303 assert(totalElements >= 0);
304
305 int num_free = 0;
306
307 Taipan_MemTable *tab;
308
309 // count all free managed arrays of N blocks in the memTable
310 tab = memTable_Root;
311 while (tab != 0) {
312 if (tab->N == N) {
313 if (tab->free) {
314 num_free++;
315 }
316 }
317 tab = tab->next;
318 }
319 return num_free;
320 }
321
322 long
323 Taipan::num_elements() {
324
325 assert(totalElements >= 0);
326
327 return totalElements;
328 }
329
330 void
331 Taipan::dump_stats() {
332
333 assert(totalElements >= 0);
334
335 float elMb=statTable->allocated_elements*8.0/1048576;
336 float deelMb=statTable->deallocated_elements*8.0/1048576;
337 float tszMb=statTable->max_tab_size*8.0/1048576;
338 #ifndef PASO_MPI
339 cout << "========== Mem Stats =============================" << endl;
340 cout << "Total Num requests: " << statTable->requests << endl;
341 cout << "Total Num releases: " << statTable->frees << endl;
342 cout << "Total Num allocated arrays: " << statTable->allocations << endl;
343 cout << "Total Num deallocated arrays: " << statTable->deallocations << endl;
344 cout << "Total Num allocated elements: " << statTable->allocated_elements << " (" << elMb << " Mb)" << endl;
345 cout << "Total Num deallocated elements: " << statTable->deallocated_elements << " (" << deelMb << " Mb)" << endl;
346 cout << "Maximum memory buffer size: " << statTable->max_tab_size << " (" << tszMb << " Mb)" << endl;
347 cout << "Curr Num arrays: " << num_arrays() << endl;
348 cout << "Curr Num elements in buffer: " << num_elements() << endl;
349 cout << "==================================================" << endl;
350 #endif
351 }
352
353 void
354 Taipan::clear_stats() {
355
356 assert(totalElements >= 0);
357
358 statTable->requests=0;
359 statTable->frees=0;
360 statTable->allocations=0;
361 statTable->deallocations=0;
362 statTable->allocated_elements=0;
363 statTable->deallocated_elements=0;
364 statTable->max_tab_size=0;
365 }
366
367 } // end of namespace

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.26