diff options
| author | Mike Buland <mike@xagasoft.com> | 2012-07-18 01:26:34 -0600 |
|---|---|---|
| committer | Mike Buland <mike@xagasoft.com> | 2012-07-18 01:26:34 -0600 |
| commit | 299640ce5f6499e07c5799f48897ac5a77e72c54 (patch) | |
| tree | 47b502fca70dc2fc8a48ae9b3ae813763e98c78e | |
| parent | a2679e3bc2f407fae6b97908aeebb215c6678ebc (diff) | |
| download | libgenetic-299640ce5f6499e07c5799f48897ac5a77e72c54.tar.gz libgenetic-299640ce5f6499e07c5799f48897ac5a77e72c54.tar.bz2 libgenetic-299640ce5f6499e07c5799f48897ac5a77e72c54.tar.xz libgenetic-299640ce5f6499e07c5799f48897ac5a77e72c54.zip | |
Persistant multi-threading works perfectly.
It uses the forever-blocking variation of the Bu::SynchroQueue dequeue
to maximize efficiency.
| -rw-r--r-- | src/explicitsimulation.cpp | 64 | ||||
| -rw-r--r-- | src/explicitsimulation.h | 10 | ||||
| -rw-r--r-- | src/tests/maxima/main.cpp | 2 |
3 files changed, 59 insertions, 17 deletions
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, | |||
| 15 | Genetic::FitnessFunction *pFunc, int iThreads, int iPopSize, | 15 | Genetic::FitnessFunction *pFunc, int iThreads, int iPopSize, |
| 16 | float fKeep, float fRandom, bool bKeepBest ) : | 16 | float fKeep, float fRandom, bool bKeepBest ) : |
| 17 | pOper( pOper ), | 17 | pOper( pOper ), |
| 18 | //pFunc( pFunc ), | ||
| 19 | iPopSize( iPopSize ), | 18 | iPopSize( iPopSize ), |
| 20 | fKeep( fKeep ), | 19 | fKeep( fKeep ), |
| 21 | fRandom( fRandom ), | 20 | fRandom( fRandom ), |
| 22 | bKeepBest( bKeepBest ) | 21 | bKeepBest( bKeepBest ), |
| 22 | bRunning( true ) | ||
| 23 | { | 23 | { |
| 24 | for( int j = 0; j < iPopSize; j++ ) | 24 | for( int j = 0; j < iPopSize; j++ ) |
| 25 | { | 25 | { |
| @@ -35,6 +35,8 @@ Genetic::ExplicitSimulation::ExplicitSimulation( Genetic::Operator *pOper, | |||
| 35 | lProcessor.append( | 35 | lProcessor.append( |
| 36 | new Processor( *this, pFunc->clone(), qWork, iId++ ) | 36 | new Processor( *this, pFunc->clone(), qWork, iId++ ) |
| 37 | ); | 37 | ); |
| 38 | for( ProcessorList::iterator i = lProcessor.begin(); i; i++ ) | ||
| 39 | (*i)->start(); | ||
| 38 | 40 | ||
| 39 | updateFitness(); | 41 | updateFitness(); |
| 40 | } | 42 | } |
| @@ -43,8 +45,9 @@ Genetic::ExplicitSimulation::~ExplicitSimulation() | |||
| 43 | { | 45 | { |
| 44 | delete pOper; | 46 | delete pOper; |
| 45 | 47 | ||
| 46 | for( ProcessorList::iterator i = lProcessor.begin(); i; i++ ) | 48 | setRunning( false ); |
| 47 | (*i)->setRunning( false ); | 49 | |
| 50 | qWork.unblockAll(); | ||
| 48 | for( ProcessorList::iterator i = lProcessor.begin(); i; i++ ) | 51 | for( ProcessorList::iterator i = lProcessor.begin(); i; i++ ) |
| 49 | { | 52 | { |
| 50 | (*i)->join(); | 53 | (*i)->join(); |
| @@ -139,12 +142,21 @@ void Genetic::ExplicitSimulation::updateFitness() | |||
| 139 | dMinFitness = -1.0; | 142 | dMinFitness = -1.0; |
| 140 | dTotalFitness = 0.0; | 143 | dTotalFitness = 0.0; |
| 141 | mFitness.unlock(); | 144 | mFitness.unlock(); |
| 145 | cWorkDone.lock(); | ||
| 146 | iWorkDone = xPop.getSize(); | ||
| 147 | cWorkDone.unlock(); | ||
| 142 | 148 | ||
| 143 | for( Population::iterator i = xPop.begin(); i; i++ ) | 149 | for( Population::iterator i = xPop.begin(); i; i++ ) |
| 144 | { | 150 | { |
| 145 | if( hFitness.has( i.getKey() ) ) | 151 | mFitness.lock(); |
| 152 | bool bHas = hFitness.has( i.getKey() ); | ||
| 153 | mFitness.unlock(); | ||
| 154 | if( bHas ) | ||
| 146 | { | 155 | { |
| 147 | setFitness( i.getKey(), hFitness.get( i.getKey() ) ); | 156 | setFitness( i.getKey(), hFitness.get( i.getKey() ) ); |
| 157 | cWorkDone.lock(); | ||
| 158 | iWorkDone--; | ||
| 159 | cWorkDone.unlock(); | ||
| 148 | } | 160 | } |
| 149 | else | 161 | else |
| 150 | { | 162 | { |
| @@ -152,11 +164,16 @@ void Genetic::ExplicitSimulation::updateFitness() | |||
| 152 | } | 164 | } |
| 153 | } | 165 | } |
| 154 | 166 | ||
| 155 | for( ProcessorList::iterator i = lProcessor.begin(); i; i++ ) | 167 | cWorkDone.lock(); |
| 156 | (*i)->start(); | 168 | if( iWorkDone == 0 ) |
| 169 | { | ||
| 170 | cWorkDone.unlock(); | ||
| 171 | return; | ||
| 172 | } | ||
| 157 | 173 | ||
| 158 | for( ProcessorList::iterator i = lProcessor.begin(); i; i++ ) | 174 | while( iWorkDone > 0 ) |
| 159 | (*i)->join(); | 175 | cWorkDone.wait(); |
| 176 | cWorkDone.unlock(); | ||
| 160 | } | 177 | } |
| 161 | 178 | ||
| 162 | void Genetic::ExplicitSimulation::setFitness( Genetic::PhenotypeId id, | 179 | void Genetic::ExplicitSimulation::setFitness( Genetic::PhenotypeId id, |
| @@ -166,7 +183,6 @@ void Genetic::ExplicitSimulation::setFitness( Genetic::PhenotypeId id, | |||
| 166 | if( dFitness < 0.0 ) | 183 | if( dFitness < 0.0 ) |
| 167 | dFitness = 0.0; | 184 | dFitness = 0.0; |
| 168 | 185 | ||
| 169 | // sio << id << ": " << dFitness << sio.nl; | ||
| 170 | hFitness.insert( id, dFitness ); | 186 | hFitness.insert( id, dFitness ); |
| 171 | 187 | ||
| 172 | dTotalFitness += dFitness; | 188 | dTotalFitness += dFitness; |
| @@ -186,6 +202,28 @@ void Genetic::ExplicitSimulation::setFitness( Genetic::PhenotypeId id, | |||
| 186 | } | 202 | } |
| 187 | } | 203 | } |
| 188 | 204 | ||
| 205 | void Genetic::ExplicitSimulation::workDone() | ||
| 206 | { | ||
| 207 | cWorkDone.lock(); | ||
| 208 | iWorkDone--; | ||
| 209 | |||
| 210 | if( iWorkDone == 0 ) | ||
| 211 | cWorkDone.signal(); | ||
| 212 | cWorkDone.unlock(); | ||
| 213 | } | ||
| 214 | |||
| 215 | void Genetic::ExplicitSimulation::setRunning( bool b ) | ||
| 216 | { | ||
| 217 | Bu::MutexLocker ml( mRunning ); | ||
| 218 | bRunning = b; | ||
| 219 | } | ||
| 220 | |||
| 221 | bool Genetic::ExplicitSimulation::isRunning() | ||
| 222 | { | ||
| 223 | Bu::MutexLocker ml( mRunning ); | ||
| 224 | return bRunning; | ||
| 225 | } | ||
| 226 | |||
| 189 | Genetic::ExplicitSimulation::Processor::Processor( | 227 | Genetic::ExplicitSimulation::Processor::Processor( |
| 190 | Genetic::ExplicitSimulation &rSim, | 228 | Genetic::ExplicitSimulation &rSim, |
| 191 | Genetic::FitnessFunction *pFunc, | 229 | Genetic::FitnessFunction *pFunc, |
| @@ -205,15 +243,15 @@ Genetic::ExplicitSimulation::Processor::~Processor() | |||
| 205 | 243 | ||
| 206 | void Genetic::ExplicitSimulation::Processor::run() | 244 | void Genetic::ExplicitSimulation::Processor::run() |
| 207 | { | 245 | { |
| 208 | bRunning = true; | 246 | while( rSim.isRunning() ) |
| 209 | while( bRunning && !rqWork.isEmpty() ) | ||
| 210 | { | 247 | { |
| 211 | Genetic::Phenotype *pPhen = rqWork.dequeue( 0, 250000 ); | 248 | Genetic::Phenotype *pPhen = rqWork.dequeue( true ); |
| 212 | if( pPhen == NULL ) | 249 | if( pPhen == NULL ) |
| 213 | continue; | 250 | continue; |
| 214 | 251 | ||
| 215 | double dFitness = (*pFunc)( pPhen ); | 252 | double dFitness = (*pFunc)( pPhen ); |
| 216 | rSim.setFitness( pPhen->getId(), dFitness ); | 253 | rSim.setFitness( pPhen->getId(), dFitness ); |
| 254 | rSim.workDone(); | ||
| 217 | } | 255 | } |
| 218 | } | 256 | } |
| 219 | 257 | ||
diff --git a/src/explicitsimulation.h b/src/explicitsimulation.h index c2aeed9..7713c71 100644 --- a/src/explicitsimulation.h +++ b/src/explicitsimulation.h | |||
| @@ -31,6 +31,9 @@ namespace Genetic | |||
| 31 | protected: | 31 | protected: |
| 32 | void updateFitness(); | 32 | void updateFitness(); |
| 33 | void setFitness( Genetic::PhenotypeId, double dFitness ); | 33 | void setFitness( Genetic::PhenotypeId, double dFitness ); |
| 34 | void workDone(); | ||
| 35 | void setRunning( bool b ); | ||
| 36 | bool isRunning(); | ||
| 34 | 37 | ||
| 35 | protected: | 38 | protected: |
| 36 | Population xPop; | 39 | Population xPop; |
| @@ -49,8 +52,12 @@ namespace Genetic | |||
| 49 | PhenotypeId uMaxFitness; | 52 | PhenotypeId uMaxFitness; |
| 50 | 53 | ||
| 51 | Bu::Mutex mFitness; | 54 | Bu::Mutex mFitness; |
| 55 | Bu::Condition cWorkDone; | ||
| 52 | typedef Bu::SynchroQueue<Phenotype *> WorkQueue; | 56 | typedef Bu::SynchroQueue<Phenotype *> WorkQueue; |
| 53 | WorkQueue qWork; | 57 | WorkQueue qWork; |
| 58 | int iWorkDone; | ||
| 59 | bool bRunning; | ||
| 60 | Bu::Mutex mRunning; | ||
| 54 | 61 | ||
| 55 | class Processor : public Bu::Thread | 62 | class Processor : public Bu::Thread |
| 56 | { | 63 | { |
| @@ -59,8 +66,6 @@ namespace Genetic | |||
| 59 | WorkQueue &rqWork, int iId ); | 66 | WorkQueue &rqWork, int iId ); |
| 60 | virtual ~Processor(); | 67 | virtual ~Processor(); |
| 61 | 68 | ||
| 62 | void setRunning( bool b ) { bRunning = b; } | ||
| 63 | |||
| 64 | protected: | 69 | protected: |
| 65 | virtual void run(); | 70 | virtual void run(); |
| 66 | 71 | ||
| @@ -68,7 +73,6 @@ namespace Genetic | |||
| 68 | FitnessFunction *pFunc; | 73 | FitnessFunction *pFunc; |
| 69 | WorkQueue &rqWork; | 74 | WorkQueue &rqWork; |
| 70 | int iId; | 75 | int iId; |
| 71 | bool bRunning; | ||
| 72 | }; | 76 | }; |
| 73 | 77 | ||
| 74 | typedef Bu::List<Processor *> ProcessorList; | 78 | typedef Bu::List<Processor *> ProcessorList; |
diff --git a/src/tests/maxima/main.cpp b/src/tests/maxima/main.cpp index db11f66..176a589 100644 --- a/src/tests/maxima/main.cpp +++ b/src/tests/maxima/main.cpp | |||
| @@ -14,7 +14,7 @@ int main( int argc, char *argv[] ) | |||
| 14 | { | 14 | { |
| 15 | Bu::Random::seed( time( NULL ) ); | 15 | Bu::Random::seed( time( NULL ) ); |
| 16 | sio << "Global maxima equation test" << sio.nl | 16 | sio << "Global maxima equation test" << sio.nl |
| 17 | << " - -1.8*x^4 + 0.86*x^3 + 4.0*x^2 == 3.53518 (approx)" << sio.nl | 17 | << " -1.8*x^4 + 0.86*x^3 + 4.0*x^2 == 3.53518 (approx)" << sio.nl |
| 18 | << sio.nl; | 18 | << sio.nl; |
| 19 | 19 | ||
| 20 | Genetic::ExplicitSimulation ex( | 20 | Genetic::ExplicitSimulation ex( |
