From b12e7297d8418e0a373a3facd3098c86367b3499 Mon Sep 17 00:00:00 2001 From: kanschat Date: Mon, 17 Dec 2007 19:54:07 +0000 Subject: [PATCH] growing vector memory using same pool git-svn-id: https://svn.dealii.org/trunk@15603 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/lac/include/lac/pointer_matrix.h | 15 +- deal.II/lac/include/lac/vector_memory.h | 216 +++++++++++++++-------- deal.II/lac/source/vector_memory.cc | 72 +------- deal.II/lac/source/vector_memory.inst.in | 27 +++ 4 files changed, 175 insertions(+), 155 deletions(-) create mode 100644 deal.II/lac/source/vector_memory.inst.in diff --git a/deal.II/lac/include/lac/pointer_matrix.h b/deal.II/lac/include/lac/pointer_matrix.h index a2ca02167d..81df756b8a 100644 --- a/deal.II/lac/include/lac/pointer_matrix.h +++ b/deal.II/lac/include/lac/pointer_matrix.h @@ -269,8 +269,8 @@ class PointerMatrixAux : public PointerMatrixBase * If M is zero, no * matrix is stored. * - * If mem is zero, the - * VectorMemory::default_pool() + * If mem is zero, then + * GrowingVectorMemory * is used. */ PointerMatrixAux (VectorMemory* mem = 0, @@ -357,7 +357,7 @@ class PointerMatrixAux : public PointerMatrixBase /** * The backup memory if none was provided. */ - mutable PrimitiveVectorMemory my_memory; + mutable GrowingVectorMemory my_memory; /** * Object for getting the @@ -848,8 +848,7 @@ PointerMatrixAux::PointerMatrixAux ( : mem(mem, typeid(*this).name()), m(M, typeid(*this).name()) { - if (mem == 0) - mem = &VectorMemory::default_pool(); + if (mem == 0) mem = &my_memory; } @@ -860,8 +859,7 @@ PointerMatrixAux::PointerMatrixAux ( : mem(mem, name), m(0, name) { - if (mem == 0) - mem = &VectorMemory::default_pool(); + if (mem == 0) mem = &my_memory; } @@ -873,8 +871,7 @@ PointerMatrixAux::PointerMatrixAux ( : mem(mem, name), m(M, name) { - if (mem == 0) - mem = &VectorMemory::default_pool(); + if (mem == 0) mem = &my_memory; } diff --git a/deal.II/lac/include/lac/vector_memory.h b/deal.II/lac/include/lac/vector_memory.h index 0210ba93ce..7a7527ee5f 100644 --- a/deal.II/lac/include/lac/vector_memory.h +++ b/deal.II/lac/include/lac/vector_memory.h @@ -21,6 +21,7 @@ #include #include +#include DEAL_II_NAMESPACE_OPEN @@ -99,21 +100,6 @@ class VectorMemory : public Subscriptor */ virtual void free (const VECTOR * const) = 0; - /** - * Access the default memory - * space deal.II is offering for - * vectors of this kind. - * - * This function accesses static - * VectorMemory objects used by - * deal.II classes to allocate - * vectors. It is good practice - * to use these in your program - * as well, in order to optimize - * memory usage. - */ - static VectorMemory& default_pool(); - /** @addtogroup Exceptions * @{ */ @@ -127,15 +113,6 @@ class VectorMemory : public Subscriptor */ DeclException0(ExcNotAllocatedHere); - /** - * You tried to access the - * deal.II - * VectorMemory::default_pool(), - * but the vector class you are - * using is not a standard - * deal.II vector class. - */ - DeclException0(ExcNoDefaultMemoryForThisVectorClass); //@} }; @@ -214,6 +191,27 @@ class PrimitiveVectorMemory : public VectorMemory * other hand, it doesn't release once-allocated memory at the * earliest possible time and may therefore lead to an increased * overall memory consumption. + * + * All GrowingVectorMemory objects of the same vector type use the + * same memory Pool. Therefore, functions can create such a + * VectorMemory object whenever needed without preformance penalty. A + * drawback of this policy might be that vectors once allocated are + * only released at the end of the program run. Nebertheless, the + * since they are reused, this should be of no concern. Additionally, + * the destructor of the Pool warns about memory leaks. + * + * @note Instantiations for this class are provided for the types + * Vector and BlockVector with number types float, + * double, long double, @@>, + * @@> and @@>. In order to generate additional instances, it is + * sufficient to define the Pool variable somewhere by + * + * #include + * + * template GrowingVectorMemory::Pool + * GrowingVectorMemory::pool; + * * * @author Guido Kanschat, 1999, 2007 */ @@ -277,12 +275,6 @@ class GrowingVectorMemory : public VectorMemory */ unsigned int memory_consumption() const; - /** - * A flag controlling the logging - * of statistics at the end. - */ - bool log_statistics; - private: /** * Type to enter into the @@ -293,10 +285,35 @@ class GrowingVectorMemory : public VectorMemory */ typedef std::pair entry_type; + /** + * The class providing the actual + * storage for the memory pool. + * + * This is where the actual + * storage for GrowingVectorMemory + * is provided. Only one of these + * pools is used for each vector + * type, thus allocating all + * vectors from the same storage. + * + * @author Guido Kanschat, 2007 + */ + struct Pool + { +/// Standard constructor creating an empty pool + Pool(); +/// Destructor. Frees memory and warns about memory leaks + ~Pool(); +/// Create data vector; does nothing after first initialization + void initialize(const unsigned int size); +/// Pointer to the storage object + std::vector* data; + }; + /** * Array of allocated vectors. */ - std::vector pool; + static Pool pool; /** * Overall number of @@ -305,7 +322,20 @@ class GrowingVectorMemory : public VectorMemory * output at the end of an * object's lifetime. */ - unsigned int n_alloc; + unsigned int total_alloc; + /** + * Number of vectors currently + * allocated in this object; used + * for detecting memory leaks. + */ + unsigned int current_alloc; + + /** + * A flag controlling the logging + * of statistics by the + * destructor. + */ + bool log_statistics; /** * Mutex to synchronise access to @@ -320,75 +350,107 @@ class GrowingVectorMemory : public VectorMemory #ifndef DOXYGEN /* --------------------- inline functions ---------------------- */ - template -GrowingVectorMemory::GrowingVectorMemory (const unsigned int initial_size, - const bool log_statistics) +inline +GrowingVectorMemory::Pool::Pool() : - log_statistics(log_statistics), - pool(initial_size) + data(0) +{} + + + +template +inline +GrowingVectorMemory::Pool::~Pool() { - Threads::ThreadMutex::ScopedLock lock(mutex); - for (typename std::vector::iterator i=pool.begin(); - i != pool.end(); + // Nothing to do if memory was unused. + if (data == 0) return; + + // First, delete all remaining + // vectors. Actually, there should + // be none, if there is no memory + // leak + unsigned int n=0; + for (typename std::vector::iterator i=data->begin(); + i != data->end(); ++i) { - i->first = false; - i->second = new VECTOR; + if (i->first == true) + ++n; + delete i->second; } + delete data; +} + - // no vectors yet claimed - n_alloc = 0; +template +inline +void +GrowingVectorMemory::Pool::initialize(const unsigned int size) +{ + if (data == 0) + { + data = new std::vector(size); + + for (typename std::vector::iterator i= data->begin(); + i != data->end(); + ++i) + { + i->first = false; + i->second = new VECTOR; + } + } } +template +typename GrowingVectorMemory::Pool GrowingVectorMemory::pool; -template -GrowingVectorMemory::~GrowingVectorMemory() + +template +inline +GrowingVectorMemory::GrowingVectorMemory (const unsigned int initial_size, + const bool log_statistics) + + : + total_alloc(0), + current_alloc(0), + log_statistics(log_statistics) { Threads::ThreadMutex::ScopedLock lock(mutex); + pool.initialize(initial_size); +} - // deallocate all vectors and count - // number of vectors that is still - // claimed by other users - unsigned int n = 0; - for (typename std::vector::iterator i=pool.begin(); - i != pool.end(); - ++i) - { - if (i->first == true) - ++n; - delete i->second; - } + +template +inline +GrowingVectorMemory::~GrowingVectorMemory() +{ + AssertThrow(current_alloc == 0, + StandardExceptions::ExcMemoryLeak(current_alloc)); if (log_statistics) { deallog << "GrowingVectorMemory:Overall allocated vectors: " - << n_alloc << std::endl; + << total_alloc << std::endl; deallog << "GrowingVectorMemory:Maximum allocated vectors: " - << pool.size() << std::endl; + << pool.data->size() << std::endl; } - pool.clear (); - - // write out warning if memory leak - if (n!=0) - deallog << "GrowingVectorMemory:Vectors not deallocated: " - << n << ". Memory leak!" << std::endl; } template +inline VECTOR * GrowingVectorMemory::alloc () { Threads::ThreadMutex::ScopedLock lock(mutex); - ++n_alloc; - + ++total_alloc; + ++current_alloc; // see if there is a free vector // available in our list - for (typename std::vector::iterator i=pool.begin(); - i != pool.end(); - ++i) + for (typename std::vector::iterator i=pool.data->begin(); + i != pool.data->end(); ++i) { if (i->first == false) { @@ -400,7 +462,7 @@ GrowingVectorMemory::alloc () // no free vector found, so let's // just allocate a new one const entry_type t (true, new VECTOR); - pool.push_back(t); + pool.data->push_back(t); return t.second; } @@ -408,15 +470,18 @@ GrowingVectorMemory::alloc () template +inline void GrowingVectorMemory::free(const VECTOR* const v) { Threads::ThreadMutex::ScopedLock lock(mutex); - for (typename std::vector::iterator i=pool.begin();i != pool.end() ;++i) + for (typename std::vector::iterator i=pool.data->begin(); + i != pool.data->end(); ++i) { if (v == (i->second)) { i->first = false; + --current_alloc; return; } } @@ -426,14 +491,15 @@ GrowingVectorMemory::free(const VECTOR* const v) template +inline unsigned int GrowingVectorMemory::memory_consumption () const { unsigned int result = sizeof (*this); const typename std::vector::const_iterator - end = pool.end(); + end = pool.data->end(); for (typename std::vector::const_iterator - i = pool.begin(); i != end ; ++i) + i = pool.data->begin(); i != end ; ++i) result += sizeof (*i) + i->second->memory_consumption(); return result; diff --git a/deal.II/lac/source/vector_memory.cc b/deal.II/lac/source/vector_memory.cc index f47f12a2ac..e1a2abf67c 100644 --- a/deal.II/lac/source/vector_memory.cc +++ b/deal.II/lac/source/vector_memory.cc @@ -18,76 +18,6 @@ DEAL_II_NAMESPACE_OPEN - -namespace -{ - GrowingVectorMemory > default_pool_Vector_double(0, false); - GrowingVectorMemory > default_pool_Vector_float(0, false); - GrowingVectorMemory > default_pool_BlockVector_double(0, false); - GrowingVectorMemory > default_pool_BlockVector_float(0, false); - - - template - inline - VectorMemory* - default_pool_select() - { - Assert(false, typename VectorMemory::ExcNoDefaultMemoryForThisVectorClass()); - return 0; - } - - - template <> - inline - VectorMemory >* - default_pool_select >() - { - return &default_pool_Vector_double; - } - - - template <> - inline - VectorMemory >* - default_pool_select >() - { - return &default_pool_Vector_float; - } - - - - template <> - inline - VectorMemory >* - default_pool_select >() - { - return &default_pool_BlockVector_double; - } - - - template <> - inline - VectorMemory >* - default_pool_select >() - { - return &default_pool_BlockVector_float; - } - -} - - -template -VectorMemory& -VectorMemory::default_pool() -{ - return *default_pool_select(); -} - - -template class VectorMemory >; -template class VectorMemory >; -template class VectorMemory >; -template class VectorMemory >; - +#include "vector_memory.inst" DEAL_II_NAMESPACE_CLOSE diff --git a/deal.II/lac/source/vector_memory.inst.in b/deal.II/lac/source/vector_memory.inst.in new file mode 100644 index 0000000000..220711a78b --- /dev/null +++ b/deal.II/lac/source/vector_memory.inst.in @@ -0,0 +1,27 @@ +//--------------------------------------------------------------------------- +// $Id: vector.cc 15443 2007-11-05 03:43:52Z bangerth $ +// Version: $Name$ +// +// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//--------------------------------------------------------------------------- + + +for (SCALAR : REAL_SCALARS) + { + template class VectorMemory >; + template class GrowingVectorMemory >; +// template GrowingVectorMemory >::Pool +// GrowingVectorMemory >::pool; + + template class VectorMemory >; + template class GrowingVectorMemory >; +// template GrowingVectorMemory >::Pool +// GrowingVectorMemory >::pool; + } + -- 2.39.5