From 299640ce5f6499e07c5799f48897ac5a77e72c54 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Wed, 18 Jul 2012 01:26:34 -0600 Subject: Persistant multi-threading works perfectly. It uses the forever-blocking variation of the Bu::SynchroQueue dequeue to maximize efficiency. --- src/explicitsimulation.cpp | 64 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 13 deletions(-) (limited to 'src/explicitsimulation.cpp') diff --git a/src/explicitsimulation.cpp b/src/explicitsimulation.cpp index 6a9356b..98df0b0 100644 --- a/src/explicitsimulation.cpp +++ b/src/explicitsimulation.cpp @@ -15,11 +15,11 @@ Genetic::ExplicitSimulation::ExplicitSimulation( Genetic::Operator *pOper, Genetic::FitnessFunction *pFunc, int iThreads, int iPopSize, float fKeep, float fRandom, bool bKeepBest ) : pOper( pOper ), - //pFunc( pFunc ), iPopSize( iPopSize ), fKeep( fKeep ), fRandom( fRandom ), - bKeepBest( bKeepBest ) + bKeepBest( bKeepBest ), + bRunning( true ) { for( int j = 0; j < iPopSize; j++ ) { @@ -35,6 +35,8 @@ Genetic::ExplicitSimulation::ExplicitSimulation( Genetic::Operator *pOper, lProcessor.append( new Processor( *this, pFunc->clone(), qWork, iId++ ) ); + for( ProcessorList::iterator i = lProcessor.begin(); i; i++ ) + (*i)->start(); updateFitness(); } @@ -43,8 +45,9 @@ Genetic::ExplicitSimulation::~ExplicitSimulation() { delete pOper; - for( ProcessorList::iterator i = lProcessor.begin(); i; i++ ) - (*i)->setRunning( false ); + setRunning( false ); + + qWork.unblockAll(); for( ProcessorList::iterator i = lProcessor.begin(); i; i++ ) { (*i)->join(); @@ -139,12 +142,21 @@ void Genetic::ExplicitSimulation::updateFitness() dMinFitness = -1.0; dTotalFitness = 0.0; mFitness.unlock(); + cWorkDone.lock(); + iWorkDone = xPop.getSize(); + cWorkDone.unlock(); for( Population::iterator i = xPop.begin(); i; i++ ) { - if( hFitness.has( i.getKey() ) ) + mFitness.lock(); + bool bHas = hFitness.has( i.getKey() ); + mFitness.unlock(); + if( bHas ) { setFitness( i.getKey(), hFitness.get( i.getKey() ) ); + cWorkDone.lock(); + iWorkDone--; + cWorkDone.unlock(); } else { @@ -152,11 +164,16 @@ void Genetic::ExplicitSimulation::updateFitness() } } - for( ProcessorList::iterator i = lProcessor.begin(); i; i++ ) - (*i)->start(); + cWorkDone.lock(); + if( iWorkDone == 0 ) + { + cWorkDone.unlock(); + return; + } - for( ProcessorList::iterator i = lProcessor.begin(); i; i++ ) - (*i)->join(); + while( iWorkDone > 0 ) + cWorkDone.wait(); + cWorkDone.unlock(); } void Genetic::ExplicitSimulation::setFitness( Genetic::PhenotypeId id, @@ -166,7 +183,6 @@ void Genetic::ExplicitSimulation::setFitness( Genetic::PhenotypeId id, if( dFitness < 0.0 ) dFitness = 0.0; -// sio << id << ": " << dFitness << sio.nl; hFitness.insert( id, dFitness ); dTotalFitness += dFitness; @@ -186,6 +202,28 @@ void Genetic::ExplicitSimulation::setFitness( Genetic::PhenotypeId id, } } +void Genetic::ExplicitSimulation::workDone() +{ + cWorkDone.lock(); + iWorkDone--; + + if( iWorkDone == 0 ) + cWorkDone.signal(); + cWorkDone.unlock(); +} + +void Genetic::ExplicitSimulation::setRunning( bool b ) +{ + Bu::MutexLocker ml( mRunning ); + bRunning = b; +} + +bool Genetic::ExplicitSimulation::isRunning() +{ + Bu::MutexLocker ml( mRunning ); + return bRunning; +} + Genetic::ExplicitSimulation::Processor::Processor( Genetic::ExplicitSimulation &rSim, Genetic::FitnessFunction *pFunc, @@ -205,15 +243,15 @@ Genetic::ExplicitSimulation::Processor::~Processor() void Genetic::ExplicitSimulation::Processor::run() { - bRunning = true; - while( bRunning && !rqWork.isEmpty() ) + while( rSim.isRunning() ) { - Genetic::Phenotype *pPhen = rqWork.dequeue( 0, 250000 ); + Genetic::Phenotype *pPhen = rqWork.dequeue( true ); if( pPhen == NULL ) continue; double dFitness = (*pFunc)( pPhen ); rSim.setFitness( pPhen->getId(), dFitness ); + rSim.workDone(); } } -- cgit v1.2.3