/* * 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" #include "tools/useful.h" 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; } Operator_Multithread::~Operator_Multithread() { Delete(); } void Operator_Multithread::setNumThreads( unsigned int numThreads ) { m_numThreads = numThreads; } Engine* Operator_Multithread::CreateEngine() const { Engine_Multithread* e = Engine_Multithread::New(this,m_numThreads); return e; } Operator_Multithread::Operator_Multithread() { m_CalcEC_Start=NULL; m_CalcEC_Stop=NULL; m_CalcPEC_Start=NULL; m_CalcPEC_Stop=NULL; } void Operator_Multithread::Init() { Operator_SSE_Compressed::Init(); m_CalcEC_Start=NULL; m_CalcEC_Stop=NULL; m_CalcPEC_Start=NULL; m_CalcPEC_Stop=NULL; } void Operator_Multithread::Delete() { m_thread_group.join_all(); delete m_CalcEC_Start; m_CalcEC_Start=NULL; delete m_CalcEC_Stop; m_CalcEC_Stop=NULL; delete m_CalcPEC_Start; m_CalcPEC_Start=NULL; delete m_CalcPEC_Stop; m_CalcPEC_Stop=NULL; } void Operator_Multithread::Reset() { Delete(); Operator_SSE_Compressed::Reset(); } void Operator_Multithread::CalcStartStopLines(unsigned int &numThreads, vector &start, vector &stop) const { vector jpt = AssignJobs2Threads(numLines[0], numThreads, true); numThreads = jpt.size(); start.resize(numThreads); stop.resize(numThreads); start.at(0)=0; stop.at(0)=jpt.at(0)-1; for (unsigned int n=1; n m_Start_Lines; vector m_Stop_Lines; CalcStartStopLines( m_numThreads, m_Start_Lines, m_Stop_Lines ); cout << "Multithreaded 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 delete m_CalcPEC_Start; m_CalcPEC_Start = new boost::barrier(m_numThreads+1); // numThread workers + 1 controller delete m_CalcPEC_Stop; m_CalcPEC_Stop = new boost::barrier(m_numThreads+1); // numThread workers + 1 controller for (unsigned int n=0; nSetPos(0,0,0); m_CalcEC_Start->wait(); m_CalcEC_Stop->wait(); return true; } bool Operator_Multithread::CalcPEC() { m_Nr_PEC[0]=0; m_Nr_PEC[1]=0; m_Nr_PEC[2]=0; m_Nr_PEC_thread = new unsigned int[m_numThreads][3]; m_CalcPEC_Start->wait(); m_CalcPEC_Stop->wait(); for (unsigned int t=0; tm_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(); //************** calculate EC (Calc_EC) ***********************// m_OpPtr->m_CalcPEC_Start->wait(); for (int n=0; n<3; ++n) m_OpPtr->m_Nr_PEC_thread[m_threadID][n] = 0; m_OpPtr->CalcPEC_Range(m_start,m_stop,m_OpPtr->m_Nr_PEC_thread[m_threadID]); m_OpPtr->m_CalcPEC_Stop->wait(); }