Revision: 7910
http://playerstage.svn.sourceforge.net/playerstage/?rev=7910&view=rev
Author: rtv
Date: 2009-06-26 05:55:33 +0000 (Fri, 26 Jun 2009)
Log Message:
-----------
new multithread model seems to perform pretty well
Modified Paths:
--------------
code/stage/trunk/examples/ctrl/CMakeLists.txt
code/stage/trunk/libstage/model.cc
code/stage/trunk/libstage/model_laser.cc
code/stage/trunk/libstage/stage.hh
code/stage/trunk/libstage/world.cc
code/stage/trunk/worlds/benchmark/cave.world
code/stage/trunk/worlds/fasr.world
Modified: code/stage/trunk/examples/ctrl/CMakeLists.txt
===================================================================
--- code/stage/trunk/examples/ctrl/CMakeLists.txt 2009-06-26 01:48:30 UTC
(rev 7909)
+++ code/stage/trunk/examples/ctrl/CMakeLists.txt 2009-06-26 05:55:33 UTC
(rev 7910)
@@ -5,7 +5,7 @@
sink
source
wander
- rasterize
+# rasterize
)
# need plaer's wavefront planning library for this one
Modified: code/stage/trunk/libstage/model.cc
===================================================================
--- code/stage/trunk/libstage/model.cc 2009-06-26 01:48:30 UTC (rev 7909)
+++ code/stage/trunk/libstage/model.cc 2009-06-26 05:55:33 UTC (rev 7910)
@@ -706,19 +706,20 @@
// this->world->sim_time, this->token, this->subs );
// if we're drawing current and a power pack has been installed
+
PowerPack* pp = FindPowerPack();
if( pp && ( watts > 0 ))
- {
- // consume energy stored in the power pack
- stg_joules_t consumed = watts * (world->interval_sim * 1e-6);
- pp->Dissipate( consumed, GetGlobalPose() );
- }
-
+ {
+ // consume energy stored in the power pack
+ stg_joules_t consumed = watts * (world->interval_sim * 1e-6);
+ pp->Dissipate( consumed, GetGlobalPose() );
+ }
+
last_update = world->sim_time;
if( log_state )
- world->Log( this );
+ world->Log( this );
}
void Model::CallUpdateCallbacks( void )
Modified: code/stage/trunk/libstage/model_laser.cc
===================================================================
--- code/stage/trunk/libstage/model_laser.cc 2009-06-26 01:48:30 UTC (rev
7909)
+++ code/stage/trunk/libstage/model_laser.cc 2009-06-26 05:55:33 UTC (rev
7910)
@@ -168,10 +168,11 @@
void ModelLaser::Update( void )
{
+ // removed UnMapFromRoot() optimization - though neat, it breaks
+ // thread-safety by messing with the Cell contents - rtv.
+
assert( samples.size() == sample_count );
-
- UnMapFromRoot(); // Don't raytrace self
-
+
double bearing( -fov/2.0 );
// make the first and last rays exactly at the extremes of the FOV
double sample_incr( fov / MAX(sample_count-1,1) );
@@ -222,8 +223,9 @@
}
}
- MapFromRoot();
-
+ // removed MapFromRoot() optimization - though neat, it breaks
+ // thread-safety by messing with the Cell contents - rtv
+
Model::Update();
}
Modified: code/stage/trunk/libstage/stage.hh
===================================================================
--- code/stage/trunk/libstage/stage.hh 2009-06-26 01:48:30 UTC (rev 7909)
+++ code/stage/trunk/libstage/stage.hh 2009-06-26 05:55:33 UTC (rev 7910)
@@ -952,7 +952,7 @@
bool show_clock; ///< iff true, print the sim time on stdout
unsigned int show_clock_interval; ///< updates between clock xoutputs
GMutex* thread_mutex; ///< protect the worker thread management stuff
- GThreadPool *threadpool; ///<worker threads for updating some sensor
models in parallel
+ //GThreadPool *threadpool; ///<worker threads for updating some sensor
models in parallel
int total_subs; ///< the total number of subscriptions to all models
GList* velocity_list; ///< Models with non-zero velocity and should have
their poses updated
Modified: code/stage/trunk/libstage/world.cc
===================================================================
--- code/stage/trunk/libstage/world.cc 2009-06-26 01:48:30 UTC (rev 7909)
+++ code/stage/trunk/libstage/world.cc 2009-06-26 05:55:33 UTC (rev 7910)
@@ -14,22 +14,36 @@
interval_real 100
interval_sim 100
resolution 0.02
+ threads 0
@endverbatim
@par Details
+
- interval_sim <int>\n
- the length of each simulation update cycle in milliseconds.
+ The length of each simulation update cycle in milliseconds.
+
- interval_real <int>\n
- the amount of real-world (wall-clock) time the siulator will attempt to
spend on each simulation cycle.
+ The amount of real-world (wall-clock) time the siulator will
+ attempt to spend on each simulation cycle.
+
- resolution <float>\n
- The resolution (in meters) of the underlying bitmap model. Larger values
speed up raytracing at the expense of fidelity in collision detection and
sensing.
+ The resolution (in meters) of the underlying bitmap model. Larger
+ values speed up raytracing at the expense of fidelity in collision
+ detection and sensing.
+ - threads <int>\n
+ The number of worker threads to spawn. Some models can be updated
+ in parallel (e.g. laser, ranger), and running 2 or more threads
+ here may make the simulation run faster, depending on the number
+ of CPU cores available and the worldfile. As a guideline, use one
+ thread per core if you have high-resolution models, e.g. a laser
+ with hundreds of samples
+
@par More examples
The Stage source distribution contains several example world files in
<tt>(stage src)/worlds</tt> along with the worldfile properties
described on the manual page for each model type.
-
*/
#ifndef _GNU_SOURCE
@@ -76,7 +90,6 @@
show_clock( false ),
show_clock_interval( 100 ), // 10 simulated seconds using defaults
thread_mutex( g_mutex_new() ),
- //threadpool( NULL ),
total_subs( 0 ),
velocity_list( NULL ),
worker_threads( 0 ),
@@ -163,30 +176,31 @@
//puts( "worker waiting for start signal" );
g_cond_wait( world->threads_start_cond, world->thread_mutex );
g_mutex_unlock( world->thread_mutex );
+ //puts( "worker thread awakes" );
- //puts( "worker thread awakes" );
-
- //r loop over the list of rentrant models for this thread
+ // loop over the list of rentrant models for this thread
FOR_EACH( it, world->reentrant_update_lists[thread_instance] )
- {
- Model* mod = *it;
- //printf( "thread %d updating model %s (%p)\n",
thread_instance, mod->Token(), mod );
- mod->UpdateIfDue();
- mod->CallUpdateCallbacks();
- }
+ {
+ Model* mod = *it;
+ //printf( "thread %d updating model %s (%p)\n",
thread_instance, mod->Token(), mod );
+
+ // TODO - some of this (Model::Update()) is not thread
safe!
+ if( mod->UpdateDue() )
+ mod->Update();
+ }
// done working, so increment the counter. If this was the last
// thread to finish working, signal the main thread, which is
// blocked waiting for this to happen
g_mutex_lock( world->thread_mutex );
if( --world->threads_working == 0 )
- {
- //puts( "last worker signalling main thread" );
- g_cond_signal( world->threads_done_cond );
- }
- //g_mutex_unlock( world->thread_mutex );
- }
-
+ {
+ //puts( "last worker signalling main thread" );
+ g_cond_signal( world->threads_done_cond );
+ }
+ // keep lock going round the loop
+ }
+
return NULL;
}
@@ -341,7 +355,7 @@
NULL );
}
- printf( "[threadpool %u]", worker_threads );
+ printf( "[threads %u]", worker_threads );
}
}
@@ -529,7 +543,10 @@
// then update all models on the update lists
FOR_EACH( it, nonreentrant_update_list )
- (*it)->UpdateIfDue();
+ {
+ //printf( "thread MAIN updating model %s\n", (*it)->Token() );
+ (*it)->UpdateIfDue();
+ }
//printf( "nonre list length %d\n", g_list_length( nonreentrant_update_list
) );
//printf( "re list length %d\n", g_list_length( reentrant_update_list ) );
@@ -555,13 +572,15 @@
g_cond_wait( threads_done_cond, thread_mutex );
}
g_mutex_unlock( thread_mutex );
-
//puts( "main thread awakes" );
- // TODO - move this back here!
- // now call all the callbacks - ignores dueness, but not a big deal
- //FOR_EACH( it, reentrant_update_list )
- //(*it)->CallUpdateCallbacks();
+ // TODO: allow threadsafe callbacks to be called in worker
+ // threads
+
+ // now call all the callbacks in each list
+ FOR_EACH( it1, reentrant_update_lists )
+ FOR_EACH( it2, *it1 )
+ (*it2)->CallUpdateCallbacks();
}
if( show_clock && ((this->updates % show_clock_interval) == 0) )
@@ -660,7 +679,6 @@
RaytraceResult sample( r.origin, r.range );
// our global position in (floating point) cell coordinates
- //stg_point_t glob( r.origin.x * ppm, r.origin.y * ppm );
double globx( r.origin.x * ppm );
double globy( r.origin.y * ppm );
@@ -709,7 +727,7 @@
// Stage spends up to 95% of its time in this loop! It would be
// neater with more function calls encapsulating things, but even
- // inline calls have a noticeable (2-3%) effect on performance
+ // inline calls have a noticeable (2-3%) effect on performance.
while( n > 0 ) // while we are still not at the ray end
{
Region* reg( GetSuperRegionCached( GETSREG(globx), GETSREG(globy) )
@@ -727,7 +745,7 @@
Cell* c( ®->cells[ cx + cy * REGIONWIDTH ] );
assert(c); // should be good: we know the region contains
objects
-
+
// while within the bounds of this region and while some ray
remains
// we'll tweak the cell pointer directly to move around
quickly
while( (cx>=0) && (cx<REGIONWIDTH) &&
@@ -1106,7 +1124,7 @@
{
LogEntry( sim_time, mod);
- printf( "log entry count %d\n", LogEntry::Count() );
+ printf( "log entry count %u\n", (unsigned int)LogEntry::Count() );
//LogEntry::Print();
}
Modified: code/stage/trunk/worlds/benchmark/cave.world
===================================================================
--- code/stage/trunk/worlds/benchmark/cave.world 2009-06-26 01:48:30 UTC
(rev 7909)
+++ code/stage/trunk/worlds/benchmark/cave.world 2009-06-26 05:55:33 UTC
(rev 7910)
@@ -11,8 +11,6 @@
interval_real 0 # real-time interval between simulation updates in
milliseconds
paused 1
-threadpool 0
-
# configure the GUI window
window
(
@@ -57,6 +55,8 @@
define goldrob rob( color "gold" )
define darkredrob rob( color "DarkRed" )
+# 100 robots in assorted colors
+
redrob( pose [-5.285 4.915 0 150.459] )
redrob( pose [-4.458 5.785 0 -85.494] )
redrob( pose [-5.518 4.157 0 -10.236] )
Modified: code/stage/trunk/worlds/fasr.world
===================================================================
--- code/stage/trunk/worlds/fasr.world 2009-06-26 01:48:30 UTC (rev 7909)
+++ code/stage/trunk/worlds/fasr.world 2009-06-26 05:55:33 UTC (rev 7910)
@@ -11,12 +11,12 @@
paused 1
# time to pause (in GUI mode) or quit (in headless mode) the simulation
-quit_time 3600 # 1 hour of simulated time
+quit_time 360 # 1 hour of simulated time
resolution 0.02
# threads may speed things up here depending on available CPU cores & workload
-# threads 3
+threads 0
# configure the GUI window
window
@@ -133,7 +133,7 @@
define autorob pioneer2dx
(
- sicklaser( samples 32 range_max 5 laser_return 2 watts 30 )
+ sicklaser( samples 320 range_max 5 laser_return 2 watts 30 )
ctrl "fasr"
joules 100000
joules_capacity 400000
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit