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 creationpull/1/head
parent
df17dc23c6
commit
dab5be229b
|
@ -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;iter<m_enginePtr->m_iterTS;++iter)
|
||||
{
|
||||
// pre voltage stuff...
|
||||
for (size_t n=m_threadID;n<m_enginePtr->m_RunEngine->GetExtensionCount();n+=m_enginePtr->m_numThreads)
|
||||
m_enginePtr->m_RunEngine->GetExtension(n)->DoPreVoltageUpdates();
|
||||
for (size_t n=m_threadID;n<m_enginePtr->GetExtensionCount();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;n<m_enginePtr->m_RunEngine->GetExtensionCount();n+=m_enginePtr->m_numThreads)
|
||||
m_enginePtr->m_RunEngine->GetExtension(n)->DoPostVoltageUpdates();
|
||||
for (size_t n=m_threadID;n<m_enginePtr->GetExtensionCount();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;n<m_enginePtr->m_RunEngine->GetExtensionCount();n+=m_enginePtr->m_numThreads)
|
||||
m_enginePtr->m_RunEngine->GetExtension(n)->DoPreCurrentUpdates();
|
||||
for (size_t n=m_threadID;n<m_enginePtr->GetExtensionCount();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;n<m_enginePtr->m_RunEngine->GetExtensionCount();n+=m_enginePtr->m_numThreads)
|
||||
m_enginePtr->m_RunEngine->GetExtension(n)->DoPostCurrentUpdates();
|
||||
for (size_t n=m_threadID;n<m_enginePtr->GetExtensionCount();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;n<m_enginePtr->m_RunEngine->GetExtensionCount();++n)
|
||||
m_enginePtr->m_RunEngine->GetExtension(n)->Apply2Voltages();
|
||||
for (size_t n=0;n<m_enginePtr->GetExtensionCount();++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;n<m_enginePtr->m_RunEngine->GetExtensionCount();++n)
|
||||
m_enginePtr->m_RunEngine->GetExtension(n)->Apply2Current();
|
||||
for (size_t n=0;n<m_enginePtr->GetExtensionCount();++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
|
||||
}
|
||||
|
|
|
@ -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 <boost/thread.hpp>
|
||||
#include <boost/fusion/include/list.hpp>
|
||||
|
@ -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<boost::thread::id, std::vector<double> > m_timer_list;
|
||||
#endif
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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()
|
||||
{
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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
|
|
@ -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
|
||||
|
|
18
openems.cpp
18
openems.cpp
|
@ -18,11 +18,9 @@
|
|||
#include "openems.h"
|
||||
#include <iomanip>
|
||||
#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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue