Solve algorithmic execution time of Anabatic layer assignement.

* Change: In AnabaticEngine::_desaturate(), now use a STL priority
    queue built upon a vector with duplicates of the GCell keys.
      Much much more faster than the previous set with a custom
    sorting key over the GCell. Insertion & removal where getting
    a lot of time. Now it's down to less than a minutes, even for
    big designs.
* Change; In Anabatic::GCells, add the ability to clone the GCell
    key, to use it independently in GCells sorting containers.
      This way the cloned value do not change when the GCell is
    updated. Keep track of the latest (most up to date) cloned
    key.
This commit is contained in:
Jean-Paul Chaput 2020-08-05 01:27:26 +02:00
parent 78b7e683e5
commit 85d7714910
3 changed files with 155 additions and 76 deletions

View File

@ -306,6 +306,7 @@ namespace Anabatic {
, _fragmentations(new float [_depth]) , _fragmentations(new float [_depth])
, _globalsCount (new float [_depth]) , _globalsCount (new float [_depth])
, _key (this,1) , _key (this,1)
, _lastClonedKey (NULL)
{ {
if (not _matrixHSide) { if (not _matrixHSide) {
_matrixVSide = Session::getSliceHeight(); _matrixVSide = Session::getSliceHeight();

View File

@ -336,6 +336,51 @@ namespace Anabatic {
cmess1 << " o Desaturate layer " cmess1 << " o Desaturate layer "
<< Session::getRoutingGauge()->getRoutingLayer(depth)->getName() << endl; << Session::getRoutingGauge()->getRoutingLayer(depth)->getName() << endl;
GCellKeyQueue queue;
GCell::Set invalidateds;
for ( GCell* gcell : getGCells() ) queue.push( gcell->cloneKey(depth) );
bool optimized = true;
bool finished = false;
while ( optimized ) {
Session::revalidate ();
optimized = false;
while ( not queue.empty() ) {
GCell::Key* topKey = queue.top();
GCell* gcell = const_cast<GCell*>( topKey->getGCell() );
queue.pop();
if (topKey->isActive()) {
cdebug_log(149,0) << "_desaturate: [" << depth << "]:"
<< gcell->getDensity(depth) << " " << gcell << endl;
if (not gcell->isSaturated(depth)) {
cdebug_log(149,0) << "STOP desaturated: " << gcell << endl;
finished = true;
} else {
if (finished) {
cparanoid << "[ERROR] Still saturated: " << gcell << endl;
}
}
if (not finished) {
optimized = gcell->stepNetDesaturate( depth, globalNets, invalidateds );
if (optimized) {
for ( GCell* gcell : invalidateds ) {
queue.push( gcell->cloneKey(depth) );
}
}
}
}
delete topKey;
}
}
#if OLD_QUEUE_DISABLED
GCellDensitySet queue ( depth, getGCells() ); GCellDensitySet queue ( depth, getGCells() );
GCell::Set invalidateds; GCell::Set invalidateds;
@ -371,6 +416,7 @@ namespace Anabatic {
} }
} }
} }
#endif
} }

View File

@ -14,10 +14,9 @@
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
#ifndef ANABATIC_GCELL_H #pragma once
#define ANABATIC_GCELL_H
#include <vector> #include <vector>
#include <queue>
#include <string> #include <string>
#include <set> #include <set>
#include <functional> #include <functional>
@ -115,13 +114,20 @@ namespace Anabatic {
public: public:
class Key { class Key {
public: public:
inline Key ( GCell*, size_t depth ); inline Key ( const GCell*, size_t depth );
inline ~Key ();
inline float getDensity () const; inline float getDensity () const;
inline GCell* getGCell () const; inline const GCell* getGCell () const;
inline bool isActive () const;
inline void update ( size_t depth ); inline void update ( size_t depth );
friend bool operator< ( const Key&, const Key& ); friend bool operator< ( const Key&, const Key& );
public:
class Compare {
public:
inline bool operator() ( const Key*, const Key* );
};
private: private:
GCell* _gcell; const GCell* _gcell;
float _density; float _density;
}; };
public: public:
@ -242,6 +248,9 @@ namespace Anabatic {
inline AutoSegments getStopSegments ( Flags direction ); inline AutoSegments getStopSegments ( Flags direction );
size_t getRoutingPads ( set<RoutingPad*>& ); size_t getRoutingPads ( set<RoutingPad*>& );
inline const Key& getKey () const; inline const Key& getKey () const;
inline Key* cloneKey ( size_t depth ) const;
inline Key* getLastClonedKey () const;
inline void clearClonedKey () const;
size_t checkDensity () const; size_t checkDensity () const;
bool checkEdgeSaturation ( size_t hreserved, size_t vreserved) const; bool checkEdgeSaturation ( size_t hreserved, size_t vreserved) const;
void setType ( Flags ); void setType ( Flags );
@ -330,6 +339,7 @@ namespace Anabatic {
float* _fragmentations; float* _fragmentations;
float* _globalsCount; float* _globalsCount;
Key _key; Key _key;
mutable Key* _lastClonedKey;
}; };
@ -387,6 +397,9 @@ namespace Anabatic {
inline float GCell::getDensity ( size_t depth ) const { return (depth<_depth) ? _densities[depth] : 0.0; } inline float GCell::getDensity ( size_t depth ) const { return (depth<_depth) ? _densities[depth] : 0.0; }
inline const GCell::Key& GCell::getKey () const { return _key; } inline const GCell::Key& GCell::getKey () const { return _key; }
inline GCell::Key* GCell::cloneKey ( size_t depth ) const { _lastClonedKey = new Key(this,depth); return _lastClonedKey; }
inline void GCell::clearClonedKey () const { _lastClonedKey=NULL; }
inline GCell::Key* GCell::getLastClonedKey () const { return _lastClonedKey; }
inline void GCell::setType ( Flags type ) { _flags.reset(Flags::GCellTypeMask); _flags |= (type&Flags::GCellTypeMask); }; inline void GCell::setType ( Flags type ) { _flags.reset(Flags::GCellTypeMask); _flags |= (type&Flags::GCellTypeMask); };
inline void GCell::updateKey ( size_t depth ) { _key.update(depth); } inline void GCell::updateKey ( size_t depth ) { _key.update(depth); }
inline const Flags& GCell::flags () const { return _flags; } inline const Flags& GCell::flags () const { return _flags; }
@ -478,17 +491,24 @@ namespace Anabatic {
return lhs.getId() < rhs.getId(); return lhs.getId() < rhs.getId();
} }
// GCell::CompareByKey Inline Functions. // GCell::CompareByKey Inline Functions.
inline bool GCell::CompareByKey::operator() ( const GCell* lhs, const GCell* rhs ) inline bool GCell::CompareByKey::operator() ( const GCell* lhs, const GCell* rhs )
{ return lhs->getKey() < rhs->getKey(); } { return lhs->getKey() < rhs->getKey(); }
// GCell::Key Inline Functions. // GCell::Key Inline Functions.
inline GCell::Key::Key ( GCell* owner, size_t depth ) : _gcell(owner), _density(owner->getWDensity(depth,Flags::NoUpdate)) {} inline GCell::Key::Key ( const GCell* owner, size_t depth )
: _gcell(owner)
, _density(owner->getWDensity(depth,Flags::NoUpdate))
{ }
inline GCell::Key::~Key ()
{ if (isActive()) _gcell->clearClonedKey(); }
inline float GCell::Key::getDensity () const { return _density; } inline float GCell::Key::getDensity () const { return _density; }
inline GCell* GCell::Key::getGCell () const { return _gcell; } inline const GCell* GCell::Key::getGCell () const { return _gcell; }
inline void GCell::Key::update ( size_t depth ) { _density=_gcell->getWDensity(depth); } inline void GCell::Key::update ( size_t depth ) { _density=_gcell->getWDensity(depth); }
inline bool GCell::Key::isActive () const { return (this == _gcell->getLastClonedKey()); }
inline bool operator< ( const GCell::Key& lhs, const GCell::Key& rhs ) inline bool operator< ( const GCell::Key& lhs, const GCell::Key& rhs )
{ {
@ -498,6 +518,20 @@ namespace Anabatic {
return lhs._gcell->getId() < rhs._gcell->getId(); return lhs._gcell->getId() < rhs._gcell->getId();
} }
inline bool GCell::Key::Compare::operator() ( const GCell::Key* lhs, const GCell::Key* rhs )
{
float difference = lhs->_density - rhs->_density;
if (difference != 0.0) return (difference > 0.0);
return lhs->_gcell->getId() < rhs->_gcell->getId();
}
// -------------------------------------------------------------------
// Class : "GCellKeyQueue".
typedef std::priority_queue< GCell::Key*, std::vector<GCell::Key*>, GCell::Key::Compare > GCellKeyQueue;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Class : "GCellDensitySet". // Class : "GCellDensitySet".
@ -542,5 +576,3 @@ namespace Anabatic {
INSPECTOR_P_SUPPORT(Anabatic::GCell); INSPECTOR_P_SUPPORT(Anabatic::GCell);
#endif // ANABATIC_GCELL_H