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])
|
, _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();
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
Loading…
Reference in New Issue