EgtGeomKernel 2.2f7 :

- in Zmap calcolo numero parti ora parallelizzato.
This commit is contained in:
Dario Sassi
2020-06-26 08:00:04 +00:00
parent 1c0749e0aa
commit c146898eae
3 changed files with 129 additions and 26 deletions
+122 -22
View File
@@ -23,6 +23,8 @@
#include "/EgtDev/Include/EGkIntervals.h"
#include "/EgtDev/Include/EGkStringUtils3d.h"
#include "/EgtDev/Include/EgtNumUtils.h"
#include <thread>
#include <future>
using namespace std ;
@@ -734,7 +736,8 @@ VolZmap::CheckMapConnection( void)
}
}
}
// Numero massimo di thread
int nThreadMax = max( 1, int( thread::hardware_concurrency()) - 1) ;
// Ciclo sui dexel lungo Z
for ( int tI = 0 ; tI < m_nNx[0] ; ++ tI) {
for ( int tJ = 0 ; tJ < m_nNy[0] ; ++ tJ) {
@@ -754,24 +757,29 @@ VolZmap::CheckMapConnection( void)
NewInt.tMap = 0 ;
NewInt.tDex = tJ * m_nNx[0] + tI ;
NewInt.tInt = tIntZ ;
// Stack di segmenti
IntContaier IntervalsToProcess ;
// Aggiungo il segmento corrente
IntervalsToProcess.push( NewInt) ;
// Processo gli intervalli trovati
while ( ! IntervalsToProcess.empty()) {
switch ( IntervalsToProcess.top().tMap) {
case 0 :
ExpandFromZInterval( IntervalsToProcess) ;
break ;
case 1 :
ExpandFromXInterval( IntervalsToProcess) ;
break ;
case 2 :
ExpandFromYInterval( IntervalsToProcess) ;
break ;
// Vettore di stack di segmenti
IntContainerVec IntervalsToProcessStackVec ;
IntervalsToProcessStackVec.resize( nThreadMax) ;
// Mi espando dal primo intervallo mettendo gli intervalli che intersecano nei vari thread
FirstExpansionFromZ( nThreadMax, NewInt, IntervalsToProcessStackVec) ;
// Lancio in parallelo più ricerche
int nActiveThread = 0 ;
vector<future<bool>> vRes ;
vRes.resize( nThreadMax) ;
for ( int i = 0 ; i < nThreadMax ; ++ i) {
if ( ! IntervalsToProcessStackVec[i].empty()) {
++ nActiveThread ;
vRes[i] = async( launch::async, &VolZmap::ProcessIntervals, this, ref( IntervalsToProcessStackVec[i])) ;
}
}
// Attendo che tutti i porcessi terminino
int nTerminated = 0 ;
while ( nTerminated < nActiveThread) {
for ( int i = 0 ; i < nThreadMax ; ++ i) {
if ( vRes[i].valid() && vRes[i].wait_for( chrono::microseconds{ 1 }) == future_status::ready) {
vRes[i].get() ;
++ nTerminated ;
}
}
}
}
@@ -788,7 +796,7 @@ VolZmap::CheckMapConnection( void)
//----------------------------------------------------------------------------
bool
VolZmap::ExpandFromXInterval( IntContaier& IntCont)
VolZmap::ExpandFromXInterval( IntContainer& IntCont)
{
// Copio i dati dell'intervallo corrente
IntervalIndexes CurrInterval = IntCont.top() ;
@@ -859,7 +867,7 @@ VolZmap::ExpandFromXInterval( IntContaier& IntCont)
//----------------------------------------------------------------------------
bool
VolZmap::ExpandFromYInterval( IntContaier& IntCont)
VolZmap::ExpandFromYInterval( IntContainer& IntCont)
{
// Copio i dati dell'intervallo corrente
IntervalIndexes CurrInterval = IntCont.top() ;
@@ -930,7 +938,7 @@ VolZmap::ExpandFromYInterval( IntContaier& IntCont)
//----------------------------------------------------------------------------
bool
VolZmap::ExpandFromZInterval( IntContaier& IntCont)
VolZmap::ExpandFromZInterval( IntContainer& IntCont)
{
// Copio i dati dell'intervallo corrente
IntervalIndexes CurrInterval = IntCont.top() ;
@@ -999,6 +1007,98 @@ VolZmap::ExpandFromZInterval( IntContaier& IntCont)
return true ;
}
//----------------------------------------------------------------------------
bool
VolZmap::FirstExpansionFromZ( int nNumThread, IntervalIndexes IntSt, IntContainerVec& IntervalsToProcessStackVec)
{
int tDex = IntSt.tDex ;
int tGrIndex1 = IntSt.tDex % m_nNx[0] ;
int tGrIndex2 = IntSt.tDex / m_nNx[0] ;
int tInt = IntSt.tInt ;
// Quote estreme del segmento lungo Z
double dMinZ = m_Values[0][tDex][tInt].dMin ;
double dMaxZ = m_Values[0][tDex][tInt].dMax ;
double dMinDZ = max( floor( ( dMinZ - 2 * EPS_SMALL) / m_dStep - 0.5), 0.) ;
double dMaxDZ = max( floor( ( dMaxZ + 2 * EPS_SMALL) / m_dStep - 0.5), 0.) ;
// Indici estremi dei dexel ortogonali
// che possono intersecare il segmento di partenza
int tStartK = min( int( dMinDZ), ( m_nNy[1] - 1)) ;
int tStopK = min( int( dMaxDZ), ( m_nNy[1] - 1)) ;
// Posizione XY del dexel
double dX = ( tGrIndex1 + 0.5) * m_dStep ;
double dY = ( tGrIndex2 + 0.5) * m_dStep ;
// Ciclo sugli indici dei dexel che potrebbero
// intersecare il segmento di partenza
int nCurStack = 0 ;
for ( int tK = tStartK ; tK <= tStopK ; ++ tK) {
// Analizzo i dexel della griglia 1.
int tStopX = int( m_Values[1][tK * m_nNx[1] + tGrIndex2].size()) ;
for ( int tIntX = 0 ; tIntX < tStopX ; ++ tIntX) {
// Estremi del segmento del dexel lungo X
double dXmin = m_Values[1][tK * m_nNx[1] + tGrIndex2][tIntX].dMin ;
double dXmax = m_Values[1][tK * m_nNx[1] + tGrIndex2][tIntX].dMax ;
// Se i segmenti si incrociano e il nuovo trovato non
// ha già un indice assegnato, assegno l'indice e
// aggiungo l'intervallo trovato allo stack.
if ( dXmin - 2 * EPS_SMALL < dX &&
dXmax + 2 * EPS_SMALL > dX &&
m_Values[1][tK * m_nNx[1] + tGrIndex2][tIntX].nCompo == 0) {
m_Values[1][tK * m_nNx[1] + tGrIndex2][tIntX].nCompo = m_Values[0][tDex][tInt].nCompo ;
IntervalIndexes NewInterval ;
NewInterval.tMap = 1 ;
NewInterval.tDex = tK * m_nNx[1] + tGrIndex2 ;
NewInterval.tInt = tIntX ;
IntervalsToProcessStackVec[nCurStack].push( NewInterval) ;
nCurStack = ( ++ nCurStack) % int( IntervalsToProcessStackVec.size()) ;
}
}
// Analizzo i dexel della griglia 2
int tStopY = int( m_Values[2][tGrIndex1 * m_nNx[2] + tK].size()) ;
for ( int tIntY = 0 ; tIntY < tStopY ; ++ tIntY) {
// Estremi del segmento del dexel lungo Y
double dYmin = m_Values[2][tGrIndex1 * m_nNx[2] + tK][tIntY].dMin ;
double dYmax = m_Values[2][tGrIndex1 * m_nNx[2] + tK][tIntY].dMax ;
// Se i segmenti si incrociano e il nuovo trovato non
// ha già un indice assegnato, assegno l'indice e
// aggiungo l'intervallo trovato allo stack.
if ( dYmin - 2 * EPS_SMALL < dY &&
dYmax + 2 * EPS_SMALL > dY &&
m_Values[2][tGrIndex1 * m_nNx[2] + tK][tIntY].nCompo == 0) {
m_Values[2][tGrIndex1 * m_nNx[2] + tK][tIntY].nCompo = m_Values[0][tDex][tInt].nCompo ;
IntervalIndexes NewInterval ;
NewInterval.tMap = 2 ;
NewInterval.tDex = tGrIndex1 * m_nNx[2] + tK ;
NewInterval.tInt = tIntY ;
IntervalsToProcessStackVec[nCurStack].push( NewInterval) ;
nCurStack = ( ++ nCurStack) % int( IntervalsToProcessStackVec.size()) ;
}
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
VolZmap::ProcessIntervals( IntContainer& IntervalsToProcess)
{
// Processo gli intervalli trovati
while ( ! IntervalsToProcess.empty()) {
switch ( IntervalsToProcess.top().tMap) {
case 0:
ExpandFromZInterval( IntervalsToProcess) ;
break ;
case 1:
ExpandFromXInterval( IntervalsToProcess) ;
break ;
case 2:
ExpandFromYInterval( IntervalsToProcess) ;
break ;
}
}
return true ;
}
//----------------------------------------------------------------------------
VolZmap*
VolZmap::ClonePart( int nPart) const