Fix routing perf regression from clearance cache
The clearance cache added in b0d0dd57ef invalidates on every
SetLayer() and SetNetCode() call. The router's rule resolver
calls SetLayer() on dummy board items for every clearance
evaluation during routing. Each call acquires an exclusive
lock and linearly scans the entire cache, but dummy items
never exist in the cache, so this is pure waste.
Skip cache invalidation for items flagged ROUTER_TRANSIENT.
The flag is already set on all dummy items in the rule
resolver.
Also replace the O(n) linear scan in InvalidateClearanceCache
with targeted O(1) hash erasure per copper layer.
This commit is contained in:
@@ -53,9 +53,11 @@ void BOARD_CONNECTED_ITEM::SetLayer( PCB_LAYER_ID aLayer )
|
||||
{
|
||||
BOARD_ITEM::SetLayer( aLayer );
|
||||
|
||||
// Invalidate clearance cache since layer can affect clearance rules
|
||||
if( BOARD* board = GetBoard() )
|
||||
board->InvalidateClearanceCache( m_Uuid );
|
||||
if( !( GetFlags() & ROUTER_TRANSIENT ) )
|
||||
{
|
||||
if( BOARD* board = GetBoard() )
|
||||
board->InvalidateClearanceCache( m_Uuid );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -103,10 +105,10 @@ bool BOARD_CONNECTED_ITEM::SetNetCode( int aNetCode, bool aNoAssert )
|
||||
if( !aNoAssert )
|
||||
wxASSERT( m_netinfo );
|
||||
|
||||
// Invalidate clearance cache since net can affect clearance rules
|
||||
if( board )
|
||||
{
|
||||
board->InvalidateClearanceCache( m_Uuid );
|
||||
if( !( GetFlags() & ROUTER_TRANSIENT ) )
|
||||
board->InvalidateClearanceCache( m_Uuid );
|
||||
|
||||
std::unique_lock<std::shared_mutex> writeLock( board->m_CachesMutex );
|
||||
board->m_ItemNetclassCache.erase( this );
|
||||
|
||||
@@ -2553,15 +2553,24 @@ void DRC_ENGINE::InvalidateClearanceCache( const KIID& aUuid )
|
||||
{
|
||||
std::unique_lock<std::shared_mutex> writeLock( m_clearanceCacheMutex );
|
||||
|
||||
// Remove all entries for this item (across all layers)
|
||||
auto it = m_ownClearanceCache.begin();
|
||||
|
||||
while( it != m_ownClearanceCache.end() )
|
||||
if( m_board )
|
||||
{
|
||||
if( it->first.m_uuid == aUuid )
|
||||
it = m_ownClearanceCache.erase( it );
|
||||
else
|
||||
++it;
|
||||
LSET copperLayers = m_board->GetEnabledLayers() & LSET::AllCuMask();
|
||||
|
||||
for( PCB_LAYER_ID layer : copperLayers.Seq() )
|
||||
m_ownClearanceCache.erase( DRC_OWN_CLEARANCE_CACHE_KEY{ aUuid, layer } );
|
||||
}
|
||||
else
|
||||
{
|
||||
auto it = m_ownClearanceCache.begin();
|
||||
|
||||
while( it != m_ownClearanceCache.end() )
|
||||
{
|
||||
if( it->first.m_uuid == aUuid )
|
||||
it = m_ownClearanceCache.erase( it );
|
||||
else
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-6
@@ -1388,9 +1388,11 @@ void PAD::SetAttribute( PAD_ATTRIB aAttribute )
|
||||
break;
|
||||
}
|
||||
|
||||
// Invalidate clearance cache since pad type affects constraint evaluation
|
||||
if( BOARD* board = GetBoard() )
|
||||
board->InvalidateClearanceCache( m_Uuid );
|
||||
if( !( GetFlags() & ROUTER_TRANSIENT ) )
|
||||
{
|
||||
if( BOARD* board = GetBoard() )
|
||||
board->InvalidateClearanceCache( m_Uuid );
|
||||
}
|
||||
}
|
||||
|
||||
SetDirty();
|
||||
@@ -1619,9 +1621,11 @@ void PAD::SetLayerSet( const LSET& aLayers )
|
||||
m_padStack.SetLayerSet( aLayers );
|
||||
SetDirty();
|
||||
|
||||
// Invalidate clearance cache since layer set can affect clearance rules
|
||||
if( BOARD* board = GetBoard() )
|
||||
board->InvalidateClearanceCache( m_Uuid );
|
||||
if( !( GetFlags() & ROUTER_TRANSIENT ) )
|
||||
{
|
||||
if( BOARD* board = GetBoard() )
|
||||
board->InvalidateClearanceCache( m_Uuid );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+15
-9
@@ -1643,9 +1643,11 @@ void PCB_VIA::SetLayerPair( PCB_LAYER_ID aTopLayer, PCB_LAYER_ID aBottomLayer )
|
||||
Padstack().Drill().end = aBottomLayer;
|
||||
SanitizeLayers();
|
||||
|
||||
// Invalidate clearance cache since layer can affect clearance rules
|
||||
if( BOARD* board = GetBoard() )
|
||||
board->InvalidateClearanceCache( m_Uuid );
|
||||
if( !( GetFlags() & ROUTER_TRANSIENT ) )
|
||||
{
|
||||
if( BOARD* board = GetBoard() )
|
||||
board->InvalidateClearanceCache( m_Uuid );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1658,9 +1660,11 @@ void PCB_VIA::SetTopLayer( PCB_LAYER_ID aLayer )
|
||||
Padstack().Drill().start = aLayer;
|
||||
SanitizeLayers();
|
||||
|
||||
// Invalidate clearance cache since layer can affect clearance rules
|
||||
if( BOARD* board = GetBoard() )
|
||||
board->InvalidateClearanceCache( m_Uuid );
|
||||
if( !( GetFlags() & ROUTER_TRANSIENT ) )
|
||||
{
|
||||
if( BOARD* board = GetBoard() )
|
||||
board->InvalidateClearanceCache( m_Uuid );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1673,9 +1677,11 @@ void PCB_VIA::SetBottomLayer( PCB_LAYER_ID aLayer )
|
||||
Padstack().Drill().end = aLayer;
|
||||
SanitizeLayers();
|
||||
|
||||
// Invalidate clearance cache since layer can affect clearance rules
|
||||
if( BOARD* board = GetBoard() )
|
||||
board->InvalidateClearanceCache( m_Uuid );
|
||||
if( !( GetFlags() & ROUTER_TRANSIENT ) )
|
||||
{
|
||||
if( BOARD* board = GetBoard() )
|
||||
board->InvalidateClearanceCache( m_Uuid );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user