diff --git a/FDTD/operator_multithread.cpp b/FDTD/operator_multithread.cpp index 71159d3..6acecba 100644 --- a/FDTD/operator_multithread.cpp +++ b/FDTD/operator_multithread.cpp @@ -18,10 +18,11 @@ #include "operator_multithread.h" #include "engine_multithread.h" -Operator_Multithread* Operator_Multithread::New() +Operator_Multithread* Operator_Multithread::New(unsigned int numThreads) { cout << "Create FDTD operator (compressed SSE + multi-threading)" << endl; Operator_Multithread* op = new Operator_Multithread(); + op->setNumThreads(numThreads); op->Init(); return op; } @@ -30,12 +31,112 @@ Operator_Multithread::~Operator_Multithread() { } +void Operator_Multithread::setNumThreads( unsigned int numThreads ) +{ + m_numThreads = numThreads; +} + Engine* Operator_Multithread::CreateEngine() const { - Engine_Multithread* e = Engine_Multithread::New(this); + Engine_Multithread* e = Engine_Multithread::New(this,m_numThreads); return e; } Operator_Multithread::Operator_Multithread() { + m_CalcEC_Start=NULL; + m_CalcEC_Stop=NULL; } + +void Operator_Multithread::Init() +{ + Operator_SSE_Compressed::Init(); + m_CalcEC_Start=NULL; + m_CalcEC_Stop=NULL; +} + +void Operator_Multithread::Reset() +{ + Operator_SSE_Compressed::Reset(); + + m_thread_group.join_all(); + + delete m_CalcEC_Start;m_CalcEC_Start=NULL; + delete m_CalcEC_Stop;m_CalcEC_Stop=NULL; +} + +int Operator_Multithread::CalcECOperator() +{ + if (m_numThreads == 0) + m_numThreads = boost::thread::hardware_concurrency(); + + cout << "Multithreading operator using " << m_numThreads << " threads." << std::endl; + + m_thread_group.join_all(); + delete m_CalcEC_Start;m_CalcEC_Start = new boost::barrier(m_numThreads+1); // numThread workers + 1 controller + delete m_CalcEC_Stop;m_CalcEC_Stop = new boost::barrier(m_numThreads+1); // numThread workers + 1 controller + + unsigned int linesPerThread = round((float)numLines[0] / (float)m_numThreads); + for (unsigned int n=0; nSetPos(0,0,0); + + m_CalcEC_Start->wait(); + + m_CalcEC_Stop->wait(); + + return true; +} + +Operator_Thread::Operator_Thread( Operator_Multithread* ptr, unsigned int start, unsigned int stop, unsigned int threadID ) +{ + m_start=start; + m_stop=stop; + m_threadID=threadID; + m_OpPtr = ptr; +} + +void Operator_Thread::operator()() +{ + //************** calculate EC (Calc_EC) ***********************// + m_OpPtr->m_CalcEC_Start->wait(); + unsigned int ipos; + unsigned int pos[3]; + double inEC[4]; + for (int n=0;n<3;++n) + { + for (pos[0]=m_start;pos[0]<=m_stop;++pos[0]) + { + for (pos[1]=0;pos[1]numLines[1];++pos[1]) + { + for (pos[2]=0;pos[2]numLines[2];++pos[2]) + { + m_OpPtr->Calc_ECPos(n,pos,inEC); + ipos = m_OpPtr->MainOp->GetPos(pos[0],pos[1],pos[2]); + m_OpPtr->EC_C[n][ipos]=inEC[0]; + m_OpPtr->EC_G[n][ipos]=inEC[1]; + m_OpPtr->EC_L[n][ipos]=inEC[2]; + m_OpPtr->EC_R[n][ipos]=inEC[3]; + } + } + } + } + m_OpPtr->m_CalcEC_Stop->wait(); +} + diff --git a/FDTD/operator_multithread.h b/FDTD/operator_multithread.h index 65970bc..896753c 100644 --- a/FDTD/operator_multithread.h +++ b/FDTD/operator_multithread.h @@ -20,17 +20,45 @@ #include "operator_sse_compressed.h" +#include + class Operator_Multithread : public Operator_SSE_Compressed { + friend class Operator_Thread; public: //! Create a new operator - static Operator_Multithread* New(); + static Operator_Multithread* New(unsigned int numThreads = 0); virtual ~Operator_Multithread(); + virtual int CalcECOperator(); + + virtual void setNumThreads( unsigned int numThreads ); + virtual Engine* CreateEngine() const; protected: Operator_Multithread(); + virtual void Init(); + virtual void Reset(); + + virtual bool Calc_EC(); //this method is using multi-threading + + boost::barrier* m_CalcEC_Start; + boost::barrier* m_CalcEC_Stop; + boost::thread_group m_thread_group; + unsigned int m_numThreads; // number of worker threads }; +class Operator_Thread +{ +public: + Operator_Thread( Operator_Multithread* ptr, unsigned int start, unsigned int stop, unsigned int threadID ); + void operator()(); + +protected: + unsigned int m_start, m_stop, m_threadID; + Operator_Multithread *m_OpPtr; +}; + + #endif // OPERATOR_MULTITHREAD_H diff --git a/openems.cpp b/openems.cpp index 2f4cc63..e70c5fc 100644 --- a/openems.cpp +++ b/openems.cpp @@ -236,7 +236,7 @@ int openEMS::SetupFDTD(const char* file) } else if (m_engine == EngineType_Multithreaded) { - FDTD_Op = Operator_Multithread::New(); + FDTD_Op = Operator_Multithread::New(m_engine_numThreads); } else {