Added a temporary item cache to improve router performance

Some items only used within algorithms were never cached
Because they are hard to manually clean up
But caching them does help the algorithms a lot
So this solution is the best I can think of
This commit is contained in:
Seneral 2023-10-01 16:12:24 +02:00 committed by Alex Shvartzkop
parent a558a67fbd
commit d29c07a663
3 changed files with 29 additions and 4 deletions

View File

@ -126,6 +126,7 @@ public:
void ClearCacheForItems( std::vector<const PNS::ITEM*>& aItems ) override;
void ClearCaches() override;
void ClearTemporaryCaches() override;
private:
/**
@ -148,6 +149,7 @@ private:
int m_clearanceEpsilon;
std::unordered_map<CLEARANCE_CACHE_KEY, int> m_clearanceCache;
std::unordered_map<CLEARANCE_CACHE_KEY, int> m_tempClearanceCache;
};
@ -447,6 +449,13 @@ void PNS_PCBNEW_RULE_RESOLVER::ClearCacheForItems( std::vector<const PNS::ITEM*>
void PNS_PCBNEW_RULE_RESOLVER::ClearCaches()
{
m_clearanceCache.clear();
m_tempClearanceCache.clear();
}
void PNS_PCBNEW_RULE_RESOLVER::ClearTemporaryCaches()
{
m_tempClearanceCache.clear();
}
@ -454,11 +463,17 @@ int PNS_PCBNEW_RULE_RESOLVER::Clearance( const PNS::ITEM* aA, const PNS::ITEM* a
bool aUseClearanceEpsilon )
{
CLEARANCE_CACHE_KEY key = { aA, aB, aUseClearanceEpsilon };
auto it = m_clearanceCache.find( key );
// Search cache (used for actual board items)
auto it = m_clearanceCache.find( key );
if( it != m_clearanceCache.end() )
return it->second;
// Search cache (used for temporary items within an algorithm)
it = m_tempClearanceCache.find( key );
if( it != m_tempClearanceCache.end() )
return it->second;
PNS::CONSTRAINT constraint;
int rv = 0;
LAYER_RANGE layers;
@ -519,10 +534,17 @@ int PNS_PCBNEW_RULE_RESOLVER::Clearance( const PNS::ITEM* aA, const PNS::ITEM* a
/* It makes no sense to put items that have no owning NODE in the cache - they can be allocated on stack
and we can't really invalidate them in the cache when they are destroyed. Probably a better idea would be
to use a static unique counter in PNS::ITEM constructor to generate the cache keys. */
if( aA && aB && aA->Owner() && aB->Owner() )
to use a static unique counter in PNS::ITEM constructor to generate the cache keys. */
/* However, algorithms DO greatly benefit from using the cache, so ownerless items need to be cached.
In order to easily clear those only, a temporary cache is created. If this doesn't seem nice, an alternative
is clearing the full cache once it reaches a certain size. Also not pretty, but VERY effective
to keep things interactive. */
if( aA && aB )
{
m_clearanceCache[ key ] = rv;
if ( aA->Owner() && aB->Owner() )
m_clearanceCache[ key ] = rv;
else
m_tempClearanceCache[ key ] = rv;
}
return rv;

View File

@ -156,6 +156,7 @@ public:
virtual void ClearCacheForItems( std::vector<const PNS::ITEM*>& aItems ) {}
virtual void ClearCaches() {}
virtual void ClearTemporaryCaches() {}
virtual int ClearanceEpsilon() const { return 0; }
};

View File

@ -494,6 +494,8 @@ bool ROUTER::Move( const VECTOR2I& aP, ITEM* endItem )
break;
}
GetRuleResolver()->ClearTemporaryCaches();
return false;
}