Browse files

optmized FOR_EACH macro to assume container is not modified. other sm…

…all speed tweaks
  • Loading branch information...
1 parent 568444e commit 0a5ba1d713646fb6af0f7572cc9a74e6e60161fa @rtv committed Nov 29, 2010
Showing with 120 additions and 71 deletions.
  1. +17 −49 libstage/block.cc
  2. +22 −4 libstage/model.cc
  3. +52 −9 libstage/region.cc
  4. +3 −0 libstage/region.hh
  5. +13 −2 libstage/stage.hh
  6. +4 −4 libstage/world.cc
  7. +7 −0 todo.txt
  8. +2 −3 worlds/fasr2.world
View
66 libstage/block.cc
@@ -205,51 +205,19 @@ void Block::UnMap()
mapped = false;
}
+#include <algorithm>
+#include <functional>
+
inline void Block::RemoveFromCellArray( CellPtrVec *cells )
{
- FOR_EACH( it, *cells )
- {
- Cell* cell = *it;
-
- size_t len = cell->blocks.size();
- if( len )
- {
-#if 0 // Use conventional STL style
-
- // this special-case test is faster for worlds with simple models,
- // which are the ones we want to be really fast. It's a small
- // extra cost for worlds with several models in each cell. It
- // gives a 5% overall speed increase in fasr.world.
-
- if( (cell->blocks.size() == 1) &&
- (cell->blocks[0] == this) ) // special but common case
- {
- cell->blocks.clear(); // cheap
- }
- else // the general but relatively expensive case
- {
- EraseAll( this, cell->blocks );
- }
-#else // attempt faster removal loop
- // O(n) * low constant array element removal
- // this C-style pointer work looks to be very slightly faster than the STL way
- Block **start = &cell->blocks[0]; // start of array
- Block **r = &cell->blocks[0]; // read from here
- Block **w = &cell->blocks[0]; // write to here
-
- while( r < start + len ) // scan down array, skipping 'this'
- {
- if( *r != this )
- *w++ = *r;
- r++;
- }
- cell->blocks.resize( w-start );
-#endif
- }
-
- --cell->region->count;
- --cell->region->superregion->count;
- }
+ // FOR_EACH( it, *cells )
+ // (*it)->RemoveBlock(this);
+
+ // this is equivalent to the above commented code - experimenting
+ // with optimizations
+ std::for_each( cells->begin(),
+ cells->end(),
+ std::bind2nd( std::mem_fun(&Cell::RemoveBlock), this));
//printf( "%d %d %.2f\n", count1, countmore, ((float)count1)/float(countmore));
}
@@ -263,7 +231,7 @@ void Block::SwitchToTestedCells()
// 2. find the set of cells in candidate but not rendered and insert
// them
-
+
// .. and see if that is faster than the current method
//printf( "rendered_cells %lu\n", rendered_cells->size() );
@@ -319,14 +287,14 @@ void Block::GenerateCandidateCells()
mpts.resize( pts.size() );
- for( unsigned int i=0; i<pt_count; i++ )
+ for( unsigned int i=0; i<pt_count; ++i )
mpts[i] = BlockPointToModelMeters( pts[i] );
}
gpts.clear();
mod->LocalToPixels( mpts, gpts );
- for( unsigned int i=0; i<pt_count; i++ )
+ for( unsigned int i=0; i<pt_count; ++i )
mod->world->ForEachCellInLine( gpts[i],
gpts[(i+1)%pt_count],
*candidate_cells );
@@ -361,7 +329,7 @@ void Block::Rasterize( uint8_t* data,
// this, width, height, scalex, scaley, offsetx, offsety );
const unsigned int pt_count = pts.size();
- for( unsigned int i=0; i<pt_count; i++ )
+ for( unsigned int i=0; i<pt_count; ++i )
{
// convert points from local to model coords
point_t mpt1 = BlockPointToModelMeters( pts[i] );
@@ -397,7 +365,7 @@ void Block::Rasterize( uint8_t* data,
double dydx = (double) (b.y - a.y) / (double) (b.x - a.x);
double y = a.y;
- for(int x=a.x; x<=b.x; x++)
+ for(int x=a.x; x<=b.x; ++x)
{
if( steep )
{
@@ -488,7 +456,7 @@ void Block::Load( Worldfile* wf, int entity )
const unsigned int pt_count = wf->ReadInt( entity, "points", 0);
char key[128];
- for( unsigned int p=0; p<pt_count; p++ )
+ for( unsigned int p=0; p<pt_count; ++p )
{
snprintf(key, sizeof(key), "point[%d]", p );
View
26 libstage/model.cc
@@ -949,6 +949,24 @@ Model* Model::ConditionalMove( const Pose& newpose )
return hitmod;
}
+void Model::ConditionalMove_calc( const Pose& newpose )
+{
+ const Pose startpose( pose );
+ pose = newpose; // do the move provisionally - we might undo it below
+
+ this->hitmod = NULL;
+ this->hitmod = TestCollisionTree();
+
+ if( hitmod )
+ pose = startpose; // move failed - put me back where I started
+}
+
+void Model::ConditionalMove_commit()
+{
+ CommitTestedPose(); //recursively commit to blocks to the new pose
+ world->dirty = true; // need redraw
+}
+
void Model::UpdatePose( void )
{
@@ -1189,8 +1207,8 @@ void Model::RasterVis::Visualize( Model* mod, Camera* cam )
mod->PushColor( 0,0,0,0.5 );
glPolygonMode( GL_FRONT, GL_FILL );
- for( unsigned int y=0; y<height; y++ )
- for( unsigned int x=0; x<width; x++ )
+ for( unsigned int y=0; y<height; ++y )
+ for( unsigned int x=0; x<width; ++x )
{
// printf( "[%u %u] ", x, y );
if( data[ x + y*width ] )
@@ -1201,8 +1219,8 @@ void Model::RasterVis::Visualize( Model* mod, Camera* cam )
mod->PushColor( 0,0,0,1 );
glPolygonMode( GL_FRONT, GL_LINE );
- for( unsigned int y=0; y<height; y++ )
- for( unsigned int x=0; x<width; x++ )
+ for( unsigned int y=0; y<height; ++y )
+ for( unsigned int x=0; x<width; ++x )
{
if( data[ x + y*width ] )
glRectf( x, y, x+1, y+1 );
View
61 libstage/region.cc
@@ -51,8 +51,8 @@ void SuperRegion::DrawOccupancy()
char buf[32];
glColor3f( 0,1,0 );
- for( int y=0; y<SUPERREGIONWIDTH; y++ )
- for( int x=0; x<SUPERREGIONWIDTH; x++ )
+ for( int y=0; y<SUPERREGIONWIDTH; ++y )
+ for( int x=0; x<SUPERREGIONWIDTH; ++x )
{
if( r->count ) // region contains some occupied cells
{
@@ -65,8 +65,8 @@ void SuperRegion::DrawOccupancy()
Gl::draw_string( x<<RBITS, y<<RBITS, 0, buf );
// draw a rectangle around each occupied cell
- for( int p=0; p<REGIONWIDTH; p++ )
- for( int q=0; q<REGIONWIDTH; q++ )
+ for( int p=0; p<REGIONWIDTH; ++p )
+ for( int q=0; q<REGIONWIDTH; ++q )
if( r->cells[p+(q*REGIONWIDTH)].blocks.size() )
{
GLfloat xx = p+(x<<RBITS);
@@ -105,7 +105,7 @@ void SuperRegion::DrawOccupancy()
glEnd();
}
- r++; // next region quickly
+ ++r; // next region quickly
}
snprintf( buf, 15, "%lu", count );
@@ -162,12 +162,12 @@ void SuperRegion::DrawVoxels()
Region* r = GetRegion( 0, 0);
- for( int y=0; y<SUPERREGIONWIDTH; y++ )
- for( int x=0; x<SUPERREGIONWIDTH; x++ )
+ for( int y=0; y<SUPERREGIONWIDTH; ++y )
+ for( int x=0; x<SUPERREGIONWIDTH; ++x )
{
if( r->count )
- for( int p=0; p<REGIONWIDTH; p++ )
- for( int q=0; q<REGIONWIDTH; q++ )
+ for( int p=0; p<REGIONWIDTH; ++p )
+ for( int q=0; q<REGIONWIDTH; ++q )
{
Cell* c = (Cell*)&r->cells[p+(q*REGIONWIDTH)];
@@ -203,3 +203,46 @@ void SuperRegion::DrawVoxels()
}
glPopMatrix();
}
+
+
+void Cell::RemoveBlock( Block* b )
+{
+ size_t len = blocks.size();
+ if( len )
+ {
+#if 0 // Use conventional STL style
+
+ // this special-case test is faster for worlds with simple models,
+ // which are the ones we want to be really fast. It's a small
+ // extra cost for worlds with several models in each cell. It
+ // gives a 5% overall speed increase in fasr.world.
+
+ if( (blocks.size() == 1) &&
+ (blocks[0] == b) ) // special but common case
+ {
+ blocks.clear(); // cheap
+ }
+ else // the general but relatively expensive case
+ {
+ EraseAll( b, blocks );
+ }
+#else // attempt faster removal loop
+ // O(n) * low constant array element removal
+ // this C-style pointer work looks to be very slightly faster than the STL way
+ Block **start = &blocks[0]; // start of array
+ Block **r = &blocks[0]; // read from here
+ Block **w = &blocks[0]; // write to here
+
+ while( r < start + len ) // scan down array, skipping 'this'
+ {
+ if( *r != b )
+ *w++ = *r;
+ ++r;
+ }
+ blocks.resize( w-start );
+#endif
+ }
+
+ --region->count;
+ --region->superregion->count;
+}
View
3 libstage/region.hh
@@ -49,6 +49,9 @@ namespace Stg
: region( reg ),
blocks()
{ /* nothing to do */ }
+
+ void RemoveBlock( Block* b );
+
}; // class Cell
class Region
View
15 libstage/stage.hh
@@ -605,9 +605,13 @@ namespace Stg
Model* finder,
const void* arg );
- // STL container iterator macros
+ // STL container iterator macros - __typeof is a gcc extension, so
+ // this could be an issue one day.
#define VAR(V,init) __typeof(init) V=(init)
-#define FOR_EACH(I,C) for(VAR(I,(C).begin());I!=(C).end();I++)
+//#define FOR_EACH(I,C) for(VAR(I,(C).begin());I!=(C).end();++I) NOTE:
+// this version assumes the container is not modified in the loop,
+// which I think is true everywhere it is used in Stage
+#define FOR_EACH(I,C) for(VAR(I,(C).begin()),ite=(C).end();(I)!=ite;++(I))
/** wrapper for Erase-Remove method of removing all instances of thing from container */
template <class T, class C>
@@ -1716,6 +1720,9 @@ namespace Stg
std::vector<Option*> drawOptions;
const std::vector<Option*>& getOptions() const { return drawOptions; }
+ /** EXP */
+ Model* hitmod; // thing we hit in a (parallel) collision test
+
protected:
/** If true, the model always has at least one subscription, so
@@ -2102,6 +2109,10 @@ namespace Stg
virtual void UpdateCharge();
Model* ConditionalMove( const Pose& newpose );
+
+ // EXP
+ void ConditionalMove_calc( const Pose& newpose );
+ void ConditionalMove_commit( void );
meters_t ModelHeight() const;
View
8 libstage/world.cc
@@ -410,7 +410,7 @@ void World::Load( const std::string& worldfile_path )
//printf( "worker threads %d\n", worker_threads );
// kick off the threads
- for( unsigned int t=0; t<worker_threads; t++ )
+ for( unsigned int t=0; t<worker_threads; ++t )
{
// a little configuration for each thread can't be a local
// stack var, since it's accssed in the threads
@@ -432,7 +432,7 @@ void World::Load( const std::string& worldfile_path )
}
// Iterate through entitys and create objects of the appropriate type
- for( int entity = 1; entity < wf->GetEntityCount(); entity++ )
+ for( int entity = 1; entity < wf->GetEntityCount(); ++entity )
{
const char *typestr = (char*)wf->GetEntityType(entity);
@@ -711,7 +711,7 @@ void World::Raytrace( const Pose &gpose, // global pose
Pose raypose = gpose;
const double starta = fov/2.0 - raypose.a;
- for( uint32_t s=0; s < sample_count; s++ )
+ for( uint32_t s=0; s < sample_count; ++s )
{
raypose.a = (s * fov / (double)(sample_count-1)) - starta;
samples[s] = Raytrace( raypose, range, func, model, arg, ztest );
@@ -1082,7 +1082,7 @@ void World::ForEachCellInLine( const point_int_t& start,
void World::Extend( point3_t pt )
{
- extent.x.min = std::min( extent.x.min, pt.x);
+ extent.x.min = std::min( extent.x.min, pt.x );
extent.x.max = std::max( extent.x.max, pt.x );
extent.y.min = std::min( extent.y.min, pt.y );
extent.y.max = std::max( extent.y.max, pt.y );
View
7 todo.txt
@@ -22,6 +22,13 @@ MBA 17.3
MBA 23.1 (1 thread)
MBA 19.3 (2 threads)
+Timing test FASR2.world 200 seconds
+-----------------------
+MBPi7 2 threads
+
+32.3 (user 45.4) old FOR_EACH
+30.0 (user 44.2) new FOR_EACH
+
** 3.2.0 RELEASE *
- visualizer option state in worldfile
View
5 worlds/fasr2.world
@@ -12,12 +12,11 @@ paused 0
# time at which to pause (in GUI mode) or quit (in headless mode) the simulation
# quit_time 3600 # 1 hour of simulated time
-quit_time 1000
-
+quit_time 200
resolution 0.02
-threads 8
+threads 2
# configure the GUI window
window

0 comments on commit 0a5ba1d

Please sign in to comment.