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:
parent
78b7e683e5
commit
85d7714910
|
@ -306,6 +306,7 @@ namespace Anabatic {
|
|||
, _fragmentations(new float [_depth])
|
||||
, _globalsCount (new float [_depth])
|
||||
, _key (this,1)
|
||||
, _lastClonedKey (NULL)
|
||||
{
|
||||
if (not _matrixHSide) {
|
||||
_matrixVSide = Session::getSliceHeight();
|
||||
|
|
|
@ -336,6 +336,51 @@ namespace Anabatic {
|
|||
cmess1 << " o Desaturate layer "
|
||||
<< 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() );
|
||||
GCell::Set invalidateds;
|
||||
|
||||
|
@ -371,6 +416,7 @@ namespace Anabatic {
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -14,10 +14,9 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#ifndef ANABATIC_GCELL_H
|
||||
#define ANABATIC_GCELL_H
|
||||
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <functional>
|
||||
|
@ -115,13 +114,20 @@ namespace Anabatic {
|
|||
public:
|
||||
class Key {
|
||||
public:
|
||||
inline Key ( GCell*, size_t depth );
|
||||
inline Key ( const GCell*, size_t depth );
|
||||
inline ~Key ();
|
||||
inline float getDensity () const;
|
||||
inline GCell* getGCell () const;
|
||||
inline const GCell* getGCell () const;
|
||||
inline bool isActive () const;
|
||||
inline void update ( size_t depth );
|
||||
friend bool operator< ( const Key&, const Key& );
|
||||
public:
|
||||
class Compare {
|
||||
public:
|
||||
inline bool operator() ( const Key*, const Key* );
|
||||
};
|
||||
private:
|
||||
GCell* _gcell;
|
||||
const GCell* _gcell;
|
||||
float _density;
|
||||
};
|
||||
public:
|
||||
|
@ -242,6 +248,9 @@ namespace Anabatic {
|
|||
inline AutoSegments getStopSegments ( Flags direction );
|
||||
size_t getRoutingPads ( set<RoutingPad*>& );
|
||||
inline const Key& getKey () const;
|
||||
inline Key* cloneKey ( size_t depth ) const;
|
||||
inline Key* getLastClonedKey () const;
|
||||
inline void clearClonedKey () const;
|
||||
size_t checkDensity () const;
|
||||
bool checkEdgeSaturation ( size_t hreserved, size_t vreserved) const;
|
||||
void setType ( Flags );
|
||||
|
@ -330,6 +339,7 @@ namespace Anabatic {
|
|||
float* _fragmentations;
|
||||
float* _globalsCount;
|
||||
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 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::updateKey ( size_t depth ) { _key.update(depth); }
|
||||
inline const Flags& GCell::flags () const { return _flags; }
|
||||
|
@ -478,17 +491,24 @@ namespace Anabatic {
|
|||
return lhs.getId() < rhs.getId();
|
||||
}
|
||||
|
||||
|
||||
// GCell::CompareByKey Inline Functions.
|
||||
inline bool GCell::CompareByKey::operator() ( const GCell* lhs, const GCell* rhs )
|
||||
{ return lhs->getKey() < rhs->getKey(); }
|
||||
|
||||
|
||||
// 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 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 bool GCell::Key::isActive () const { return (this == _gcell->getLastClonedKey()); }
|
||||
|
||||
inline bool operator< ( const GCell::Key& lhs, const GCell::Key& rhs )
|
||||
{
|
||||
|
@ -498,6 +518,20 @@ namespace Anabatic {
|
|||
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".
|
||||
|
@ -542,5 +576,3 @@ namespace Anabatic {
|
|||
|
||||
|
||||
INSPECTOR_P_SUPPORT(Anabatic::GCell);
|
||||
|
||||
#endif // ANABATIC_GCELL_H
|
||||
|
|
Loading…
Reference in New Issue