EgtGeomKernel 2.2f7 :
- in Zmap calcolo numero parti ora parallelizzato.
This commit is contained in:
+122
-22
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user