From dab5be229b197f03c5bf42dbafa2205a53c9c0f4 Mon Sep 17 00:00:00 2001 From: Thorsten Liebig Date: Thu, 20 May 2010 22:02:06 +0200 Subject: [PATCH] multithreaded engine now a derived class of compressed sse engine, created by new operator_multithread class - also fixed double init() call of engines - operator_multithread open for future multithreaded operator creation --- FDTD/engine_multithread.cpp | 60 ++++++++++++++++++++--------------- FDTD/engine_multithread.h | 20 +++--------- FDTD/operator_multithread.cpp | 41 ++++++++++++++++++++++++ FDTD/operator_multithread.h | 36 +++++++++++++++++++++ openEMS.pro | 6 ++-- openems.cpp | 18 ++++------- openems.h | 3 +- 7 files changed, 128 insertions(+), 56 deletions(-) create mode 100644 FDTD/operator_multithread.cpp create mode 100644 FDTD/operator_multithread.h diff --git a/FDTD/engine_multithread.cpp b/FDTD/engine_multithread.cpp index b1995c0..d176c87 100644 --- a/FDTD/engine_multithread.cpp +++ b/FDTD/engine_multithread.cpp @@ -35,19 +35,28 @@ //! \brief construct an Engine_Multithread instance //! it's the responsibility of the caller to free the returned pointer -Engine_Multithread* Engine_Multithread::New(const Operator* op, unsigned int numThreads) +Engine_Multithread* Engine_Multithread::New(const Operator_Multithread* op, unsigned int numThreads) { - cout << "Create FDTD engine multithreading environment" << endl; + cout << "Create FDTD engine (compressed SSE + multi-threading)" << endl; Engine_Multithread* e = new Engine_Multithread(op); e->setNumThreads( numThreads ); e->Init(); return e; } -Engine_Multithread::Engine_Multithread(const Operator* op) : Engine(op) +Engine_Multithread::Engine_Multithread(const Operator_SSE_Compressed* op) : Engine_SSE_Compressed(op) { - m_type = UNKNOWN; - m_RunEngine = NULL; + m_type = SSE; + m_barrier_VoltUpdate = 0; + m_barrier_VoltExcite = 0; + m_barrier_PreVolt = 0; + m_barrier_PostVolt = 0; + m_barrier_CurrUpdate = 0; + m_barrier_CurrExcite = 0; + m_barrier_PreCurr = 0; + m_barrier_PostCurr = 0; + m_startBarrier = 0; + m_stopBarrier = 0; } Engine_Multithread::~Engine_Multithread() @@ -78,8 +87,8 @@ void Engine_Multithread::setNumThreads( unsigned int numThreads ) void Engine_Multithread::Init() { - delete m_RunEngine; - m_RunEngine = Op->CreateEngine(); + m_stopThreads = true; + Engine_SSE_Compressed::Init(); // initialize threads m_stopThreads = false; @@ -141,8 +150,7 @@ void Engine_Multithread::Reset() delete m_stopBarrier; m_stopBarrier = 0; } - delete m_RunEngine; - m_RunEngine = NULL; + Engine_SSE_Compressed::Reset(); } bool Engine_Multithread::IterateTS(unsigned int iterTS) @@ -189,13 +197,13 @@ void thread::operator()() for (unsigned int iter=0;iterm_iterTS;++iter) { // pre voltage stuff... - for (size_t n=m_threadID;nm_RunEngine->GetExtensionCount();n+=m_enginePtr->m_numThreads) - m_enginePtr->m_RunEngine->GetExtension(n)->DoPreVoltageUpdates(); + for (size_t n=m_threadID;nGetExtensionCount();n+=m_enginePtr->m_numThreads) + m_enginePtr->GetExtension(n)->DoPreVoltageUpdates(); m_enginePtr->m_barrier_PreVolt->wait(); //voltage updates - m_enginePtr->m_RunEngine->UpdateVoltages(m_start,m_stop-m_start+1); + m_enginePtr->UpdateVoltages(m_start,m_stop-m_start+1); // record time DEBUG_TIME( m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); ) @@ -207,8 +215,8 @@ void thread::operator()() DEBUG_TIME( m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); ) //post voltage stuff... - for (size_t n=m_threadID;nm_RunEngine->GetExtensionCount();n+=m_enginePtr->m_numThreads) - m_enginePtr->m_RunEngine->GetExtension(n)->DoPostVoltageUpdates(); + for (size_t n=m_threadID;nGetExtensionCount();n+=m_enginePtr->m_numThreads) + m_enginePtr->GetExtension(n)->DoPostVoltageUpdates(); m_enginePtr->m_barrier_PostVolt->wait(); // e-field excitation (thread thread_e_excitation) @@ -219,12 +227,12 @@ void thread::operator()() DEBUG_TIME( m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); ) //pre current stuff - for (size_t n=m_threadID;nm_RunEngine->GetExtensionCount();n+=m_enginePtr->m_numThreads) - m_enginePtr->m_RunEngine->GetExtension(n)->DoPreCurrentUpdates(); + for (size_t n=m_threadID;nGetExtensionCount();n+=m_enginePtr->m_numThreads) + m_enginePtr->GetExtension(n)->DoPreCurrentUpdates(); m_enginePtr->m_barrier_PreCurr->wait(); //current updates - m_enginePtr->m_RunEngine->UpdateCurrents(m_start,m_stop_h-m_start+1); + m_enginePtr->UpdateCurrents(m_start,m_stop_h-m_start+1); // record time DEBUG_TIME( m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); ) @@ -234,8 +242,8 @@ void thread::operator()() DEBUG_TIME( m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); ) //post current stuff - for (size_t n=m_threadID;nm_RunEngine->GetExtensionCount();n+=m_enginePtr->m_numThreads) - m_enginePtr->m_RunEngine->GetExtension(n)->DoPostCurrentUpdates(); + for (size_t n=m_threadID;nGetExtensionCount();n+=m_enginePtr->m_numThreads) + m_enginePtr->GetExtension(n)->DoPostCurrentUpdates(); m_enginePtr->m_barrier_PostCurr->wait(); //soft current excitation here (H-field excite) @@ -243,7 +251,7 @@ void thread::operator()() // excitation finished if (m_threadID == 0) - ++m_enginePtr->m_RunEngine->numTS; // only the first thread increments numTS + ++m_enginePtr->numTS; // only the first thread increments numTS } m_enginePtr->m_stopBarrier->wait(); @@ -273,20 +281,20 @@ void thread_e_excitation::operator()() { m_enginePtr->m_barrier_PostVolt->wait(); // waiting on NS_Engine_Multithread::thread - for (size_t n=0;nm_RunEngine->GetExtensionCount();++n) - m_enginePtr->m_RunEngine->GetExtension(n)->Apply2Voltages(); + for (size_t n=0;nGetExtensionCount();++n) + m_enginePtr->GetExtension(n)->Apply2Voltages(); - m_enginePtr->m_RunEngine->ApplyVoltageExcite(); + m_enginePtr->ApplyVoltageExcite(); m_enginePtr->m_barrier_VoltExcite->wait(); // continue NS_Engine_Multithread::thread m_enginePtr->m_barrier_PostCurr->wait(); // waiting on NS_Engine_Multithread::thread - for (size_t n=0;nm_RunEngine->GetExtensionCount();++n) - m_enginePtr->m_RunEngine->GetExtension(n)->Apply2Current(); + for (size_t n=0;nGetExtensionCount();++n) + m_enginePtr->GetExtension(n)->Apply2Current(); - m_enginePtr->m_RunEngine->ApplyCurrentExcite(); + m_enginePtr->ApplyCurrentExcite(); m_enginePtr->m_barrier_CurrExcite->wait(); // continue NS_Engine_Multithread::thread } diff --git a/FDTD/engine_multithread.h b/FDTD/engine_multithread.h index c4dc7cf..ff062c8 100644 --- a/FDTD/engine_multithread.h +++ b/FDTD/engine_multithread.h @@ -18,8 +18,8 @@ #ifndef ENGINE_MULTITHREAD_H #define ENGINE_MULTITHREAD_H -#include "operator.h" -#include "engine.h" +#include "operator_multithread.h" +#include "engine_sse_compressed.h" #include #include @@ -74,31 +74,23 @@ namespace NS_Engine_Multithread { } // namespace -class Engine_Multithread : public Engine +class Engine_Multithread : public Engine_SSE_Compressed { friend class NS_Engine_Multithread::thread; friend class NS_Engine_Multithread::thread_e_excitation; public: - static Engine_Multithread* New(const Operator* op, unsigned int numThreads = 0); + static Engine_Multithread* New(const Operator_Multithread* op, unsigned int numThreads = 0); virtual ~Engine_Multithread(); - //this access functions muss be overloaded by any new engine using a different storage model - inline virtual FDTD_FLOAT& GetVolt( unsigned int n, unsigned int x, unsigned int y, unsigned int z ) { return m_RunEngine->GetVolt(n,x,y,z); } - inline virtual FDTD_FLOAT& GetVolt( unsigned int n, unsigned int pos[3] ) { return m_RunEngine->GetVolt(n,pos); } - inline virtual FDTD_FLOAT& GetCurr( unsigned int n, unsigned int x, unsigned int y, unsigned int z ) { return m_RunEngine->GetCurr(n,x,y,z); } - inline virtual FDTD_FLOAT& GetCurr( unsigned int n, unsigned int pos[3] ) { return m_RunEngine->GetCurr(n,pos);} - virtual void setNumThreads( unsigned int numThreads ); virtual void Init(); virtual void Reset(); - virtual unsigned int GetNumberOfTimesteps() {return m_RunEngine->GetNumberOfTimesteps();} - //!Iterate a number of timesteps virtual bool IterateTS(unsigned int iterTS); protected: - Engine_Multithread(const Operator* op); + Engine_Multithread(const Operator_SSE_Compressed* op); boost::thread_group m_thread_group; boost::barrier *m_startBarrier, *m_stopBarrier; boost::barrier *m_barrier_VoltUpdate, *m_barrier_VoltExcite, *m_barrier_PreVolt, *m_barrier_PostVolt; @@ -107,8 +99,6 @@ protected: unsigned int m_numThreads; //!< number of worker threads volatile bool m_stopThreads; - Engine* m_RunEngine; - #ifdef ENABLE_DEBUG_TIME std::map > m_timer_list; #endif diff --git a/FDTD/operator_multithread.cpp b/FDTD/operator_multithread.cpp new file mode 100644 index 0000000..71159d3 --- /dev/null +++ b/FDTD/operator_multithread.cpp @@ -0,0 +1,41 @@ +/* +* Copyright (C) 2010 Thorsten Liebig (Thorsten.Liebig@gmx.de) +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ + +#include "operator_multithread.h" +#include "engine_multithread.h" + +Operator_Multithread* Operator_Multithread::New() +{ + cout << "Create FDTD operator (compressed SSE + multi-threading)" << endl; + Operator_Multithread* op = new Operator_Multithread(); + op->Init(); + return op; +} + +Operator_Multithread::~Operator_Multithread() +{ +} + +Engine* Operator_Multithread::CreateEngine() const +{ + Engine_Multithread* e = Engine_Multithread::New(this); + return e; +} + +Operator_Multithread::Operator_Multithread() +{ +} diff --git a/FDTD/operator_multithread.h b/FDTD/operator_multithread.h new file mode 100644 index 0000000..65970bc --- /dev/null +++ b/FDTD/operator_multithread.h @@ -0,0 +1,36 @@ +/* +* Copyright (C) 2010 Thorsten Liebig (Thorsten.Liebig@gmx.de) +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ + +#ifndef OPERATOR_MULTITHREAD_H +#define OPERATOR_MULTITHREAD_H + +#include "operator_sse_compressed.h" + +class Operator_Multithread : public Operator_SSE_Compressed +{ +public: + //! Create a new operator + static Operator_Multithread* New(); + virtual ~Operator_Multithread(); + + virtual Engine* CreateEngine() const; + +protected: + Operator_Multithread(); +}; + +#endif // OPERATOR_MULTITHREAD_H diff --git a/openEMS.pro b/openEMS.pro index dbd7481..48a5344 100644 --- a/openEMS.pro +++ b/openEMS.pro @@ -54,7 +54,8 @@ SOURCES += main.cpp \ FDTD/operator_ext_cylinder.cpp \ FDTD/engine_ext_cylinder.cpp \ FDTD/operator_sse_compressed.cpp \ - FDTD/engine_sse_compressed.cpp + FDTD/engine_sse_compressed.cpp \ + FDTD/operator_multithread.cpp HEADERS += tools/ErrorMsg.h \ tools/AdrOp.h \ tools/constants.h \ @@ -79,7 +80,8 @@ HEADERS += tools/ErrorMsg.h \ FDTD/operator_ext_cylinder.h \ FDTD/engine_ext_cylinder.h \ FDTD/operator_sse_compressed.h \ - FDTD/engine_sse_compressed.h + FDTD/engine_sse_compressed.h \ + FDTD/operator_multithread.h QMAKE_CXXFLAGS_RELEASE = -O3 \ -g \ -march=native diff --git a/openems.cpp b/openems.cpp index 00b6f35..a614a42 100644 --- a/openems.cpp +++ b/openems.cpp @@ -18,11 +18,9 @@ #include "openems.h" #include #include "tools/array_ops.h" -#include "FDTD/engine.h" #include "FDTD/operator_cylinder.h" #include "FDTD/engine_multithread.h" -#include "FDTD/engine_sse.h" -#include "FDTD/operator_sse_compressed.h" +#include "FDTD/operator_multithread.h" #include "FDTD/operator_ext_mur_abc.h" #include "FDTD/processvoltage.h" #include "FDTD/processcurrent.h" @@ -47,7 +45,6 @@ openEMS::openEMS() FDTD_Eng=NULL; PA=NULL; CylinderCoords = false; - m_MultiThreading = false; Enable_Dumps = true; DebugMat = false; DebugOp = false; @@ -107,7 +104,7 @@ bool openEMS::parseCommandLineArgument( const char *argv ) else if (strcmp(argv,"--engine=multithreaded")==0) { cout << "openEMS - enabled multithreading" << endl; - m_MultiThreading = true; + m_engine = EngineType_Multithreaded; return true; } else if (strncmp(argv,"--numThreads=",13)==0) @@ -221,6 +218,10 @@ int openEMS::SetupFDTD(const char* file) { FDTD_Op = Operator_SSE_Compressed::New(); } + else if (m_engine == EngineType_Multithreaded) + { + FDTD_Op = Operator_Multithread::New(); + } else { FDTD_Op = Operator::New(); @@ -263,12 +264,7 @@ int openEMS::SetupFDTD(const char* file) cout << "Creation time for operator: " << difftime(OpDoneTime,startTime) << " s" << endl; //create FDTD engine - if (m_MultiThreading) - { - FDTD_Eng = Engine_Multithread::New(FDTD_Op,m_engine_numThreads); - } - else - FDTD_Eng = FDTD_Op->CreateEngine(); + FDTD_Eng = FDTD_Op->CreateEngine(); //*************** setup processing ************// cout << "Setting up processing..." << endl; diff --git a/openems.h b/openems.h index 2b38c88..efa9f2e 100644 --- a/openems.h +++ b/openems.h @@ -46,7 +46,6 @@ public: protected: bool CylinderCoords; - bool m_MultiThreading; //! Number of Timesteps unsigned int NrTS; @@ -60,7 +59,7 @@ protected: Engine* FDTD_Eng; ProcessingArray* PA; - enum EngineType {EngineType_Standard, EngineType_SSE, EngineType_SSE_Compressed}; + enum EngineType {EngineType_Standard, EngineType_SSE, EngineType_SSE_Compressed, EngineType_Multithreaded}; EngineType m_engine; unsigned int m_engine_numThreads; };