Speedup dynamic ratsnest

Removes some unneeded calculations and threads the remaining.

Threading was previously removed to avoid overhead issues with small
boards.  This is no longer needed with the thread pool implementation

Fixes https://gitlab.com/kicad/code/kicad/issues/12131
This commit is contained in:
Seth Hillbrand 2022-10-04 17:00:08 -07:00
parent a0865082fb
commit 87171f53c7
3 changed files with 28 additions and 17 deletions

View File

@ -313,10 +313,12 @@ void CONNECTIVITY_DATA::ComputeLocalRatsnest( const std::vector<BOARD_ITEM*>& aI
return;
m_dynamicRatsnest.clear();
std::mutex dynamic_ratsnest_mutex;
// This gets connections between the stationary board and the
// moving selection
for( unsigned int nc = 1; nc < aDynamicData->m_nets.size(); nc++ )
auto update_lambda = [&]( int nc )
{
RN_NET* dynamicNet = aDynamicData->m_nets[nc];
RN_NET* staticNet = m_nets[nc];
@ -329,17 +331,25 @@ void CONNECTIVITY_DATA::ComputeLocalRatsnest( const std::vector<BOARD_ITEM*>& aI
{
VECTOR2I pos1, pos2;
if( staticNet->NearestBicoloredPair( *dynamicNet, &pos1, &pos2 ) )
if( staticNet->NearestBicoloredPair( dynamicNet, pos1, pos2 ) )
{
RN_DYNAMIC_LINE l;
l.a = pos1;
l.b = pos2;
l.netCode = nc;
std::lock_guard<std::mutex> lock( dynamic_ratsnest_mutex );
m_dynamicRatsnest.push_back( l );
}
}
}
};
GetKiCadThreadPool().parallelize_loop( 1, aDynamicData->m_nets.size(),
[&]( const int a, const int b)
{
for( int ii = a; ii < b; ++ii )
update_lambda( ii );
}).wait();
// This gets the ratsnest for internal connections in the moving set
const std::vector<CN_EDGE>& edges = GetRatsnestForItems( aItems );

View File

@ -494,7 +494,7 @@ void RN_NET::AddCluster( std::shared_ptr<CN_CLUSTER> aCluster )
}
bool RN_NET::NearestBicoloredPair( const RN_NET& aOtherNet, VECTOR2I* aPos1, VECTOR2I* aPos2 ) const
bool RN_NET::NearestBicoloredPair( RN_NET* aOtherNet, VECTOR2I& aPos1, VECTOR2I& aPos2 ) const
{
bool rv = false;
@ -511,32 +511,36 @@ bool RN_NET::NearestBicoloredPair( const RN_NET& aOtherNet, VECTOR2I* aPos1, VEC
{
rv = true;
distMax_sq = dist_sq;
*aPos1 = aTestNode1->Pos();
*aPos2 = aTestNode2->Pos();
aPos1 = aTestNode1->Pos();
aPos2 = aTestNode2->Pos();
}
};
std::multiset<std::shared_ptr<CN_ANCHOR>, CN_PTR_CMP> nodes_b;
std::copy_if( m_nodes.begin(), m_nodes.end(), std::inserter( nodes_b, nodes_b.end() ),
[]( const std::shared_ptr<CN_ANCHOR> &aVal )
{ return !aVal->GetNoLine(); } );
/// Sweep-line algorithm to cut the number of comparisons to find the closest point
///
/// Step 1: The outer loop needs to be the subset (selected nodes) as it is a linear search
for( const std::shared_ptr<CN_ANCHOR>& nodeA : aOtherNet.m_nodes )
for( const std::shared_ptr<CN_ANCHOR>& nodeA : aOtherNet->m_nodes )
{
if( nodeA->GetNoLine() )
continue;
/// Step 2: O( log n ) search to identify a close element ordered by x
/// The fwd_it iterator will move forward through the elements while
/// the rev_it iterator will move backward through the same set
auto fwd_it = m_nodes.lower_bound( nodeA );
auto fwd_it = nodes_b.lower_bound( nodeA );
auto rev_it = std::make_reverse_iterator( fwd_it );
for( ; fwd_it != m_nodes.end(); ++fwd_it )
for( ; fwd_it != nodes_b.end(); ++fwd_it )
{
const std::shared_ptr<CN_ANCHOR>& nodeB = *fwd_it;
if( nodeB->GetNoLine() )
continue;
SEG::ecoord distX_sq = SEG::Square( nodeA->Pos().x - nodeB->Pos().x );
/// As soon as the x distance (primary sort) is larger than the smallest distance,
@ -548,13 +552,10 @@ bool RN_NET::NearestBicoloredPair( const RN_NET& aOtherNet, VECTOR2I* aPos1, VEC
}
/// Step 3: using the same starting point, check points backwards for closer points
for( ; rev_it != m_nodes.rend(); ++rev_it )
for( ; rev_it != nodes_b.rend(); ++rev_it )
{
const std::shared_ptr<CN_ANCHOR>& nodeB = *rev_it;
if( nodeB->GetNoLine() )
continue;
SEG::ecoord distX_sq = SEG::Square( nodeA->Pos().x - nodeB->Pos().x );
if( distX_sq > distMax_sq )

View File

@ -90,7 +90,7 @@ public:
const std::vector<CN_EDGE>& GetEdges() const { return m_rnEdges; }
std::vector<CN_EDGE>& GetEdges() { return m_rnEdges; }
bool NearestBicoloredPair( const RN_NET& aOtherNet, VECTOR2I* aPos1, VECTOR2I* aPos2 ) const;
bool NearestBicoloredPair( RN_NET* aOtherNet, VECTOR2I& aPos1, VECTOR2I& aPos2 ) const;
protected:
///< Recompute ratsnest from scratch.