diff --git a/FDTD/engine_multithread.cpp b/FDTD/engine_multithread.cpp index e51cf25..6744d75 100644 --- a/FDTD/engine_multithread.cpp +++ b/FDTD/engine_multithread.cpp @@ -35,9 +35,10 @@ //! \brief construct an Engine_Multithread instance //! it's the responsibility of the caller to free the returned pointer -Engine_Multithread* Engine_Multithread::createEngine(Operator* op) +Engine_Multithread* Engine_Multithread::createEngine(Operator* op, unsigned int numThreads) { Engine_Multithread* e = new Engine_Multithread(op); + e->setNumThreads( numThreads ); e->Init(); return e; } @@ -66,15 +67,20 @@ Engine_Multithread::~Engine_Multithread() } +void Engine_Multithread::setNumThreads( unsigned int numThreads ) +{ + m_numThreads = numThreads; +} + void Engine_Multithread::Init() { Engine::Init(); - numTS = 0; m_numTS_times_threads = 0; // initialize threads - m_numThreads = boost::thread::hardware_concurrency(); + if (m_numThreads == 0) + m_numThreads = boost::thread::hardware_concurrency(); std::cout << "using " << m_numThreads << " threads" << std::endl; m_barrier1 = new boost::barrier(m_numThreads+1); // numThread workers + 1 excitation thread m_barrier2 = new boost::barrier(m_numThreads+1); // numThread workers + 1 excitation thread @@ -82,12 +88,13 @@ void Engine_Multithread::Init() m_startBarrier = new boost::barrier(m_numThreads+1); // numThread workers + 1 controller m_stopBarrier = new boost::barrier(m_numThreads+1); // numThread workers + 1 controller - for (int n=0; nnumLines[0]+m_numThreads-1) / m_numThreads; unsigned int start = n * linesPerThread; unsigned int stop = min( (n+1) * linesPerThread - 1, Op->numLines[0]-1 ); - //std::cout << "### " << Op->numLines[0] << " " << linesPerThread << " " << start << " " << stop << std::endl; - boost::thread *t = new boost::thread( thread(this,start,stop) ); + unsigned int stop_h = (n!=m_numThreads-1)?stop:stop-1; + std::cout << "###DEBUG## Thread " << n << ": start=" << start << " stop=" << stop << " stop_h=" << stop_h << std::endl; + boost::thread *t = new boost::thread( thread(this,start,stop,stop_h) ); m_thread_group.add_thread( t ); } boost::thread *t = new boost::thread( thread_e_excitation(this) ); @@ -118,11 +125,16 @@ bool Engine_Multithread::IterateTS(unsigned int iterTS) -thread::thread( Engine_Multithread* ptr, unsigned int start, unsigned int stop ) : m_enginePtr(ptr), m_start(start), m_stop(stop), m_stopThread(false) +thread::thread( Engine_Multithread* ptr, unsigned int start, unsigned int stop, unsigned int stop_h ) { + m_enginePtr = ptr; + m_start = start; + m_stop = stop; + m_stop_h = stop_h; Op = m_enginePtr->Op; - volt = m_enginePtr->volt; - curr = m_enginePtr->curr; + m_stopThread = false; +// volt = m_enginePtr->volt; +// curr = m_enginePtr->curr; } void thread::operator()() @@ -154,16 +166,16 @@ void thread::operator()() shift[2]=pos[2]; //do the updates here //for x - volt[0][pos[0]][pos[1]][pos[2]] *= Op->vv[0][pos[0]][pos[1]][pos[2]]; - volt[0][pos[0]][pos[1]][pos[2]] += Op->vi[0][pos[0]][pos[1]][pos[2]] * ( curr[2][pos[0]][pos[1]][pos[2]] - curr[2][pos[0]][pos[1]-shift[1]][pos[2]] - curr[1][pos[0]][pos[1]][pos[2]] + curr[1][pos[0]][pos[1]][pos[2]-shift[2]]); + m_enginePtr->volt[0][pos[0]][pos[1]][pos[2]] *= Op->vv[0][pos[0]][pos[1]][pos[2]]; + m_enginePtr->volt[0][pos[0]][pos[1]][pos[2]] += Op->vi[0][pos[0]][pos[1]][pos[2]] * ( m_enginePtr->curr[2][pos[0]][pos[1]][pos[2]] - m_enginePtr->curr[2][pos[0]][pos[1]-shift[1]][pos[2]] - m_enginePtr->curr[1][pos[0]][pos[1]][pos[2]] + m_enginePtr->curr[1][pos[0]][pos[1]][pos[2]-shift[2]]); //for y - volt[1][pos[0]][pos[1]][pos[2]] *= Op->vv[1][pos[0]][pos[1]][pos[2]]; - volt[1][pos[0]][pos[1]][pos[2]] += Op->vi[1][pos[0]][pos[1]][pos[2]] * ( curr[0][pos[0]][pos[1]][pos[2]] - curr[0][pos[0]][pos[1]][pos[2]-shift[2]] - curr[2][pos[0]][pos[1]][pos[2]] + curr[2][pos[0]-shift[0]][pos[1]][pos[2]]); + m_enginePtr->volt[1][pos[0]][pos[1]][pos[2]] *= Op->vv[1][pos[0]][pos[1]][pos[2]]; + m_enginePtr->volt[1][pos[0]][pos[1]][pos[2]] += Op->vi[1][pos[0]][pos[1]][pos[2]] * ( m_enginePtr->curr[0][pos[0]][pos[1]][pos[2]] - m_enginePtr->curr[0][pos[0]][pos[1]][pos[2]-shift[2]] - m_enginePtr->curr[2][pos[0]][pos[1]][pos[2]] + m_enginePtr->curr[2][pos[0]-shift[0]][pos[1]][pos[2]]); //for x - volt[2][pos[0]][pos[1]][pos[2]] *= Op->vv[2][pos[0]][pos[1]][pos[2]]; - volt[2][pos[0]][pos[1]][pos[2]] += Op->vi[2][pos[0]][pos[1]][pos[2]] * ( curr[1][pos[0]][pos[1]][pos[2]] - curr[1][pos[0]-shift[0]][pos[1]][pos[2]] - curr[0][pos[0]][pos[1]][pos[2]] + curr[0][pos[0]][pos[1]-shift[1]][pos[2]]); + m_enginePtr->volt[2][pos[0]][pos[1]][pos[2]] *= Op->vv[2][pos[0]][pos[1]][pos[2]]; + m_enginePtr->volt[2][pos[0]][pos[1]][pos[2]] += Op->vi[2][pos[0]][pos[1]][pos[2]] * ( m_enginePtr->curr[1][pos[0]][pos[1]][pos[2]] - m_enginePtr->curr[1][pos[0]-shift[0]][pos[1]][pos[2]] - m_enginePtr->curr[0][pos[0]][pos[1]][pos[2]] + m_enginePtr->curr[0][pos[0]][pos[1]-shift[1]][pos[2]]); } } } @@ -186,7 +198,7 @@ void thread::operator()() DEBUG_TIME( m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); ) //current updates - for (pos[0]=m_start;pos[0]<=m_stop-1;++pos[0]) + for (pos[0]=m_start;pos[0]<=m_stop_h;++pos[0]) { for (pos[1]=0;pos[1]numLines[1]-1;++pos[1]) { @@ -194,16 +206,16 @@ void thread::operator()() { //do the updates here //for x - curr[0][pos[0]][pos[1]][pos[2]] *= Op->ii[0][pos[0]][pos[1]][pos[2]]; - curr[0][pos[0]][pos[1]][pos[2]] += Op->iv[0][pos[0]][pos[1]][pos[2]] * ( volt[2][pos[0]][pos[1]][pos[2]] - volt[2][pos[0]][pos[1]+1][pos[2]] - volt[1][pos[0]][pos[1]][pos[2]] + volt[1][pos[0]][pos[1]][pos[2]+1]); + m_enginePtr->curr[0][pos[0]][pos[1]][pos[2]] *= Op->ii[0][pos[0]][pos[1]][pos[2]]; + m_enginePtr->curr[0][pos[0]][pos[1]][pos[2]] += Op->iv[0][pos[0]][pos[1]][pos[2]] * ( m_enginePtr->volt[2][pos[0]][pos[1]][pos[2]] - m_enginePtr->volt[2][pos[0]][pos[1]+1][pos[2]] - m_enginePtr->volt[1][pos[0]][pos[1]][pos[2]] + m_enginePtr->volt[1][pos[0]][pos[1]][pos[2]+1]); //for y - curr[1][pos[0]][pos[1]][pos[2]] *= Op->ii[1][pos[0]][pos[1]][pos[2]]; - curr[1][pos[0]][pos[1]][pos[2]] += Op->iv[1][pos[0]][pos[1]][pos[2]] * ( volt[0][pos[0]][pos[1]][pos[2]] - volt[0][pos[0]][pos[1]][pos[2]+1] - volt[2][pos[0]][pos[1]][pos[2]] + volt[2][pos[0]+1][pos[1]][pos[2]]); + m_enginePtr->curr[1][pos[0]][pos[1]][pos[2]] *= Op->ii[1][pos[0]][pos[1]][pos[2]]; + m_enginePtr->curr[1][pos[0]][pos[1]][pos[2]] += Op->iv[1][pos[0]][pos[1]][pos[2]] * ( m_enginePtr->volt[0][pos[0]][pos[1]][pos[2]] - m_enginePtr->volt[0][pos[0]][pos[1]][pos[2]+1] - m_enginePtr->volt[2][pos[0]][pos[1]][pos[2]] + m_enginePtr->volt[2][pos[0]+1][pos[1]][pos[2]]); //for x - curr[2][pos[0]][pos[1]][pos[2]] *= Op->ii[2][pos[0]][pos[1]][pos[2]]; - curr[2][pos[0]][pos[1]][pos[2]] += Op->iv[2][pos[0]][pos[1]][pos[2]] * ( volt[1][pos[0]][pos[1]][pos[2]] - volt[1][pos[0]+1][pos[1]][pos[2]] - volt[0][pos[0]][pos[1]][pos[2]] + volt[0][pos[0]][pos[1]+1][pos[2]]); + m_enginePtr->curr[2][pos[0]][pos[1]][pos[2]] *= Op->ii[2][pos[0]][pos[1]][pos[2]]; + m_enginePtr->curr[2][pos[0]][pos[1]][pos[2]] += Op->iv[2][pos[0]][pos[1]][pos[2]] * ( m_enginePtr->volt[1][pos[0]][pos[1]][pos[2]] - m_enginePtr->volt[1][pos[0]+1][pos[1]][pos[2]] - m_enginePtr->volt[0][pos[0]][pos[1]][pos[2]] + m_enginePtr->volt[0][pos[0]][pos[1]+1][pos[2]]); } } } @@ -226,11 +238,13 @@ void thread::operator()() } -thread_e_excitation::thread_e_excitation( Engine_Multithread* ptr ) : m_enginePtr(ptr), m_stopThread(false) +thread_e_excitation::thread_e_excitation( Engine_Multithread* ptr ) { + m_enginePtr = ptr; Op = m_enginePtr->Op; - volt = m_enginePtr->volt; - curr = m_enginePtr->curr; + m_stopThread = false; +// volt = m_enginePtr->volt; +// curr = m_enginePtr->curr; } void thread_e_excitation::operator()() @@ -251,7 +265,7 @@ void thread_e_excitation::operator()() exc_pos = (int)numTS - (int)Op->E_Exc_delay[n]; exc_pos*= (exc_pos>0 && exc_pos<(int)Op->ExciteLength); // if (n==0) cerr << numTS << " => " << Op->ExciteSignal[exc_pos] << endl; - volt[Op->E_Exc_dir[n]][Op->E_Exc_index[0][n]][Op->E_Exc_index[1][n]][Op->E_Exc_index[2][n]] += Op->E_Exc_amp[n]*Op->ExciteSignal[exc_pos]; + m_enginePtr->volt[Op->E_Exc_dir[n]][Op->E_Exc_index[0][n]][Op->E_Exc_index[1][n]][Op->E_Exc_index[2][n]] += Op->E_Exc_amp[n]*Op->ExciteSignal[exc_pos]; } // continueing thread diff --git a/FDTD/engine_multithread.h b/FDTD/engine_multithread.h index e6abbb4..12c9a8c 100644 --- a/FDTD/engine_multithread.h +++ b/FDTD/engine_multithread.h @@ -37,17 +37,13 @@ protected: class Engine_Multithread : public Engine { - friend class Processing; - friend class ProcessVoltage; - friend class ProcessCurrent; - friend class ProcessFields; - friend class ProcessFieldsTD; friend class thread; friend class thread_e_excitation; public: - static Engine_Multithread* createEngine(Operator* op); + static Engine_Multithread* createEngine(Operator* op, unsigned int numThreads = 0); virtual ~Engine_Multithread(); + virtual void setNumThreads( unsigned int numThreads ); virtual void Init(); virtual void Reset(); @@ -73,16 +69,16 @@ protected: class thread { public: - thread( Engine_Multithread* ptr, unsigned int start, unsigned int stop ); + thread( Engine_Multithread* ptr, unsigned int start, unsigned int stop, unsigned int stop_h ); void operator()(); protected: - unsigned int m_start, m_stop; + unsigned int m_start, m_stop, m_stop_h; volatile bool m_stopThread; Engine_Multithread *m_enginePtr; Operator *Op; - FDTD_FLOAT**** volt; - FDTD_FLOAT**** curr; +// FDTD_FLOAT**** volt; +// FDTD_FLOAT**** curr; }; class thread_e_excitation { @@ -94,8 +90,8 @@ protected: volatile bool m_stopThread; Engine_Multithread *m_enginePtr; Operator *Op; - FDTD_FLOAT**** volt; - FDTD_FLOAT**** curr; +// FDTD_FLOAT**** volt; +// FDTD_FLOAT**** curr; }; #endif // ENGINE_MULTITHREAD_H diff --git a/openems.cpp b/openems.cpp index 4fb780b..cbe374d 100644 --- a/openems.cpp +++ b/openems.cpp @@ -47,6 +47,9 @@ openEMS::openEMS() DebugMat = false; DebugOp = false; endCrit = 1e-6; + + m_engine = EngineType_Standard; + m_engine_numThreads = 0; } openEMS::~openEMS() @@ -102,6 +105,12 @@ bool openEMS::parseCommandLineArgument( const char *argv ) m_engine = EngineType_Multithreaded; return true; } + else if (strncmp(argv,"--numThreads=",13)==0) + { + m_engine_numThreads = atoi(argv+13); + cout << "openEMS - fixed number of threads: " << m_engine_numThreads << endl; + return true; + } return false; } @@ -243,7 +252,7 @@ int openEMS::SetupFDTD(const char* file) //create FDTD engine switch (m_engine) { case EngineType_Multithreaded: - FDTD_Eng = Engine_Multithread::createEngine(FDTD_Op); + FDTD_Eng = Engine_Multithread::createEngine(FDTD_Op,m_engine_numThreads); break; default: FDTD_Eng = Engine::createEngine(FDTD_Op); diff --git a/openems.h b/openems.h index d218c7a..981ac30 100644 --- a/openems.h +++ b/openems.h @@ -55,6 +55,7 @@ protected: enum EngineType {EngineType_Standard,EngineType_Multithreaded}; EngineType m_engine; + unsigned int m_engine_numThreads; }; #endif // OPENEMS_H