extensions: multithreading support added

every extension can either implement the single threaded methods e.g. DoPreVoltageUpdates()
or the multithreading aquivalent method e.g. DoPreVoltageUpdates(int threadID)

Engine_Ext_UPML class is an example for a multithreading extensions
This commit is contained in:
Thorsten Liebig 2010-10-06 10:30:55 +02:00
parent 1b2ac008e7
commit 043ef6ec4c
6 changed files with 229 additions and 88 deletions

View File

@ -20,6 +20,7 @@
#include "engine.h" #include "engine.h"
#include "engine_sse.h" #include "engine_sse.h"
#include "tools/array_ops.h" #include "tools/array_ops.h"
#include "tools/useful.h"
Engine_Ext_UPML::Engine_Ext_UPML(Operator_Ext_UPML* op_ext) : Engine_Extension(op_ext) Engine_Ext_UPML::Engine_Ext_UPML(Operator_Ext_UPML* op_ext) : Engine_Extension(op_ext)
{ {
@ -32,6 +33,8 @@ Engine_Ext_UPML::Engine_Ext_UPML(Operator_Ext_UPML* op_ext) : Engine_Extension(o
volt_flux = Create_N_3DArray<FDTD_FLOAT>(m_Op_UPML->m_numLines); volt_flux = Create_N_3DArray<FDTD_FLOAT>(m_Op_UPML->m_numLines);
curr = Create_N_3DArray<FDTD_FLOAT>(m_Op_UPML->m_numLines); curr = Create_N_3DArray<FDTD_FLOAT>(m_Op_UPML->m_numLines);
curr_flux = Create_N_3DArray<FDTD_FLOAT>(m_Op_UPML->m_numLines); curr_flux = Create_N_3DArray<FDTD_FLOAT>(m_Op_UPML->m_numLines);
SetNumberOfThreads(1);
} }
Engine_Ext_UPML::~Engine_Ext_UPML() Engine_Ext_UPML::~Engine_Ext_UPML()
@ -46,19 +49,35 @@ Engine_Ext_UPML::~Engine_Ext_UPML()
curr_flux=NULL; curr_flux=NULL;
} }
void Engine_Ext_UPML::DoPreVoltageUpdates() void Engine_Ext_UPML::SetNumberOfThreads(int nrThread)
{
Engine_Extension::SetNumberOfThreads(nrThread);
m_numX = AssignJobs2Threads(m_Op_UPML->m_numLines[0],m_NrThreads,false);
m_start.resize(m_NrThreads,0);
m_start.at(0)=0;
for (size_t n=1;n<m_numX.size();++n)
m_start.at(n) = m_start.at(n-1) + m_numX.at(n-1);
}
void Engine_Ext_UPML::DoPreVoltageUpdates(int threadID)
{ {
if (m_Eng==NULL) if (m_Eng==NULL)
return; return;
if (threadID>=m_NrThreads)
return;
unsigned int pos[3]; unsigned int pos[3];
unsigned int loc_pos[3]; unsigned int loc_pos[3];
switch (m_Eng->GetType()) switch (m_Eng->GetType())
{ {
case Engine::BASIC: case Engine::BASIC:
{ {
for (loc_pos[0]=0;loc_pos[0]<m_Op_UPML->m_numLines[0];++loc_pos[0]) for (unsigned int lineX=0;lineX<m_numX.at(threadID);++lineX)
{ {
loc_pos[0]=lineX+m_start.at(threadID);
pos[0] = loc_pos[0] + m_Op_UPML->m_StartPos[0]; pos[0] = loc_pos[0] + m_Op_UPML->m_StartPos[0];
for (loc_pos[1]=0;loc_pos[1]<m_Op_UPML->m_numLines[1];++loc_pos[1]) for (loc_pos[1]=0;loc_pos[1]<m_Op_UPML->m_numLines[1];++loc_pos[1])
{ {
@ -86,8 +105,9 @@ void Engine_Ext_UPML::DoPreVoltageUpdates()
case Engine::SSE: case Engine::SSE:
{ {
Engine_sse* eng_sse = (Engine_sse*) m_Eng; Engine_sse* eng_sse = (Engine_sse*) m_Eng;
for (loc_pos[0]=0;loc_pos[0]<m_Op_UPML->m_numLines[0];++loc_pos[0]) for (unsigned int lineX=0;lineX<m_numX.at(threadID);++lineX)
{ {
loc_pos[0]=lineX+m_start.at(threadID);
pos[0] = loc_pos[0] + m_Op_UPML->m_StartPos[0]; pos[0] = loc_pos[0] + m_Op_UPML->m_StartPos[0];
for (loc_pos[1]=0;loc_pos[1]<m_Op_UPML->m_numLines[1];++loc_pos[1]) for (loc_pos[1]=0;loc_pos[1]<m_Op_UPML->m_numLines[1];++loc_pos[1])
{ {
@ -114,8 +134,9 @@ void Engine_Ext_UPML::DoPreVoltageUpdates()
} }
default: default:
{ {
for (loc_pos[0]=0;loc_pos[0]<m_Op_UPML->m_numLines[0];++loc_pos[0]) for (unsigned int lineX=0;lineX<m_numX.at(threadID);++lineX)
{ {
loc_pos[0]=lineX+m_start.at(threadID);
pos[0] = loc_pos[0] + m_Op_UPML->m_StartPos[0]; pos[0] = loc_pos[0] + m_Op_UPML->m_StartPos[0];
for (loc_pos[1]=0;loc_pos[1]<m_Op_UPML->m_numLines[1];++loc_pos[1]) for (loc_pos[1]=0;loc_pos[1]<m_Op_UPML->m_numLines[1];++loc_pos[1])
{ {
@ -143,10 +164,12 @@ void Engine_Ext_UPML::DoPreVoltageUpdates()
} }
void Engine_Ext_UPML::DoPostVoltageUpdates() void Engine_Ext_UPML::DoPostVoltageUpdates(int threadID)
{ {
if (m_Eng==NULL) if (m_Eng==NULL)
return; return;
if (threadID>=m_NrThreads)
return;
unsigned int pos[3]; unsigned int pos[3];
unsigned int loc_pos[3]; unsigned int loc_pos[3];
@ -155,8 +178,9 @@ void Engine_Ext_UPML::DoPostVoltageUpdates()
{ {
case Engine::BASIC: case Engine::BASIC:
{ {
for (loc_pos[0]=0;loc_pos[0]<m_Op_UPML->m_numLines[0];++loc_pos[0]) for (unsigned int lineX=0;lineX<m_numX.at(threadID);++lineX)
{ {
loc_pos[0]=lineX+m_start.at(threadID);
pos[0] = loc_pos[0] + m_Op_UPML->m_StartPos[0]; pos[0] = loc_pos[0] + m_Op_UPML->m_StartPos[0];
for (loc_pos[1]=0;loc_pos[1]<m_Op_UPML->m_numLines[1];++loc_pos[1]) for (loc_pos[1]=0;loc_pos[1]<m_Op_UPML->m_numLines[1];++loc_pos[1])
{ {
@ -181,8 +205,9 @@ void Engine_Ext_UPML::DoPostVoltageUpdates()
case Engine::SSE: case Engine::SSE:
{ {
Engine_sse* eng_sse = (Engine_sse*) m_Eng; Engine_sse* eng_sse = (Engine_sse*) m_Eng;
for (loc_pos[0]=0;loc_pos[0]<m_Op_UPML->m_numLines[0];++loc_pos[0]) for (unsigned int lineX=0;lineX<m_numX.at(threadID);++lineX)
{ {
loc_pos[0]=lineX+m_start.at(threadID);
pos[0] = loc_pos[0] + m_Op_UPML->m_StartPos[0]; pos[0] = loc_pos[0] + m_Op_UPML->m_StartPos[0];
for (loc_pos[1]=0;loc_pos[1]<m_Op_UPML->m_numLines[1];++loc_pos[1]) for (loc_pos[1]=0;loc_pos[1]<m_Op_UPML->m_numLines[1];++loc_pos[1])
{ {
@ -206,8 +231,9 @@ void Engine_Ext_UPML::DoPostVoltageUpdates()
} }
default: default:
{ {
for (loc_pos[0]=0;loc_pos[0]<m_Op_UPML->m_numLines[0];++loc_pos[0]) for (unsigned int lineX=0;lineX<m_numX.at(threadID);++lineX)
{ {
loc_pos[0]=lineX+m_start.at(threadID);
pos[0] = loc_pos[0] + m_Op_UPML->m_StartPos[0]; pos[0] = loc_pos[0] + m_Op_UPML->m_StartPos[0];
for (loc_pos[1]=0;loc_pos[1]<m_Op_UPML->m_numLines[1];++loc_pos[1]) for (loc_pos[1]=0;loc_pos[1]<m_Op_UPML->m_numLines[1];++loc_pos[1])
{ {
@ -232,10 +258,12 @@ void Engine_Ext_UPML::DoPostVoltageUpdates()
} }
void Engine_Ext_UPML::DoPreCurrentUpdates() void Engine_Ext_UPML::DoPreCurrentUpdates(int threadID)
{ {
if (m_Eng==NULL) if (m_Eng==NULL)
return; return;
if (threadID>=m_NrThreads)
return;
unsigned int pos[3]; unsigned int pos[3];
unsigned int loc_pos[3]; unsigned int loc_pos[3];
@ -245,8 +273,9 @@ void Engine_Ext_UPML::DoPreCurrentUpdates()
{ {
case Engine::BASIC: case Engine::BASIC:
{ {
for (loc_pos[0]=0;loc_pos[0]<m_Op_UPML->m_numLines[0];++loc_pos[0]) for (unsigned int lineX=0;lineX<m_numX.at(threadID);++lineX)
{ {
loc_pos[0]=lineX+m_start.at(threadID);
pos[0] = loc_pos[0] + m_Op_UPML->m_StartPos[0]; pos[0] = loc_pos[0] + m_Op_UPML->m_StartPos[0];
for (loc_pos[1]=0;loc_pos[1]<m_Op_UPML->m_numLines[1];++loc_pos[1]) for (loc_pos[1]=0;loc_pos[1]<m_Op_UPML->m_numLines[1];++loc_pos[1])
{ {
@ -274,8 +303,9 @@ void Engine_Ext_UPML::DoPreCurrentUpdates()
case Engine::SSE: case Engine::SSE:
{ {
Engine_sse* eng_sse = (Engine_sse*) m_Eng; Engine_sse* eng_sse = (Engine_sse*) m_Eng;
for (loc_pos[0]=0;loc_pos[0]<m_Op_UPML->m_numLines[0];++loc_pos[0]) for (unsigned int lineX=0;lineX<m_numX.at(threadID);++lineX)
{ {
loc_pos[0]=lineX+m_start.at(threadID);
pos[0] = loc_pos[0] + m_Op_UPML->m_StartPos[0]; pos[0] = loc_pos[0] + m_Op_UPML->m_StartPos[0];
for (loc_pos[1]=0;loc_pos[1]<m_Op_UPML->m_numLines[1];++loc_pos[1]) for (loc_pos[1]=0;loc_pos[1]<m_Op_UPML->m_numLines[1];++loc_pos[1])
{ {
@ -303,8 +333,9 @@ void Engine_Ext_UPML::DoPreCurrentUpdates()
} }
default: default:
{ {
for (loc_pos[0]=0;loc_pos[0]<m_Op_UPML->m_numLines[0];++loc_pos[0]) for (unsigned int lineX=0;lineX<m_numX.at(threadID);++lineX)
{ {
loc_pos[0]=lineX+m_start.at(threadID);
pos[0] = loc_pos[0] + m_Op_UPML->m_StartPos[0]; pos[0] = loc_pos[0] + m_Op_UPML->m_StartPos[0];
for (loc_pos[1]=0;loc_pos[1]<m_Op_UPML->m_numLines[1];++loc_pos[1]) for (loc_pos[1]=0;loc_pos[1]<m_Op_UPML->m_numLines[1];++loc_pos[1])
{ {
@ -331,10 +362,12 @@ void Engine_Ext_UPML::DoPreCurrentUpdates()
} }
} }
void Engine_Ext_UPML::DoPostCurrentUpdates() void Engine_Ext_UPML::DoPostCurrentUpdates(int threadID)
{ {
if (m_Eng==NULL) if (m_Eng==NULL)
return; return;
if (threadID>=m_NrThreads)
return;
unsigned int pos[3]; unsigned int pos[3];
unsigned int loc_pos[3]; unsigned int loc_pos[3];
@ -343,8 +376,9 @@ void Engine_Ext_UPML::DoPostCurrentUpdates()
{ {
case Engine::BASIC: case Engine::BASIC:
{ {
for (loc_pos[0]=0;loc_pos[0]<m_Op_UPML->m_numLines[0];++loc_pos[0]) for (unsigned int lineX=0;lineX<m_numX.at(threadID);++lineX)
{ {
loc_pos[0]=lineX+m_start.at(threadID);
pos[0] = loc_pos[0] + m_Op_UPML->m_StartPos[0]; pos[0] = loc_pos[0] + m_Op_UPML->m_StartPos[0];
for (loc_pos[1]=0;loc_pos[1]<m_Op_UPML->m_numLines[1];++loc_pos[1]) for (loc_pos[1]=0;loc_pos[1]<m_Op_UPML->m_numLines[1];++loc_pos[1])
{ {
@ -369,8 +403,9 @@ void Engine_Ext_UPML::DoPostCurrentUpdates()
case Engine::SSE: case Engine::SSE:
{ {
Engine_sse* eng_sse = (Engine_sse*) m_Eng; Engine_sse* eng_sse = (Engine_sse*) m_Eng;
for (loc_pos[0]=0;loc_pos[0]<m_Op_UPML->m_numLines[0];++loc_pos[0]) for (unsigned int lineX=0;lineX<m_numX.at(threadID);++lineX)
{ {
loc_pos[0]=lineX+m_start.at(threadID);
pos[0] = loc_pos[0] + m_Op_UPML->m_StartPos[0]; pos[0] = loc_pos[0] + m_Op_UPML->m_StartPos[0];
for (loc_pos[1]=0;loc_pos[1]<m_Op_UPML->m_numLines[1];++loc_pos[1]) for (loc_pos[1]=0;loc_pos[1]<m_Op_UPML->m_numLines[1];++loc_pos[1])
{ {
@ -394,8 +429,9 @@ void Engine_Ext_UPML::DoPostCurrentUpdates()
} }
default: default:
{ {
for (loc_pos[0]=0;loc_pos[0]<m_Op_UPML->m_numLines[0];++loc_pos[0]) for (unsigned int lineX=0;lineX<m_numX.at(threadID);++lineX)
{ {
loc_pos[0]=lineX+m_start.at(threadID);
pos[0] = loc_pos[0] + m_Op_UPML->m_StartPos[0]; pos[0] = loc_pos[0] + m_Op_UPML->m_StartPos[0];
for (loc_pos[1]=0;loc_pos[1]<m_Op_UPML->m_numLines[1];++loc_pos[1]) for (loc_pos[1]=0;loc_pos[1]<m_Op_UPML->m_numLines[1];++loc_pos[1])
{ {

View File

@ -30,15 +30,24 @@ public:
Engine_Ext_UPML(Operator_Ext_UPML* op_ext); Engine_Ext_UPML(Operator_Ext_UPML* op_ext);
virtual ~Engine_Ext_UPML(); virtual ~Engine_Ext_UPML();
virtual void DoPreVoltageUpdates(); virtual void SetNumberOfThreads(int nrThread);
virtual void DoPostVoltageUpdates();
virtual void DoPreCurrentUpdates(); virtual void DoPreVoltageUpdates() {Engine_Ext_UPML::DoPreVoltageUpdates(0);};
virtual void DoPostCurrentUpdates(); virtual void DoPreVoltageUpdates(int threadID);
virtual void DoPostVoltageUpdates() {Engine_Ext_UPML::DoPostVoltageUpdates(0);};
virtual void DoPostVoltageUpdates(int threadID);
virtual void DoPreCurrentUpdates() {Engine_Ext_UPML::DoPreCurrentUpdates(0);};
virtual void DoPreCurrentUpdates(int threadID);
virtual void DoPostCurrentUpdates() {Engine_Ext_UPML::DoPostCurrentUpdates(0);};
virtual void DoPostCurrentUpdates(int threadID);
protected: protected:
Operator_Ext_UPML* m_Op_UPML; Operator_Ext_UPML* m_Op_UPML;
vector<unsigned int> m_start;
vector<unsigned int> m_numX;
FDTD_FLOAT**** volt; FDTD_FLOAT**** volt;
FDTD_FLOAT**** curr; FDTD_FLOAT**** curr;
FDTD_FLOAT**** volt_flux; FDTD_FLOAT**** volt_flux;

View File

@ -24,12 +24,62 @@ Engine_Extension::Engine_Extension(Operator_Extension* op_ext)
m_Op_ext = op_ext; m_Op_ext = op_ext;
m_Eng = NULL; m_Eng = NULL;
m_Priority = 0; m_Priority = 0;
m_NrThreads = 1;
} }
Engine_Extension::~Engine_Extension() Engine_Extension::~Engine_Extension()
{ {
} }
void Engine_Extension::SetNumberOfThreads(int nrThread)
{
if (nrThread<1)
return;
m_NrThreads=nrThread;
}
void Engine_Extension::DoPreVoltageUpdates(int threadID)
{
//if this method gets called the derived extension obviously doesn't support multithrading, calling non-MT method...
if (threadID==0)
DoPreVoltageUpdates();
}
void Engine_Extension::DoPostVoltageUpdates(int threadID)
{
//if this method gets called the derived extension obviously doesn't support multithrading, calling non-MT method...
if (threadID==0)
DoPostVoltageUpdates();
}
void Engine_Extension::Apply2Voltages(int threadID)
{
//if this method gets called the derived extension obviously doesn't support multithrading, calling non-MT method...
if (threadID==0)
Apply2Voltages();
}
void Engine_Extension::DoPreCurrentUpdates(int threadID)
{
//if this method gets called the derived extension obviously doesn't support multithrading, calling non-MT method...
if (threadID==0)
DoPreCurrentUpdates();
}
void Engine_Extension::DoPostCurrentUpdates(int threadID)
{
//if this method gets called the derived extension obviously doesn't support multithrading, calling non-MT method...
if (threadID==0)
DoPostCurrentUpdates();
}
void Engine_Extension::Apply2Current(int threadID)
{
//if this method gets called the derived extension obviously doesn't support multithrading, calling non-MT method...
if (threadID==0)
Apply2Current();
}
bool Engine_Extension::operator< (const Engine_Extension& other) bool Engine_Extension::operator< (const Engine_Extension& other)
{ {
return (GetPriority()<other.GetPriority()); return (GetPriority()<other.GetPriority());

View File

@ -27,19 +27,27 @@ class Engine_Extension
public: public:
virtual ~Engine_Extension(); virtual ~Engine_Extension();
virtual void SetNumberOfThreads(int nrThread);
//! This methode will be called __before__ the main engine does the usual voltage updates. This methode may __not__ change the engine voltages!!! //! This methode will be called __before__ the main engine does the usual voltage updates. This methode may __not__ change the engine voltages!!!
virtual void DoPreVoltageUpdates() {} virtual void DoPreVoltageUpdates() {}
virtual void DoPreVoltageUpdates(int threadID);
//! This methode will be called __after__ the main engine does the usual voltage updates. This methode may __not__ change the engine voltages!!! //! This methode will be called __after__ the main engine does the usual voltage updates. This methode may __not__ change the engine voltages!!!
virtual void DoPostVoltageUpdates() {} virtual void DoPostVoltageUpdates() {}
virtual void DoPostVoltageUpdates(int threadID);
//! This methode will be called __after__ all updates to the voltages and extensions and may add/set its results to the engine voltages, but may __not__ rely on the current value of the engine voltages!!! //! This methode will be called __after__ all updates to the voltages and extensions and may add/set its results to the engine voltages, but may __not__ rely on the current value of the engine voltages!!!
virtual void Apply2Voltages() {} virtual void Apply2Voltages() {}
virtual void Apply2Voltages(int threadID);
//! This methode will be called __before__ the main engine does the usual current updates. This methode may __not__ change the engine current!!! //! This methode will be called __before__ the main engine does the usual current updates. This methode may __not__ change the engine current!!!
virtual void DoPreCurrentUpdates() {} virtual void DoPreCurrentUpdates() {}
virtual void DoPreCurrentUpdates(int threadID);
//! This methode will be called __after__ the main engine does the usual current updates. This methode may __not__ change the engine current!!! //! This methode will be called __after__ the main engine does the usual current updates. This methode may __not__ change the engine current!!!
virtual void DoPostCurrentUpdates() {} virtual void DoPostCurrentUpdates() {}
virtual void DoPostCurrentUpdates(int threadID);
//! This methode will be called __after__ all updates to the current and extensions and may add/set its results to the engine current, but may __not__ rely on the current value of the engine current!!! //! This methode will be called __after__ all updates to the current and extensions and may add/set its results to the engine current, but may __not__ rely on the current value of the engine current!!!
virtual void Apply2Current() {} virtual void Apply2Current() {}
virtual void Apply2Current(int threadID);
//! Set the Engine to this extention. This will usually done automatically by Engine::AddExtension //! Set the Engine to this extention. This will usually done automatically by Engine::AddExtension
virtual void SetEngine(Engine* eng) {m_Eng=eng;} virtual void SetEngine(Engine* eng) {m_Eng=eng;}
@ -59,6 +67,8 @@ protected:
Engine* m_Eng; Engine* m_Eng;
int m_Priority; int m_Priority;
int m_NrThreads;
}; };
#endif // ENGINE_EXTENSION_H #endif // ENGINE_EXTENSION_H

View File

@ -48,14 +48,7 @@ Engine_Multithread::Engine_Multithread(const Operator_Multithread* op) : Engine_
{ {
m_Op_MT = op; m_Op_MT = op;
m_type = SSE; m_type = SSE;
m_barrier_VoltUpdate = 0; m_IterateBarrier = 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_startBarrier = 0;
m_stopBarrier = 0; m_stopBarrier = 0;
} }
@ -101,15 +94,7 @@ void Engine_Multithread::Init()
m_Op_MT->CalcStartStopLines( m_numThreads, m_Start_Lines, m_Stop_Lines ); m_Op_MT->CalcStartStopLines( m_numThreads, m_Start_Lines, m_Stop_Lines );
cout << "Multithreaded engine using " << m_numThreads << " threads. Utilization: ("; cout << "Multithreaded engine using " << m_numThreads << " threads. Utilization: (";
m_barrier_VoltUpdate = new boost::barrier(m_numThreads); // numThread workers m_IterateBarrier = new boost::barrier(m_numThreads); // numThread workers
m_barrier_VoltExcite = new boost::barrier(m_numThreads); // numThread workers
m_barrier_CurrUpdate = new boost::barrier(m_numThreads); // numThread workers
m_barrier_CurrExcite = new boost::barrier(m_numThreads); // numThread workers
m_barrier_PreVolt = new boost::barrier(m_numThreads); // numThread workers
m_barrier_PostVolt = new boost::barrier(m_numThreads); // numThread workers
m_barrier_PreCurr = new boost::barrier(m_numThreads); // numThread workers
m_barrier_PostCurr = new boost::barrier(m_numThreads); // numThread workers
m_startBarrier = new boost::barrier(m_numThreads+1); // numThread workers + 1 controller m_startBarrier = new boost::barrier(m_numThreads+1); // numThread workers + 1 controller
m_stopBarrier = new boost::barrier(m_numThreads+1); // numThread workers + 1 controller m_stopBarrier = new boost::barrier(m_numThreads+1); // numThread workers + 1 controller
@ -131,6 +116,9 @@ void Engine_Multithread::Init()
boost::thread *t = new boost::thread( NS_Engine_Multithread::thread(this,start,stop,stop_h,n) ); boost::thread *t = new boost::thread( NS_Engine_Multithread::thread(this,start,stop,stop_h,n) );
m_thread_group.add_thread( t ); m_thread_group.add_thread( t );
} }
for (size_t n=0;n<m_Eng_exts.size();++n)
m_Eng_exts.at(n)->SetNumberOfThreads(m_numThreads);
} }
void Engine_Multithread::Reset() void Engine_Multithread::Reset()
@ -146,14 +134,7 @@ void Engine_Multithread::Reset()
m_stopThreads = true; m_stopThreads = true;
m_stopBarrier->wait(); // wait for the threads to finish m_stopBarrier->wait(); // wait for the threads to finish
m_thread_group.join_all(); // wait for termination m_thread_group.join_all(); // wait for termination
delete m_barrier_VoltUpdate; m_barrier_VoltUpdate = 0; delete m_IterateBarrier; m_IterateBarrier = 0;
delete m_barrier_VoltExcite; m_barrier_VoltExcite = 0;
delete m_barrier_PreVolt; m_barrier_PreVolt = 0;
delete m_barrier_PostVolt; m_barrier_PostVolt = 0;
delete m_barrier_CurrUpdate; m_barrier_CurrUpdate = 0;
delete m_barrier_CurrExcite; m_barrier_CurrExcite = 0;
delete m_barrier_PreCurr; m_barrier_PreCurr = 0;
delete m_barrier_PostCurr; m_barrier_PostCurr = 0;
delete m_startBarrier; m_startBarrier = 0; delete m_startBarrier; m_startBarrier = 0;
delete m_stopBarrier; m_stopBarrier = 0; delete m_stopBarrier; m_stopBarrier = 0;
} }
@ -174,6 +155,67 @@ bool Engine_Multithread::IterateTS(unsigned int iterTS)
return true; return true;
} }
void Engine_Multithread::DoPreVoltageUpdates(int threadID)
{
//execute extensions in reverse order -> highest priority gets access to the voltages last
for (int n=m_Eng_exts.size()-1;n>=0;--n)
{
m_Eng_exts.at(n)->DoPreVoltageUpdates(threadID);
m_IterateBarrier->wait();
}
}
void Engine_Multithread::DoPostVoltageUpdates(int threadID)
{
//execute extensions in normal order -> highest priority gets access to the voltages first
for (size_t n=0;n<m_Eng_exts.size();++n)
{
m_Eng_exts.at(n)->DoPostVoltageUpdates(threadID);
m_IterateBarrier->wait();
}
}
void Engine_Multithread::Apply2Voltages(int threadID)
{
//execute extensions in normal order -> highest priority gets access to the voltages first
for (size_t n=0;n<m_Eng_exts.size();++n)
{
m_Eng_exts.at(n)->Apply2Voltages(threadID);
m_IterateBarrier->wait();
}
}
void Engine_Multithread::DoPreCurrentUpdates(int threadID)
{
//execute extensions in reverse order -> highest priority gets access to the currents last
for (int n=m_Eng_exts.size()-1;n>=0;--n)
{
m_Eng_exts.at(n)->DoPreCurrentUpdates(threadID);
m_IterateBarrier->wait();
}
}
void Engine_Multithread::DoPostCurrentUpdates(int threadID)
{
//execute extensions in normal order -> highest priority gets access to the currents first
for (size_t n=0;n<m_Eng_exts.size();++n)
{
m_Eng_exts.at(n)->DoPostCurrentUpdates(threadID);
m_IterateBarrier->wait();
}
}
void Engine_Multithread::Apply2Current(int threadID)
{
//execute extensions in normal order -> highest priority gets access to the currents first
for (size_t n=0;n<m_Eng_exts.size();++n)
{
m_Eng_exts.at(n)->Apply2Current(threadID);
m_IterateBarrier->wait();
}
}
// //
// ************************************************************************************************************************* // *************************************************************************************************************************
// //
@ -205,10 +247,7 @@ void thread::operator()()
for (unsigned int iter=0;iter<m_enginePtr->m_iterTS;++iter) for (unsigned int iter=0;iter<m_enginePtr->m_iterTS;++iter)
{ {
// pre voltage stuff... // pre voltage stuff...
if (m_threadID==0) m_enginePtr->DoPreVoltageUpdates(m_threadID);
m_enginePtr->DoPreVoltageUpdates();
m_enginePtr->m_barrier_PreVolt->wait();
//voltage updates //voltage updates
m_enginePtr->UpdateVoltages(m_start,m_stop-m_start+1); m_enginePtr->UpdateVoltages(m_start,m_stop-m_start+1);
@ -217,56 +256,46 @@ void thread::operator()()
DEBUG_TIME( m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); ) DEBUG_TIME( m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); )
//cout << "Thread " << boost::this_thread::get_id() << " m_barrier1 waiting..." << endl; //cout << "Thread " << boost::this_thread::get_id() << " m_barrier1 waiting..." << endl;
m_enginePtr->m_barrier_VoltUpdate->wait(); m_enginePtr->m_IterateBarrier->wait();
// record time // record time
DEBUG_TIME( m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); ) DEBUG_TIME( m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); )
//post voltage stuff... //post voltage stuff...
if (m_threadID==0) m_enginePtr->DoPostVoltageUpdates(m_threadID);
{ m_enginePtr->Apply2Voltages(m_threadID);
m_enginePtr->DoPostVoltageUpdates();
m_enginePtr->Apply2Voltages();
}
m_enginePtr->m_barrier_PostVolt->wait();
// voltage excitation (E-field excite) by the first thread // voltage excitation (E-field excite) by the first thread
if (m_threadID==0) if (m_threadID==0)
m_enginePtr->ApplyVoltageExcite(); m_enginePtr->ApplyVoltageExcite();
m_enginePtr->m_barrier_VoltExcite->wait(); m_enginePtr->m_IterateBarrier->wait();
// voltage excitation finished // voltage excitation finished
// record time // record time
DEBUG_TIME( m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); ) DEBUG_TIME( m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); )
//pre current stuff //pre current stuff
if (m_threadID==0) m_enginePtr->DoPreCurrentUpdates(m_threadID);
m_enginePtr->DoPreCurrentUpdates();
m_enginePtr->m_barrier_PreCurr->wait();
//current updates //current updates
m_enginePtr->UpdateCurrents(m_start,m_stop_h-m_start+1); m_enginePtr->UpdateCurrents(m_start,m_stop_h-m_start+1);
// record time // record time
DEBUG_TIME( m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); ) DEBUG_TIME( m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); )
m_enginePtr->m_barrier_CurrUpdate->wait(); m_enginePtr->m_IterateBarrier->wait();
// record time // record time
DEBUG_TIME( m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); ) DEBUG_TIME( m_enginePtr->m_timer_list[boost::this_thread::get_id()].push_back( timer1.elapsed() ); )
//post current stuff //post current stuff
if (m_threadID==0) m_enginePtr->DoPostCurrentUpdates(m_threadID);
{ m_enginePtr->Apply2Current(m_threadID);
m_enginePtr->DoPostCurrentUpdates();
m_enginePtr->Apply2Current();
}
m_enginePtr->m_barrier_PostCurr->wait();
// current excitation (H-field excite) by the first thread // current excitation (H-field excite) by the first thread
if (m_threadID==0) if (m_threadID==0)
m_enginePtr->ApplyCurrentExcite(); m_enginePtr->ApplyCurrentExcite();
m_enginePtr->m_barrier_CurrExcite->wait(); m_enginePtr->m_IterateBarrier->wait();
// current excitation finished // current excitation finished
if (m_threadID == 0) if (m_threadID == 0)

View File

@ -80,13 +80,20 @@ public:
//! Iterate \a iterTS number of timesteps //! Iterate \a iterTS number of timesteps
virtual bool IterateTS(unsigned int iterTS); virtual bool IterateTS(unsigned int iterTS);
virtual void DoPreVoltageUpdates(int threadID);
virtual void DoPostVoltageUpdates(int threadID);
virtual void Apply2Voltages(int threadID);
virtual void DoPreCurrentUpdates(int threadID);
virtual void DoPostCurrentUpdates(int threadID);
virtual void Apply2Current(int threadID);
protected: protected:
Engine_Multithread(const Operator_Multithread* op); Engine_Multithread(const Operator_Multithread* op);
const Operator_Multithread* m_Op_MT; const Operator_Multithread* m_Op_MT;
boost::thread_group m_thread_group; boost::thread_group m_thread_group;
boost::barrier *m_startBarrier, *m_stopBarrier; boost::barrier *m_startBarrier, *m_stopBarrier;
boost::barrier *m_barrier_VoltUpdate, *m_barrier_VoltExcite, *m_barrier_PreVolt, *m_barrier_PostVolt; boost::barrier *m_IterateBarrier;
boost::barrier *m_barrier_CurrUpdate, *m_barrier_CurrExcite, *m_barrier_PreCurr, *m_barrier_PostCurr;
volatile unsigned int m_iterTS; volatile unsigned int m_iterTS;
unsigned int m_numThreads; //!< number of worker threads unsigned int m_numThreads; //!< number of worker threads
volatile bool m_stopThreads; volatile bool m_stopThreads;