|
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.
|