small updates to MyPage and convert MyPoolChunk similar to MyPage
This commit is contained in:
@ -430,6 +430,7 @@ INPUT = @LAMMPS_SOURCE_DIR@/utils.cpp \
|
|||||||
@LAMMPS_SOURCE_DIR@/potential_file_reader.h \
|
@LAMMPS_SOURCE_DIR@/potential_file_reader.h \
|
||||||
@LAMMPS_SOURCE_DIR@/my_page.cpp \
|
@LAMMPS_SOURCE_DIR@/my_page.cpp \
|
||||||
@LAMMPS_SOURCE_DIR@/my_page.h \
|
@LAMMPS_SOURCE_DIR@/my_page.h \
|
||||||
|
@LAMMPS_SOURCE_DIR@/my_pool_chunk.cpp \
|
||||||
@LAMMPS_SOURCE_DIR@/my_pool_chunk.h \
|
@LAMMPS_SOURCE_DIR@/my_pool_chunk.h \
|
||||||
|
|
||||||
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
|
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
|
||||||
|
|||||||
@ -1162,3 +1162,7 @@ its size is registered later with :cpp:func:`vgot()
|
|||||||
.. doxygenclass:: LAMMPS_NS::MyPage
|
.. doxygenclass:: LAMMPS_NS::MyPage
|
||||||
:project: progguide
|
:project: progguide
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
|
.. doxygenclass:: LAMMPS_NS::MyPoolChunk
|
||||||
|
:project: progguide
|
||||||
|
:members:
|
||||||
|
|||||||
@ -555,7 +555,7 @@ bigint AtomVecBody::memory_usage_bonus()
|
|||||||
{
|
{
|
||||||
bigint bytes = 0;
|
bigint bytes = 0;
|
||||||
bytes += nmax_bonus*sizeof(Bonus);
|
bytes += nmax_bonus*sizeof(Bonus);
|
||||||
bytes += icp->size + dcp->size;
|
bytes += icp->size() + dcp->size();
|
||||||
|
|
||||||
int nall = nlocal_bonus + nghost_bonus;
|
int nall = nlocal_bonus + nghost_bonus;
|
||||||
for (int i = 0; i < nall; i++) {
|
for (int i = 0; i < nall; i++) {
|
||||||
|
|||||||
@ -29,8 +29,9 @@ using namespace LAMMPS_NS;
|
|||||||
* The chunks are not returnable like with malloc() (i.e. you cannot
|
* The chunks are not returnable like with malloc() (i.e. you cannot
|
||||||
* call free() on them individually). One can only reset and start over.
|
* call free() on them individually). One can only reset and start over.
|
||||||
* The purpose of this class is to replace many small memory allocations
|
* The purpose of this class is to replace many small memory allocations
|
||||||
* via malloc() with a few large ones. Since the pages are never freed,
|
* via malloc() with a few large ones. Since the pages are never freed
|
||||||
* they can be re-used without having to re-allocate them.
|
* until the class is re-initialized, they can be re-used without having
|
||||||
|
* to re-allocate them by calling the reset() method.
|
||||||
*
|
*
|
||||||
* The settings *maxchunk*, *pagesize*, and *pagedelta* control
|
* The settings *maxchunk*, *pagesize*, and *pagedelta* control
|
||||||
* the memory allocation strategy. The *maxchunk* value represents
|
* the memory allocation strategy. The *maxchunk* value represents
|
||||||
|
|||||||
@ -18,10 +18,6 @@
|
|||||||
#ifndef LAMMPS_MY_PAGE_H
|
#ifndef LAMMPS_MY_PAGE_H
|
||||||
#define LAMMPS_MY_PAGE_H
|
#define LAMMPS_MY_PAGE_H
|
||||||
|
|
||||||
#if defined(LMP_USER_INTEL) && !defined(LAMMPS_MEMALIGN) && !defined(_WIN32)
|
|
||||||
#define LAMMPS_MEMALIGN 64
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "lmptype.h"
|
#include "lmptype.h"
|
||||||
|
|
||||||
namespace LAMMPS_NS {
|
namespace LAMMPS_NS {
|
||||||
|
|||||||
244
src/my_pool_chunk.cpp
Normal file
244
src/my_pool_chunk.cpp
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
/* -*- c++ -*- ----------------------------------------------------------
|
||||||
|
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||||
|
http://lammps.sandia.gov, Sandia National Laboratories
|
||||||
|
Steve Plimpton, sjplimp@sandia.gov
|
||||||
|
|
||||||
|
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||||
|
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||||
|
certain rights in this software. This software is distributed under
|
||||||
|
the GNU General Public License.
|
||||||
|
|
||||||
|
See the README file in the top-level LAMMPS directory.
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#include "my_pool_chunk.h"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
#if defined(LMP_USER_INTEL) && !defined(LAMMPS_MEMALIGN) && !defined(_WIN32)
|
||||||
|
#define LAMMPS_MEMALIGN 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
using namespace LAMMPS_NS;
|
||||||
|
|
||||||
|
/** \class LAMMPS_NS::MyPoolChunk
|
||||||
|
* \brief Templated class for storing chunks of datums in pages
|
||||||
|
*
|
||||||
|
* The size of the chunk may vary from call to call between the
|
||||||
|
* *minchunk* and *maxchunk* setting. Chunks may be returned
|
||||||
|
* to the pool for re-use. Chunks can be reserved in *nbin*
|
||||||
|
* different sizes between *minchunk* and *maxchunk*.
|
||||||
|
* The *chunksperpage* setting specifies how many chunks are stored
|
||||||
|
* on any page and the *pagedelta* setting determines how many
|
||||||
|
* pages are allocated in one go. Pages are never freed, so they
|
||||||
|
* can be re-used without re-allocation.
|
||||||
|
*
|
||||||
|
* \note
|
||||||
|
* This is a template class with explicit instantiation. If the class
|
||||||
|
* is used with a new data type a new explicit instantiation may need
|
||||||
|
* to be added at the end of the file ``src/my_pool_chunk.cpp`` to
|
||||||
|
* avoid symbol lookup errors. */
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
MyPoolChunk = templated class for storing chunks of datums in pages
|
||||||
|
chunks can be returned to pool for reuse
|
||||||
|
chunks come in nbin different fixed sizes so can reuse
|
||||||
|
replaces many small mallocs with a few large mallocs
|
||||||
|
pages are never freed, so can reuse w/out reallocs
|
||||||
|
usage:
|
||||||
|
continuously get() and put() chunks as needed
|
||||||
|
NOTE: could add a clear() if retain info on mapping of pages to bins
|
||||||
|
inputs:
|
||||||
|
template T = one datum, e.g. int, double, struct
|
||||||
|
minchunk = min # of datums in one chunk, def = 1
|
||||||
|
maxchunk = max # of datums in one chunk, def = 1
|
||||||
|
nbin = # of bins between minchunk and maxchunk
|
||||||
|
chunkperpage = # of chunks in one page, def = 1024
|
||||||
|
pagedelta = # of pages to allocate at a time, def = 1
|
||||||
|
methods:
|
||||||
|
T *get(index) = return ptr/index to unused chunk of size maxchunk
|
||||||
|
T *get(N,index) = return ptr/index to unused chunk of size N
|
||||||
|
minchunk <= N <= maxchunk required
|
||||||
|
put(index) = return indexed chunk to pool (same index returned by get)
|
||||||
|
int size() = return total size of allocated pages in bytes
|
||||||
|
public variables:
|
||||||
|
ndatum = total # of stored datums
|
||||||
|
nchunk = total # of stored chunks
|
||||||
|
size = total size of all allocated pages in daums
|
||||||
|
errorflag = flag for various error conditions
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/** Create a class instance and set memory pool parameters */
|
||||||
|
template <class T>
|
||||||
|
MyPoolChunk<T>::MyPoolChunk(int user_minchunk, int user_maxchunk, int user_nbin,
|
||||||
|
int user_chunkperpage, int user_pagedelta) {
|
||||||
|
minchunk = user_minchunk;
|
||||||
|
maxchunk = user_maxchunk;
|
||||||
|
nbin = user_nbin;
|
||||||
|
chunkperpage = user_chunkperpage;
|
||||||
|
pagedelta = user_pagedelta;
|
||||||
|
|
||||||
|
errorflag = 0;
|
||||||
|
if (minchunk <= 0 || minchunk > maxchunk) errorflag = 1;
|
||||||
|
if (user_nbin <= 0 || chunkperpage <= 0 || pagedelta <= 0) errorflag = 1;
|
||||||
|
|
||||||
|
freehead = new int[nbin];
|
||||||
|
chunksize = new int[nbin];
|
||||||
|
if (!freehead || !chunksize) errorflag = 1;
|
||||||
|
if (errorflag) return;
|
||||||
|
|
||||||
|
// insure nbin*binsize spans minchunk to maxchunk inclusive
|
||||||
|
|
||||||
|
binsize = (maxchunk-minchunk+1) / nbin;
|
||||||
|
if (minchunk + nbin*binsize <= maxchunk) binsize++;
|
||||||
|
|
||||||
|
freelist = nullptr;
|
||||||
|
for (int ibin = 0; ibin < nbin; ibin++) {
|
||||||
|
freehead[ibin] = -1;
|
||||||
|
chunksize[ibin] = minchunk + (ibin+1)*binsize - 1;
|
||||||
|
if (chunksize[ibin] > maxchunk) chunksize[ibin] = maxchunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
ndatum = nchunk = 0;
|
||||||
|
pages = nullptr;
|
||||||
|
whichbin = nullptr;
|
||||||
|
npage = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Destroy class instance and free all allocated memory */
|
||||||
|
template <class T>
|
||||||
|
MyPoolChunk<T>::~MyPoolChunk() {
|
||||||
|
delete [] freehead;
|
||||||
|
delete [] chunksize;
|
||||||
|
if (npage) {
|
||||||
|
free(freelist);
|
||||||
|
for (int i = 0; i < npage; i++) free(pages[i]);
|
||||||
|
free(pages);
|
||||||
|
free(whichbin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return pointer/index of unused chunk of size maxchunk
|
||||||
|
*
|
||||||
|
* \param index Index of chunk in memory pool
|
||||||
|
* \return Pointer to requested chunk of storage */
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
T *MyPoolChunk<T>::get(int &index) {
|
||||||
|
int ibin = nbin-1;
|
||||||
|
if (freehead[ibin] < 0) {
|
||||||
|
allocate(ibin);
|
||||||
|
if (errorflag) return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ndatum += maxchunk;
|
||||||
|
nchunk++;
|
||||||
|
index = freehead[ibin];
|
||||||
|
int ipage = index/chunkperpage;
|
||||||
|
int ientry = index % chunkperpage;
|
||||||
|
freehead[ibin] = freelist[index];
|
||||||
|
return &pages[ipage][ientry*chunksize[ibin]];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return pointer/index of unused chunk of size N
|
||||||
|
*
|
||||||
|
* \param n Size of chunk
|
||||||
|
* \param index Index of chunk in memory pool
|
||||||
|
* \return Pointer to requested chunk of storage */
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
T *MyPoolChunk<T>::get(int n, int &index) {
|
||||||
|
if (n < minchunk || n > maxchunk) {
|
||||||
|
errorflag = 3;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ibin = (n-minchunk) / binsize;
|
||||||
|
if (freehead[ibin] < 0) {
|
||||||
|
allocate(ibin);
|
||||||
|
if (errorflag) return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ndatum += n;
|
||||||
|
nchunk++;
|
||||||
|
index = freehead[ibin];
|
||||||
|
int ipage = index/chunkperpage;
|
||||||
|
int ientry = index % chunkperpage;
|
||||||
|
freehead[ibin] = freelist[index];
|
||||||
|
return &pages[ipage][ientry*chunksize[ibin]];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Put indexed chunk back into memory pool via free list
|
||||||
|
*/
|
||||||
|
// index = -1 if no allocated chunk
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void MyPoolChunk<T>::put(int index) {
|
||||||
|
if (index < 0) return;
|
||||||
|
int ipage = index/chunkperpage;
|
||||||
|
int ibin = whichbin[ipage];
|
||||||
|
nchunk--;
|
||||||
|
ndatum -= chunksize[ibin];
|
||||||
|
freelist[index] = freehead[ibin];
|
||||||
|
freehead[ibin] = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void MyPoolChunk<T>::allocate(int ibin) {
|
||||||
|
int oldpage = npage;
|
||||||
|
npage += pagedelta;
|
||||||
|
freelist = (int *) realloc(freelist,npage*chunkperpage*sizeof(int));
|
||||||
|
pages = (T **) realloc(pages,npage*sizeof(T *));
|
||||||
|
whichbin = (int *) realloc(whichbin,npage*sizeof(int));
|
||||||
|
if (!freelist || !pages) {
|
||||||
|
errorflag = 2;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// allocate pages with appropriate chunksize for ibin
|
||||||
|
|
||||||
|
for (int i = oldpage; i < npage; i++) {
|
||||||
|
whichbin[i] = ibin;
|
||||||
|
#if defined(LAMMPS_MEMALIGN)
|
||||||
|
void *ptr;
|
||||||
|
if (posix_memalign(&ptr, LAMMPS_MEMALIGN,
|
||||||
|
chunkperpage*chunksize[ibin]*sizeof(T)))
|
||||||
|
errorflag = 2;
|
||||||
|
pages[i] = (T *) ptr;
|
||||||
|
#else
|
||||||
|
pages[i] = (T *) malloc(chunkperpage*chunksize[ibin]*sizeof(T));
|
||||||
|
size += chunkperpage*chunksize[ibin];
|
||||||
|
if (!pages[i]) errorflag = 2;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset free list for unused chunks on new pages
|
||||||
|
|
||||||
|
freehead[ibin] = oldpage*chunkperpage;
|
||||||
|
for (int i = freehead[ibin]; i < npage*chunkperpage; i++) freelist[i] = i+1;
|
||||||
|
freelist[npage*chunkperpage-1] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return total size of allocated pages
|
||||||
|
*
|
||||||
|
* \return total storage used in bytes */
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
double MyPoolChunk<T>::size() const {
|
||||||
|
double bytes = npage*chunkperpage*sizeof(int);
|
||||||
|
bytes += npage*sizeof(T *);
|
||||||
|
bytes += npage*sizeof(int);
|
||||||
|
for (int i=0; i < npage; ++i)
|
||||||
|
bytes += chunkperpage*chunksize[i]*sizeof(T);
|
||||||
|
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// explicit instantiations
|
||||||
|
|
||||||
|
namespace LAMMPS_NS {
|
||||||
|
template class MyPoolChunk<int>;
|
||||||
|
template class MyPoolChunk<double>;
|
||||||
|
}
|
||||||
@ -9,46 +9,11 @@
|
|||||||
the GNU General Public License.
|
the GNU General Public License.
|
||||||
|
|
||||||
See the README file in the top-level LAMMPS directory.
|
See the README file in the top-level LAMMPS directory.
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
|
||||||
MyPoolChunk = templated class for storing chunks of datums in pages
|
|
||||||
chunks can be returned to pool for reuse
|
|
||||||
chunks come in nbin different fixed sizes so can reuse
|
|
||||||
replaces many small mallocs with a few large mallocs
|
|
||||||
pages are never freed, so can reuse w/out reallocs
|
|
||||||
usage:
|
|
||||||
continuously get() and put() chunks as needed
|
|
||||||
NOTE: could add a clear() if retain info on mapping of pages to bins
|
|
||||||
inputs:
|
|
||||||
template T = one datum, e.g. int, double, struct
|
|
||||||
minchunk = min # of datums in one chunk, def = 1
|
|
||||||
maxchunk = max # of datums in one chunk, def = 1
|
|
||||||
nbin = # of bins between minchunk and maxchunk
|
|
||||||
chunkperpage = # of chunks in one page, def = 1024
|
|
||||||
pagedelta = # of pages to allocate at a time, def = 1
|
|
||||||
methods:
|
|
||||||
T *get(index) = return ptr/index to unused chunk of size maxchunk
|
|
||||||
T *get(N,index) = return ptr/index to unused chunk of size N
|
|
||||||
minchunk <= N <= maxchunk required
|
|
||||||
put(index) = return indexed chunk to pool (same index returned by get)
|
|
||||||
int size() = return total size of allocated pages in bytes
|
|
||||||
public variables:
|
|
||||||
ndatum = total # of stored datums
|
|
||||||
nchunk = total # of stored chunks
|
|
||||||
size = total size of all allocated pages in daums
|
|
||||||
errorflag = flag for various error conditions
|
|
||||||
------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
#ifndef LAMMPS_MY_POOL_CHUNK_H
|
#ifndef LAMMPS_MY_POOL_CHUNK_H
|
||||||
#define LAMMPS_MY_POOL_CHUNK_H
|
#define LAMMPS_MY_POOL_CHUNK_H
|
||||||
|
|
||||||
#if defined(LMP_USER_INTEL) && !defined(LAMMPS_MEMALIGN) && !defined(_WIN32)
|
|
||||||
#define LAMMPS_MEMALIGN 64
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
namespace LAMMPS_NS {
|
namespace LAMMPS_NS {
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
@ -56,113 +21,36 @@ class MyPoolChunk {
|
|||||||
public:
|
public:
|
||||||
int ndatum; // total # of stored datums
|
int ndatum; // total # of stored datums
|
||||||
int nchunk; // total # of stored chunks
|
int nchunk; // total # of stored chunks
|
||||||
int size; // total size of all allocated pages in datums
|
|
||||||
int errorflag; // flag > 1 if error has occurred
|
|
||||||
// 1 = invalid inputs
|
|
||||||
// 2 = memory allocation error
|
|
||||||
// 3 = chunk size exceeded maxchunk
|
|
||||||
|
|
||||||
MyPoolChunk(int user_minchunk = 1, int user_maxchunk = 1, int user_nbin = 1,
|
MyPoolChunk(int user_minchunk = 1, int user_maxchunk = 1, int user_nbin = 1,
|
||||||
int user_chunkperpage = 1024, int user_pagedelta = 1) {
|
int user_chunkperpage = 1024, int user_pagedelta = 1);
|
||||||
minchunk = user_minchunk;
|
|
||||||
maxchunk = user_maxchunk;
|
|
||||||
nbin = user_nbin;
|
|
||||||
chunkperpage = user_chunkperpage;
|
|
||||||
pagedelta = user_pagedelta;
|
|
||||||
|
|
||||||
errorflag = 0;
|
|
||||||
if (minchunk <= 0 || minchunk > maxchunk) errorflag = 1;
|
|
||||||
if (user_nbin <= 0 || chunkperpage <= 0 || pagedelta <= 0) errorflag = 1;
|
|
||||||
|
|
||||||
freehead = new int[nbin];
|
|
||||||
chunksize = new int[nbin];
|
|
||||||
if (!freehead || !chunksize) errorflag = 1;
|
|
||||||
if (errorflag) return;
|
|
||||||
|
|
||||||
// insure nbin*binsize spans minchunk to maxchunk inclusive
|
|
||||||
|
|
||||||
binsize = (maxchunk-minchunk+1) / nbin;
|
|
||||||
if (minchunk + nbin*binsize <= maxchunk) binsize++;
|
|
||||||
|
|
||||||
freelist = NULL;
|
|
||||||
for (int ibin = 0; ibin < nbin; ibin++) {
|
|
||||||
freehead[ibin] = -1;
|
|
||||||
chunksize[ibin] = minchunk + (ibin+1)*binsize - 1;
|
|
||||||
if (chunksize[ibin] > maxchunk) chunksize[ibin] = maxchunk;
|
|
||||||
}
|
|
||||||
|
|
||||||
ndatum = nchunk = size = 0;
|
|
||||||
pages = NULL;
|
|
||||||
whichbin = NULL;
|
|
||||||
npage = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// free all allocated memory
|
// free all allocated memory
|
||||||
|
|
||||||
~MyPoolChunk() {
|
~MyPoolChunk();
|
||||||
delete [] freehead;
|
|
||||||
delete [] chunksize;
|
|
||||||
if (npage) {
|
|
||||||
free(freelist);
|
|
||||||
for (int i = 0; i < npage; i++) free(pages[i]);
|
|
||||||
free(pages);
|
|
||||||
free(whichbin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// return pointer/index of unused chunk of size maxchunk
|
// return pointer/index of unused chunk of size maxchunk
|
||||||
|
|
||||||
T *get(int &index) {
|
T *get(int &index);
|
||||||
int ibin = nbin-1;
|
|
||||||
if (freehead[ibin] < 0) {
|
|
||||||
allocate(ibin);
|
|
||||||
if (errorflag) return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ndatum += maxchunk;
|
|
||||||
nchunk++;
|
|
||||||
index = freehead[ibin];
|
|
||||||
int ipage = index/chunkperpage;
|
|
||||||
int ientry = index % chunkperpage;
|
|
||||||
freehead[ibin] = freelist[index];
|
|
||||||
return &pages[ipage][ientry*chunksize[ibin]];
|
|
||||||
}
|
|
||||||
|
|
||||||
// return pointer/index of unused chunk of size N
|
// return pointer/index of unused chunk of size N
|
||||||
|
|
||||||
T *get(int n, int &index) {
|
T *get(int n, int &index);
|
||||||
if (n < minchunk || n > maxchunk) {
|
|
||||||
errorflag = 3;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ibin = (n-minchunk) / binsize;
|
|
||||||
if (freehead[ibin] < 0) {
|
|
||||||
allocate(ibin);
|
|
||||||
if (errorflag) return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ndatum += n;
|
|
||||||
nchunk++;
|
|
||||||
index = freehead[ibin];
|
|
||||||
int ipage = index/chunkperpage;
|
|
||||||
int ientry = index % chunkperpage;
|
|
||||||
freehead[ibin] = freelist[index];
|
|
||||||
return &pages[ipage][ientry*chunksize[ibin]];
|
|
||||||
}
|
|
||||||
|
|
||||||
// return indexed chunk to pool via free list
|
// return indexed chunk to pool via free list
|
||||||
// index = -1 if no allocated chunk
|
// index = -1 if no allocated chunk
|
||||||
|
|
||||||
void put(int index) {
|
void put(int index);
|
||||||
if (index < 0) return;
|
|
||||||
int ipage = index/chunkperpage;
|
// total memory used in bytes
|
||||||
int ibin = whichbin[ipage];
|
|
||||||
nchunk--;
|
double size() const;
|
||||||
ndatum -= chunksize[ibin];
|
|
||||||
freelist[index] = freehead[ibin];
|
/** Return error status
|
||||||
freehead[ibin] = index;
|
*
|
||||||
}
|
* \return 0 if no error, 1 if invalid input, 2 if malloc() failed, 3 if chunk > maxchunk */
|
||||||
|
|
||||||
|
int status() const { return errorflag; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int minchunk; // min # of datums per chunk
|
int minchunk; // min # of datums per chunk
|
||||||
@ -171,6 +59,10 @@ class MyPoolChunk {
|
|||||||
int chunkperpage; // # of chunks on every page, regardless of which bin
|
int chunkperpage; // # of chunks on every page, regardless of which bin
|
||||||
int pagedelta; // # of pages to allocate at once, default = 1
|
int pagedelta; // # of pages to allocate at once, default = 1
|
||||||
int binsize; // delta in chunk sizes between adjacent bins
|
int binsize; // delta in chunk sizes between adjacent bins
|
||||||
|
int errorflag; // flag > 0 if error has occurred
|
||||||
|
// 1 = invalid inputs
|
||||||
|
// 2 = memory allocation error
|
||||||
|
// 3 = chunk size exceeded maxchunk
|
||||||
|
|
||||||
T **pages; // list of allocated pages
|
T **pages; // list of allocated pages
|
||||||
int *whichbin; // which bin each page belongs to
|
int *whichbin; // which bin each page belongs to
|
||||||
@ -179,42 +71,7 @@ class MyPoolChunk {
|
|||||||
int *freehead; // index of first unused chunk in each bin
|
int *freehead; // index of first unused chunk in each bin
|
||||||
int *chunksize; // size of chunks in each bin
|
int *chunksize; // size of chunks in each bin
|
||||||
|
|
||||||
void allocate(int ibin) {
|
void allocate(int ibin);
|
||||||
int oldpage = npage;
|
|
||||||
npage += pagedelta;
|
|
||||||
freelist = (int *) realloc(freelist,npage*chunkperpage*sizeof(int));
|
|
||||||
pages = (T **) realloc(pages,npage*sizeof(T *));
|
|
||||||
whichbin = (int *) realloc(whichbin,npage*sizeof(int));
|
|
||||||
if (!freelist || !pages) {
|
|
||||||
errorflag = 2;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// allocate pages with appropriate chunksize for ibin
|
|
||||||
|
|
||||||
for (int i = oldpage; i < npage; i++) {
|
|
||||||
whichbin[i] = ibin;
|
|
||||||
#if defined(LAMMPS_MEMALIGN)
|
|
||||||
void *ptr;
|
|
||||||
if (posix_memalign(&ptr, LAMMPS_MEMALIGN,
|
|
||||||
chunkperpage*chunksize[ibin]*sizeof(T)))
|
|
||||||
errorflag = 2;
|
|
||||||
pages[i] = (T *) ptr;
|
|
||||||
#else
|
|
||||||
pages[i] = (T *) malloc(chunkperpage*chunksize[ibin]*sizeof(T));
|
|
||||||
size += chunkperpage*chunksize[ibin];
|
|
||||||
if (!pages[i]) errorflag = 2;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// reset free list for unused chunks on new pages
|
|
||||||
|
|
||||||
freehead[ibin] = oldpage*chunkperpage;
|
|
||||||
for (int i = freehead[ibin]; i < npage*chunkperpage; i++) freelist[i] = i+1;
|
|
||||||
freelist[npage*chunkperpage-1] = -1;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user