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
pull/1/head
Thorsten Liebig 2010-05-20 22:02:06 +02:00
parent df17dc23c6
commit dab5be229b
7 changed files with 128 additions and 56 deletions

View File

@ -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
}

View File

@ -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

View File

@ -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()
{
}

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;
};