From 735935d19d9c2337bae7e0826780ad454de58adf Mon Sep 17 00:00:00 2001 From: Olli Lupton Date: Tue, 1 Nov 2022 14:59:13 +0100 Subject: [PATCH] drop unused memory pool code --- src/ivoc/ocnotify.h | 2 + src/nrniv/cxprop.cpp | 352 ++++--------------------------------------- 2 files changed, 30 insertions(+), 324 deletions(-) diff --git a/src/ivoc/ocnotify.h b/src/ivoc/ocnotify.h index bdf0bd5c4a..96459b6686 100644 --- a/src/ivoc/ocnotify.h +++ b/src/ivoc/ocnotify.h @@ -1,6 +1,8 @@ #pragma once #include +#include // std::size_t + void nrn_notify_freed(void (*pf)(void*, int)); void nrn_notify_when_void_freed(void* p, Observer* ob); void nrn_notify_when_double_freed(double* p, Observer* ob); diff --git a/src/nrniv/cxprop.cpp b/src/nrniv/cxprop.cpp index 5825760a8b..2c590b53e3 100644 --- a/src/nrniv/cxprop.cpp +++ b/src/nrniv/cxprop.cpp @@ -17,242 +17,22 @@ greater cache efficiency #include #include -extern void nrn_mk_prop_pools(int); -extern void nrn_cache_prop_realloc(); extern int nrn_is_ion(int); -void nrn_delete_prop_pool(int type); #if EXTRACELLULAR extern void nrn_extcell_update_param(); #endif extern void nrn_recalc_ptrs(double* (*) (double*) ); -static double* recalc_ptr(double*); +static constexpr auto APSIZE = 1000; using CharArrayPool = ArrayPool; - -#define APSIZE 1000 using DoubleArrayPool = ArrayPool; using DatumArrayPool = ArrayPool; +using SectionPool = Pool
; -static int force; static int npools_; static DoubleArrayPool** dblpools_; static DatumArrayPool** datumpools_; -static void mk_prop_pools(int n); - -#define NRN_MECH_REORDER 1 - -/* -Based on the nrn_threads tml->ml->nodelist order from the last -call to nrn_cache_prop_realloc() (which writes a data file) from -a previous launch, on this launch, read that file and create -pools matched to the space needed by each thread and which, from -the sequence of data allocation requests returns space that ends -up being laid out in memory in just the way we want. -The data file format is -maxtype // so we can be sure we have large enough npools_ -nthread // number of threads -nmech // number of mechanisms used in this thread -type sz1 sz2 ntget cnt // mechanism type, double/Datum array size total number of times alloc was -called, how many needed for this thread -// the above specifies the pool allocation -// note that the pool chain order is the same as the thread order -// there are nthread of the following lists -cnt // number of mechanisms in thread -type i seq // i is the tml->ml->_data[i], seq is the allocation order -// ie we want - -Note that the overall memory allocation sequence has to be identical -to the original sequence in terms of get/put for the final -layout to be exactly right for cache efficiency and for threads not -to share cache lines. However, if this is not the case, the memory allocation -is still correct, just not as efficient. -*/ - -#if NRN_MECH_REORDER - -static void read_temp1() { - // return; - FILE* f; - int nscan, maxtype, imech, nmech, type, sz1, sz2, ntget, ith, nth, i, j, cnt, seq; - char line[200]; - sprintf(line, "temp_%d_%d", nrnmpi_myid, nrnmpi_numprocs); - f = fopen(line, "r"); - if (!f) { - return; - } - force = 1; - nrn_assert(fgets(line, 200, f)); - nrn_assert(sscanf(line, "%d", &maxtype) == 1); - mk_prop_pools(maxtype); - long* ntget1 = new long[maxtype]; - for (i = 0; i < maxtype; ++i) { - ntget1[i] = 0; - } - - // allocate the pool space - nrn_assert(fgets(line, 200, f)); - nrn_assert(sscanf(line, "%d", &nth) == 1); - for (ith = 0; ith < nth; ++ith) { - nrn_assert(fgets(line, 200, f)); - nrn_assert(sscanf(line, "%d", &nmech) == 1); - for (imech = 0; imech < nmech; ++imech) { - nrn_assert(fgets(line, 200, f)); - nrn_assert(sscanf(line, "%d %d %d %d %d", &type, &sz1, &sz2, &ntget, &cnt) == 5); - // printf("(%d %d %d %d %d) %s", type, sz1, sz2, ntget, cnt, line); - ntget1[type] = ntget; - if (sz1) { - if (!dblpools_[type]) { - dblpools_[type] = new DoubleArrayPool(cnt, sz1); - } else { - dblpools_[type]->grow(cnt); - } - } - if (sz2) { - if (!datumpools_[type]) { - datumpools_[type] = new DatumArrayPool(cnt, sz2); - } else { - datumpools_[type]->grow(cnt); - } - } - } - } - for (i = 0; i < maxtype; ++i) { - if (dblpools_[i] && dblpools_[i]->size() < ntget1[i]) { - dblpools_[i]->grow(ntget1[i] - dblpools_[i]->size()); - } - if (datumpools_[i] && datumpools_[i]->size() < ntget1[i]) { - datumpools_[i]->grow(ntget1[i] - datumpools_[i]->size()); - } - } - delete[] ntget1; - - // now the tricky part, put items in an unnatural order - // first set all pointers to 0 - for (i = 0; i < maxtype; ++i) { - if (dblpools_[i]) { - double** items = dblpools_[i]->items(); - int sz = dblpools_[i]->size(); - for (int j = 0; j < sz; ++j) { - items[j] = 0; - } - } - if (datumpools_[i]) { - Datum** items = datumpools_[i]->items(); - int sz = datumpools_[i]->size(); - for (int j = 0; j < sz; ++j) { - items[j] = 0; - } - } - } - - // then set the proper seq pointers - DoubleArrayPool** p1 = new DoubleArrayPool*[npools_]; - DatumArrayPool** p2 = new DatumArrayPool*[npools_]; - int* chain = new int[npools_]; - for (i = 0; i < npools_; ++i) { - p1[i] = dblpools_[i]; - p2[i] = datumpools_[i]; - chain[i] = 0; - } - for (ith = 0; ith < nth; ++ith) { - nrn_assert(fgets(line, 200, f)); - nrn_assert(sscanf(line, "%d", &cnt) == 1); - for (i = 0; i < cnt; ++i) { - nrn_assert(fgets(line, 200, f)); - nrn_assert(sscanf(line, "%d %d %d", &type, &j, &seq)); - if (dblpools_[type]) { - double** items = dblpools_[type]->items(); - assert(items[seq] == 0); - items[seq] = p1[type]->element(j); - ++chain[type]; - } - if (datumpools_[type]) { - Datum** items = datumpools_[type]->items(); - assert(items[seq] == 0); - items[seq] = p2[type]->element(j); - ++chain[type]; - } - } - for (i = 0; i < npools_; ++i) { - if (chain[i]) { - if (p1[i] && p2[i]) { - assert(chain[i] == (p1[i]->chain_size() + p2[i]->chain_size())); - } else if (p1[i]) { - assert(chain[i] == p1[i]->chain_size()); - } else if (p2[i]) { - assert(chain[i] == p2[i]->chain_size()); - } - if (p1[i]) { - p1[i] = p1[i]->chain(); - } - if (p2[i]) { - p2[i] = p2[i]->chain(); - } - chain[i] = 0; - } - } - } - // finally set the rest - for (i = 0; i < npools_; ++i) { - if (p1[i]) { - int j = 0; - int k = 0; - int n = dblpools_[i]->size(); - int sz = p1[i]->chain_size(); - double** items = dblpools_[i]->items(); - for (j = 0; j < n; ++j) { - if (items[j] == 0) { - assert(k < sz); - items[j] = p1[i]->element(k); - ++k; - } - } - assert(k == sz); - } - if (p2[i]) { - int j = 0; - int k = 0; - int n = datumpools_[i]->size(); - int sz = p2[i]->chain_size(); - Datum** items = datumpools_[i]->items(); - for (j = 0; j < n; ++j) { - if (items[j] == 0) { - assert(k < sz); - items[j] = p2[i]->element(k); - ++k; - } - } - assert(k == sz); - } - } - delete[] p1; - delete[] p2; - fclose(f); -} -#endif // NRN_MECH_REORDER - -static void mk_prop_pools(int n) { - int i; - if (n > npools_) { - DoubleArrayPool** p1 = new DoubleArrayPool*[n]; - DatumArrayPool** p2 = new DatumArrayPool*[n]; - for (i = 0; i < n; ++i) { - p1[i] = 0; - p2[i] = 0; - } - if (dblpools_) { - for (i = 0; i < npools_; ++i) { - p1[i] = dblpools_[i]; - p2[i] = datumpools_[i]; - } - delete[] dblpools_; - delete[] datumpools_; - } - dblpools_ = p1; - datumpools_ = p2; - npools_ = n; - } -} +static SectionPool* secpool_; void nrn_delete_prop_pool(int type) { assert(type < npools_); @@ -266,12 +46,26 @@ void nrn_delete_prop_pool(int type) { } void nrn_mk_prop_pools(int n) { -#if NRN_MECH_REORDER - if (force == 0) { - read_temp1(); + if (n <= npools_) { + return; } -#endif - mk_prop_pools(n); + DoubleArrayPool** p1 = new DoubleArrayPool*[n]; + DatumArrayPool** p2 = new DatumArrayPool*[n]; + for (int i = 0; i < n; ++i) { + p1[i] = 0; + p2[i] = 0; + } + if (dblpools_) { + for (int i = 0; i < npools_; ++i) { + p1[i] = dblpools_[i]; + p2[i] = datumpools_[i]; + } + delete[] dblpools_; + delete[] datumpools_; + } + dblpools_ = p1; + datumpools_ = p2; + npools_ = n; } double* nrn_prop_data_alloc(int type, int count, Prop* p) { @@ -317,10 +111,6 @@ void nrn_prop_datum_free(int type, Datum* ppd) { } } -using SectionPool = Pool
; - -static SectionPool* secpool_; - Section* nrn_section_alloc() { if (!secpool_) { secpool_ = new SectionPool(1000); @@ -328,6 +118,7 @@ Section* nrn_section_alloc() { Section* s = secpool_->alloc(); return s; } + void nrn_section_free(Section* s) { secpool_->hpfree(s); } @@ -632,111 +423,24 @@ void nrn_poolshrink(int shrink) { void nrn_cache_prop_realloc() { if (!nrn_prop_is_cache_efficient()) { - // printf("begin nrn_prop_is_cache_efficient %d\n", nrn_prop_is_cache_efficient()); in_place_data_realloc(); - // printf("end nrn_prop_is_cache_efficient %d\n", nrn_prop_is_cache_efficient()); - } - return; - - -#if NRN_MECH_REORDER - nrn_prop_is_cache_efficient(); - FILE* f; - char buf[100]; - int i, it, type; - // we wish to rearrange the arrays so that they are in memb_list->data order within - // the ArrayPools. We do not want to use up a lot of temporary space to do this - // because there may not be much left. - // In each pool all the pointers between put and get (nget of them) are in use. - if (force) { - sprintf(buf, "temp2_%d", nrnmpi_myid); - } else { - sprintf(buf, "temp_%d_%d", nrnmpi_myid, nrnmpi_numprocs); - } - f = fopen(buf, "w"); - fprintf(f, "%d\n", n_memb_func); - fprintf(f, "%d\n", nrn_nthread); - for (it = 0; it < nrn_nthread; ++it) { - NrnThread* nt = nrn_threads + it; - // how many mechanisms used in this thread - i = 0; - for (NrnThreadMembList* tml = nt->tml; tml; tml = tml->next) { - ++i; - } - fprintf(f, "%d\n", i); - for (NrnThreadMembList* tml = nt->tml; tml; tml = tml->next) { - Memb_list* ml = tml->ml; - i = tml->index; - int j, cnt = ml->nodecount; - int sz1 = 0, sz2 = 0, ntget = 0; - if (dblpools_[i]) { - sz1 = dblpools_[i]->d2(); - ntget = dblpools_[i]->ntget(); - } - if (datumpools_[i]) { - sz2 = datumpools_[i]->d2(); - } - fprintf(f, "%d %d %d %d %d %s\n", i, sz1, sz2, ntget, cnt, memb_func[i].sym->name); - } - } - // above is enough for allocating the pools. Now the proper order info. - Memb_list** mlmap = new Memb_list*[n_memb_func]; - for (it = 0; it < nrn_nthread; ++it) { - NrnThread* nt = nrn_threads + it; - for (i = 0; i < n_memb_func; ++i) { - mlmap[i] = 0; - } // unnecessary but ... - // how many prop used in this thread - int cnt = 0; - for (NrnThreadMembList* tml = nt->tml; tml; tml = tml->next) { - cnt += tml->ml->nodecount; - tml->ml->nodecount = 0; // recount them below - mlmap[tml->index] = tml->ml; - } - fprintf(f, "%d\n", cnt); - int cnt2 = 0; - for (i = 0; i < nt->end; ++i) { - Node* nd = nt->_v_node[i]; - for (Prop* p = nd->prop; p; p = p->next) { - if (memb_func[p->_type].current || memb_func[p->_type].state || - memb_func[p->_type].initialize) { - Memb_list* ml = mlmap[p->_type]; - if (!ml || nd != ml->nodelist[ml->nodecount]) { - abort(); - } - assert(ml && nd == ml->nodelist[ml->nodecount]); - nrn_assert(fprintf(f, "%d %d %ld\n", p->_type, ml->nodecount++, p->_alloc_seq) > - 0); - ++cnt2; - } - } - } - assert(cnt == cnt2); } - delete[] mlmap; - fclose(f); -#endif } // for avoiding interthread cache line sharing // each thread needs its own pool instance extern "C" void* nrn_pool_create(long count, int itemsize) { - CharArrayPool* p = new CharArrayPool(count, itemsize); - return (void*) p; + return new CharArrayPool(count, itemsize); } extern "C" void nrn_pool_delete(void* pool) { - CharArrayPool* p = (CharArrayPool*) pool; - delete p; + delete static_cast(pool); } extern "C" void* nrn_pool_alloc(void* pool) { - CharArrayPool* p = (CharArrayPool*) pool; - return (void*) p->alloc(); + return static_cast(pool)->alloc(); } extern "C" void nrn_pool_free(void* pool, void* item) { - CharArrayPool* p = (CharArrayPool*) pool; - p->hpfree(static_cast(item)); + static_cast(pool)->hpfree(static_cast(item)); } extern "C" void nrn_pool_freeall(void* pool) { - CharArrayPool* p = (CharArrayPool*) pool; - p->free_all(); + static_cast(pool)->free_all(); }