From: <axl...@us...> - 2010-11-12 20:53:41
|
Revision: 759 http://hgengine.svn.sourceforge.net/hgengine/?rev=759&view=rev Author: axlecrusher Date: 2010-11-12 20:53:35 +0000 (Fri, 12 Nov 2010) Log Message: ----------- Make vertices use memory manager. This is so that vertices are more CPU cache friendly. Vertex data will be 16 byte aligned and will be mostly contagious. If a CPU cache line is 64 bytes, then reading a vertex into cache should bring in the following 3 vertices into the cache. Modified Paths: -------------- Mercury2/src/DataTypes/MTriangle.cpp Mercury2/src/MercuryMemory.h Mercury2/src/MercuryVertex.cpp Mercury2/src/MercuryVertex.h Modified: Mercury2/src/DataTypes/MTriangle.cpp =================================================================== --- Mercury2/src/DataTypes/MTriangle.cpp 2010-11-12 16:59:05 UTC (rev 758) +++ Mercury2/src/DataTypes/MTriangle.cpp 2010-11-12 20:53:35 UTC (rev 759) @@ -3,10 +3,11 @@ #include <stdio.h> MTriangle::MTriangle() -{ - m_verts[0] = 0; - m_verts[1] = 0; - m_verts[2] = 0; +{/* + m_verts[0] = MercuryVertex(0,0,0,0); + m_verts[1] = MercuryVertex(0,0,0,0); + m_verts[2] = MercuryVertex(0,0,0,0); + */ } MTriangle::MTriangle(const MTriangle& t) Modified: Mercury2/src/MercuryMemory.h =================================================================== --- Mercury2/src/MercuryMemory.h 2010-11-12 16:59:05 UTC (rev 758) +++ Mercury2/src/MercuryMemory.h 2010-11-12 20:53:35 UTC (rev 759) @@ -14,40 +14,70 @@ free ride into the CPU cache. */ public: MercuryMemory(const uint32_t rows) + :m_free(NULL),m_rows(rows) { MSemaphoreLock lock(&m_lock); - m_data.Allocate(rows,16); - - for (unsigned int i = 0; i < rows;i++) - m_free.push_back( m_data.Buffer()+i ); + AllocateMoreSpace(m_rows); } -// void Init(); -// static MercuryMatrixMemory& GetInstance(); T* Allocate() { - T* m = (T*)0x0; - MSemaphoreLock lock(&m_lock); - if ( m_free.begin() != m_free.end() ) + T* m = NULL; + MemoryUnit* mu = NULL; { - m = m_free.front(); - m_free.pop_front(); + //keep really short lock + MSemaphoreLock lock(&m_lock); + if ( m_free == NULL ) AllocateMoreSpace(m_rows); + mu = m_free; + m_free=m_free->prev; + if (m_free!=mu->prev) { char* a = NULL; *a=0; } //wtf happened here!?!?! FREE CHANGED DURING OUR LOCK } -// if (m==0x0) *m=*m; //crash if could not allocate + m = mu->mem; + delete mu; + if (m==NULL) { char* a = NULL; *a=0; } //no memory allocated?? return m; } void Free(T* m) { MSemaphoreLock lock(&m_lock); - m_free.push_back(m); + for (MemoryUnit* mu=m_free;mu!=NULL;mu=mu->prev) + { + //probably could some some sorting here to get contigious free and used memory + //if free memory is alwasy given out in order, then used memory will also be in order + if (m==mu->mem) { char* a=NULL;*a=0;} //WTF DOUBLE FREE + } + m_free = new MemoryUnit(m_free,m); } private: -// static const unsigned int rows = 1024; //1024 matrices * 64bytes each = 64kb - AlignedBuffer<T> m_data; - std::list< T* > m_free; + struct MemoryUnit + { + MemoryUnit(MemoryUnit* p, T* m) + :mem(m),prev(p) + { +// if (p!=NULL) p->next = this; + } + T* mem; + MemoryUnit* prev; + }; + + void AllocateMoreSpace(const uint32_t rows) + { + AlignedBuffer<T>* d = new AlignedBuffer<T>(); + d->Allocate(rows,16); + + for (unsigned int i = 0; i < rows;i++) + m_free = new MemoryUnit(m_free,(d->Buffer())+i); + + m_data.push_back(d); + } + + std::list< AlignedBuffer<T>* > m_data; + MemoryUnit* m_free; + MSemaphore m_lock; + unsigned long m_rows; }; #endif Modified: Mercury2/src/MercuryVertex.cpp =================================================================== --- Mercury2/src/MercuryVertex.cpp 2010-11-12 16:59:05 UTC (rev 758) +++ Mercury2/src/MercuryVertex.cpp 2010-11-12 20:53:35 UTC (rev 759) @@ -2,13 +2,27 @@ #include <MercuryUtil.h> #include <MercuryMath.h> +float* MercuryVertex::GetFloatMem() +{ + if (m_memory==NULL) + { + m_memory = new MercuryMemory< FloatRow >(1024); + } +// return new FloatRow; + return (float*)m_memory->Allocate(); +} + MercuryVertex::MercuryVertex() + :m_xyzw(NULL) { + m_xyzw = GetFloatMem(); m_xyzw[0] = m_xyzw[1] = m_xyzw[2] = m_xyzw[3] = 0; } MercuryVertex::MercuryVertex( float ix, float iy, float iz, float iw ) + :m_xyzw(NULL) { + m_xyzw = GetFloatMem(); m_xyzw[0] = ix; m_xyzw[1] = iy; m_xyzw[2] = iz; @@ -16,31 +30,46 @@ } MercuryVertex::MercuryVertex( const float* in3f, float f ) + :m_xyzw(NULL) { + m_xyzw = GetFloatMem(); for (unsigned int i = 0; i < 3; ++i) (*this)[i] = in3f[i]; m_xyzw[3] = f; } MercuryVertex::MercuryVertex( const float* in4f ) + :m_xyzw(NULL) { + m_xyzw = GetFloatMem(); for (unsigned int i = 0; i < 4; ++i) (*this)[i] = in4f[i]; } MercuryVertex::MercuryVertex( const MercuryVertex& v) + :m_xyzw(NULL) { + m_xyzw = GetFloatMem(); for (unsigned int i = 0; i < 4; ++i) (*this)[i] = v[i]; } MercuryVertex::MercuryVertex( const MercuryVertex& v, float w) + :m_xyzw(NULL) { + m_xyzw = GetFloatMem(); for (unsigned int i = 0; i < 3; ++i) (*this)[i] = v[i]; m_xyzw[3] = w; } +MercuryVertex::~MercuryVertex() +{ + if (m_xyzw!=NULL) + m_memory->Free((FloatRow*)m_xyzw); + m_xyzw = NULL; +} + void MercuryVertex::NormalizeSelf() { float imag = 1.0f/Length(); @@ -104,7 +133,7 @@ { //XXX should this use all 4 components? MercuryVertex r; - MMCrossProduct( m_xyzw, p.m_xyzw, r.m_xyzw ); + MMCrossProduct( ToFloatRow(), p.ToFloatRow(), r.ToFloatRow() ); return r; } @@ -141,6 +170,7 @@ return MercuryVertex(x,y,z); } +MercuryMemory< FloatRow >* MercuryVertex::m_memory = NULL; /**************************************************************************** * Copyright (C) 2009 by Joshua Allen * Modified: Mercury2/src/MercuryVertex.h =================================================================== --- Mercury2/src/MercuryVertex.h 2010-11-12 16:59:05 UTC (rev 758) +++ Mercury2/src/MercuryVertex.h 2010-11-12 20:53:35 UTC (rev 759) @@ -10,6 +10,7 @@ #define __inline__ inline #endif +#include <MercuryMemory.h> class MercuryVertex { @@ -20,14 +21,17 @@ MercuryVertex( const float* in4f ); MercuryVertex( const MercuryVertex& v); MercuryVertex( const MercuryVertex& v, float w); + virtual ~MercuryVertex(); ///Direct conversion to float* __inline__ operator float* () { return m_xyzw; } ///Direct conversion to const float* __inline__ operator const float* () const { return m_xyzw; } +// __inline__ float& operator[](unsigned int i) { return m_xyzw[i]; } +// __inline__ const float& operator[](unsigned int i) const { return m_xyzw[i]; } - inline FloatRow& ToFloatRow() { return m_xyzw; } - inline const FloatRow& ToFloatRow() const { return m_xyzw; } + inline FloatRow& ToFloatRow() { return (FloatRow&)*m_xyzw; } + inline const FloatRow& ToFloatRow() const { return (const FloatRow&)*m_xyzw; } inline float GetX() const { return m_xyzw[0]; } inline float GetY() const { return m_xyzw[1]; } @@ -77,6 +81,8 @@ bool operator==(const float f) const; inline bool operator!=(const float f) const { return !(*this == f); } + inline const MercuryVertex& operator=(const MercuryVertex& p) { Copy4f(m_xyzw,p.m_xyzw);return *this; } + ///Obtain the cross product (*this) x p MercuryVertex CrossProduct(const MercuryVertex& p) const; @@ -90,7 +96,11 @@ static MercuryVertex CreateFromString(const MString& s); // float m_xyzw[3]; - FloatRow m_xyzw; +// FloatRow m_xyzw; + private: + float* m_xyzw; + static MercuryMemory< FloatRow >* m_memory; + static float* GetFloatMem(); }; typedef MercuryVertex MercuryVector; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |