summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Buland <mike@xagasoft.com>2012-07-18 01:26:34 -0600
committerMike Buland <mike@xagasoft.com>2012-07-18 01:26:34 -0600
commit299640ce5f6499e07c5799f48897ac5a77e72c54 (patch)
tree47b502fca70dc2fc8a48ae9b3ae813763e98c78e
parenta2679e3bc2f407fae6b97908aeebb215c6678ebc (diff)
downloadlibgenetic-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.cpp64
-rw-r--r--src/explicitsimulation.h10
-rw-r--r--src/tests/maxima/main.cpp2
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
162void Genetic::ExplicitSimulation::setFitness( Genetic::PhenotypeId id, 179void 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
205void Genetic::ExplicitSimulation::workDone()
206{
207 cWorkDone.lock();
208 iWorkDone--;
209
210 if( iWorkDone == 0 )
211 cWorkDone.signal();
212 cWorkDone.unlock();
213}
214
215void Genetic::ExplicitSimulation::setRunning( bool b )
216{
217 Bu::MutexLocker ml( mRunning );
218 bRunning = b;
219}
220
221bool Genetic::ExplicitSimulation::isRunning()
222{
223 Bu::MutexLocker ml( mRunning );
224 return bRunning;
225}
226
189Genetic::ExplicitSimulation::Processor::Processor( 227Genetic::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
206void Genetic::ExplicitSimulation::Processor::run() 244void 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(