- Noticed a major slowdown with the fairly-recently implemented allocation strategy scheme for irrArray (About 5 times slowdown) mainly due to the switch statement in the time critical section. So I re-implemented it as a static template-based system and now the speed is a lot more acceptable.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@2939 dfc29bdd-3216-0410-991c-e03cc46cb475
master
monstrobishi 2009-11-28 06:24:37 +00:00
parent a8ccdb1194
commit 1ea180d6be
6 changed files with 67 additions and 52 deletions

View File

@ -213,10 +213,7 @@ namespace scene
//! holds a associative list of named quaternions //! holds a associative list of named quaternions
struct SMD3QuaternionTagList struct SMD3QuaternionTagList
{ {
SMD3QuaternionTagList () SMD3QuaternionTagList () {}
{
Container.setAllocStrategy ( core::ALLOC_STRATEGY_SAFE );
}
// construct copy constructor // construct copy constructor
SMD3QuaternionTagList( const SMD3QuaternionTagList & copyMe ) SMD3QuaternionTagList( const SMD3QuaternionTagList & copyMe )
@ -273,7 +270,7 @@ namespace scene
} }
private: private:
core::array < SMD3QuaternionTag > Container; core::array < SMD3QuaternionTag, core::irrAllocator<SMD3QuaternionTag>, core::irrAllocStrategySafe > Container;
}; };

View File

@ -77,7 +77,7 @@ namespace quake3
// some useful typedefs // some useful typedefs
typedef core::array< core::stringc > tStringList; typedef core::array< core::stringc > tStringList;
typedef core::array< video::ITexture* > tTexArray; typedef core::array< video::ITexture*, core::irrAllocator<video::ITexture*>, core::irrAllocStrategySafe > tTexArray;
// string helper.. TODO: move to generic files // string helper.. TODO: move to generic files
inline s16 isEqual ( const core::stringc &string, u32 &pos, const c8 *list[], u16 listSize ) inline s16 isEqual ( const core::stringc &string, u32 &pos, const c8 *list[], u16 listSize )
@ -573,7 +573,7 @@ namespace quake3
// string database. "a" = "Hello", "b" = "1234.6" // string database. "a" = "Hello", "b" = "1234.6"
struct SVarGroup struct SVarGroup
{ {
SVarGroup () { Variable.setAllocStrategy ( core::ALLOC_STRATEGY_SAFE ); } SVarGroup () {}
virtual ~SVarGroup () {} virtual ~SVarGroup () {}
u32 isDefined ( const c8 * name, const c8 * content = 0 ) const u32 isDefined ( const c8 * name, const c8 * content = 0 ) const
@ -617,19 +617,16 @@ namespace quake3
} }
core::array < SVariable > Variable; core::array < SVariable, core::irrAllocator<SVariable>, core::irrAllocStrategySafe > Variable;
}; };
//! holding a group a variable //! holding a group a variable
struct SVarGroupList: public IReferenceCounted struct SVarGroupList: public IReferenceCounted
{ {
SVarGroupList () SVarGroupList () {}
{
VariableGroup.setAllocStrategy ( core::ALLOC_STRATEGY_SAFE );
}
virtual ~SVarGroupList () {} virtual ~SVarGroupList () {}
core::array < SVarGroup > VariableGroup; core::array < SVarGroup, core::irrAllocator<SVarGroup>, core::irrAllocStrategySafe > VariableGroup;
}; };

View File

@ -109,11 +109,62 @@ public:
#endif #endif
//! defines an allocation strategy //! defines an allocation strategy
enum eAllocStrategy enum EAllocStrategy
{ {
ALLOC_STRATEGY_SAFE = 0, ALLOC_STRATEGY_SAFE = 0,
ALLOC_STRATEGY_DOUBLE = 1, ALLOC_STRATEGY_DOUBLE = 1,
ALLOC_STRATEGY_SQRT = 2 ALLOC_STRATEGY_SQ = 2
};
class irrAllocStrategyDouble
{
public:
//! Returns the new size of the buffer based on the current size.
const u32 getNewSize(const u32 oldSize) const
{
return oldSize + oldSize + 1;
}
//! Returns the EAllocStrategy enum of this allocation strategist.
EAllocStrategy getAllocationStrategy() const
{
return ALLOC_STRATEGY_DOUBLE;
}
};
class irrAllocStrategySafe
{
public:
//! Returns the new size of the buffer based on the current size.
const u32 getNewSize(const u32 oldSize) const
{
return oldSize + 1;
}
//! Returns the EAllocStrategy enum of this allocation strategist.
EAllocStrategy getAllocationStrategy() const
{
return ALLOC_STRATEGY_SAFE;
}
};
class irrAllocStrategySq
{
public:
//! Returns the new size of the buffer based on the current size.
const u32 getNewSize(const u32 oldSize) const
{
return oldSize * oldSize + 1;
}
//! Returns the EAllocStrategy enum of this allocation strategist.
EAllocStrategy getAllocationStrategy() const
{
return ALLOC_STRATEGY_SQ;
}
}; };

View File

@ -17,7 +17,7 @@ namespace core
//! Self reallocating template array (like stl vector) with additional features. //! Self reallocating template array (like stl vector) with additional features.
/** Some features are: Heap sorting, binary search methods, easier debugging. /** Some features are: Heap sorting, binary search methods, easier debugging.
*/ */
template <class T, typename TAlloc = irrAllocator<T> > template <class T, typename TAlloc = irrAllocator<T>, typename TAllocStrategy = irrAllocStrategyDouble >
class array class array
{ {
@ -25,8 +25,7 @@ public:
//! Default constructor for empty array. //! Default constructor for empty array.
array() array()
: data(0), allocated(0), used(0), : data(0), allocated(0), used(0), free_when_destroyed(true), is_sorted(true)
strategy(ALLOC_STRATEGY_DOUBLE), free_when_destroyed(true), is_sorted(true)
{ {
} }
@ -34,8 +33,7 @@ public:
//! Constructs an array and allocates an initial chunk of memory. //! Constructs an array and allocates an initial chunk of memory.
/** \param start_count Amount of elements to pre-allocate. */ /** \param start_count Amount of elements to pre-allocate. */
array(u32 start_count) array(u32 start_count)
: data(0), allocated(0), used(0), : data(0), allocated(0), used(0), free_when_destroyed(true), is_sorted(true)
strategy(ALLOC_STRATEGY_DOUBLE), free_when_destroyed(true), is_sorted(true)
{ {
reallocate(start_count); reallocate(start_count);
} }
@ -85,17 +83,6 @@ public:
allocator.deallocate(old_data); //delete [] old_data; allocator.deallocate(old_data); //delete [] old_data;
} }
//! set a new allocation strategy
/** if the maximum size of the array is unknown, you can define how big the
allocation should happen.
\param newStrategy New strategy to apply to this array. */
void setAllocStrategy ( eAllocStrategy newStrategy = ALLOC_STRATEGY_DOUBLE )
{
strategy = newStrategy;
}
//! Adds an element at back of array. //! Adds an element at back of array.
/** If the array is too small to add this new element it is made bigger. /** If the array is too small to add this new element it is made bigger.
\param element: Element to add at the back of the array. */ \param element: Element to add at the back of the array. */
@ -134,18 +121,7 @@ public:
const T e(element); const T e(element);
// increase data block // increase data block
u32 newAlloc; const u32 newAlloc = allocatorStrategy.getNewSize(used);
switch ( strategy )
{
case ALLOC_STRATEGY_DOUBLE:
newAlloc = used + 1 + (allocated < 500 ?
(allocated < 5 ? 5 : used) : used >> 2);
break;
default:
case ALLOC_STRATEGY_SAFE:
newAlloc = used + 1;
break;
}
reallocate( newAlloc); reallocate( newAlloc);
// move array content and construct new element // move array content and construct new element
@ -249,8 +225,6 @@ public:
//! Assignment operator //! Assignment operator
void operator=(const array<T>& other) void operator=(const array<T>& other)
{ {
strategy = other.strategy;
if (data) if (data)
clear(); clear();
@ -568,7 +542,7 @@ private:
u32 allocated; u32 allocated;
u32 used; u32 used;
TAlloc allocator; TAlloc allocator;
eAllocStrategy strategy:4; TAllocStrategy allocatorStrategy;
bool free_when_destroyed:1; bool free_when_destroyed:1;
bool is_sorted:1; bool is_sorted:1;
}; };

View File

@ -147,7 +147,6 @@ void CQuake3ShaderSceneNode::loadTextures( io::IFileSystem * fileSystem )
} }
// clear all stages and prefill empty // clear all stages and prefill empty
Q3Texture.setAllocStrategy ( core::ALLOC_STRATEGY_SAFE );
Q3Texture.clear(); Q3Texture.clear();
for ( i = 0; i != Shader->VarGroup->VariableGroup.size(); ++i ) for ( i = 0; i != Shader->VarGroup->VariableGroup.size(); ++i )
{ {

View File

@ -59,10 +59,7 @@ private:
SQ3Texture () : SQ3Texture () :
TextureIndex ( 0 ), TextureIndex ( 0 ),
TextureFrequency(0.f), TextureFrequency(0.f),
TextureAddressMode( video::ETC_REPEAT ) TextureAddressMode( video::ETC_REPEAT ) {}
{
Texture.setAllocStrategy ( core::ALLOC_STRATEGY_SAFE );
}
quake3::tTexArray Texture; quake3::tTexArray Texture;
@ -71,7 +68,7 @@ private:
video::E_TEXTURE_CLAMP TextureAddressMode; // Wrapping/Clamping video::E_TEXTURE_CLAMP TextureAddressMode; // Wrapping/Clamping
}; };
core::array< SQ3Texture > Q3Texture; core::array< SQ3Texture, core::irrAllocator<SQ3Texture>, core::irrAllocStrategySafe > Q3Texture;
void loadTextures ( io::IFileSystem * fileSystem ); void loadTextures ( io::IFileSystem * fileSystem );
void addBuffer ( scene::SMeshBufferLightMap * buffer ); void addBuffer ( scene::SMeshBufferLightMap * buffer );