diff --git a/src/db/db/dbHierNetworkProcessor.cc b/src/db/db/dbHierNetworkProcessor.cc index f187468fd..9ff05a5ff 100644 --- a/src/db/db/dbHierNetworkProcessor.cc +++ b/src/db/db/dbHierNetworkProcessor.cc @@ -20,7 +20,6 @@ */ - #include "dbHierNetworkProcessor.h" #include "dbShape.h" #include "dbShapes.h" @@ -1794,7 +1793,7 @@ public: cell_clusters_box_converter (const db::Layout &layout, const hier_clusters &tree) : mp_layout (&layout), mp_tree (&tree) { - // .. nothing yet .. + m_cache.resize (layout.cells (), 0); } const box_type &operator() (const db::CellInst &cell_inst) const @@ -1804,10 +1803,10 @@ public: const box_type &operator() (db::cell_index_type cell_index) const { - typename std::map::const_iterator b = m_cache.find (cell_index); - if (b != m_cache.end ()) { + const box_type *b = m_cache [cell_index]; + if (b) { - return b->second; + return *b; } else { @@ -1820,13 +1819,17 @@ public: box += inst_array.bbox (*this); } - return m_cache.insert (std::make_pair (cell_index, box)).first->second; + m_cached_boxes.push_front (box); + b = m_cached_boxes.begin ().operator-> (); + m_cache [cell_index] = b; + return *b; } } private: - mutable std::map m_cache; + mutable std::vector m_cache; + mutable tl::slist m_cached_boxes; const db::Layout *mp_layout; const hier_clusters *mp_tree; }; @@ -1993,10 +1996,10 @@ public: } /** - * @brief Finally join the clusters in the join set + * @brief Finally generate cluster-to-instance interactions and join the clusters in the join set * * This step is postponed because doing this while the iteration happens would - * invalidate the box trees. + * invalidate the box trees and disturb the propagation mechanism. */ void finish_cluster_to_instance_interactions () { @@ -2081,7 +2084,7 @@ private: const db::Connectivity *mp_conn; const std::set *mp_breakout_cells; typedef std::list > join_set_list; - std::map m_cm2join_map; + std::unordered_map m_cm2join_map; join_set_list m_cm2join_sets; std::map, int> m_soft_connections; std::list m_ci_interactions; @@ -2551,8 +2554,8 @@ private: return; } - typename std::map::const_iterator x = m_cm2join_map.find (a); - typename std::map::const_iterator y = m_cm2join_map.find (b); + typename std::unordered_map::const_iterator x = m_cm2join_map.find (a); + typename std::unordered_map::const_iterator y = m_cm2join_map.find (b); if (x == m_cm2join_map.end ()) { @@ -2579,6 +2582,11 @@ private: } else if (x->second != y->second) { + // the y set should be the smaller one for better efficiency + if (x->second->size () < y->second->size ()) { + std::swap (x, y); + } + // join two superclusters typename join_set_list::iterator yset = y->second; x->second->insert (yset->begin (), yset->end ()); @@ -2591,12 +2599,12 @@ private: #if defined(DEBUG_HIER_NETWORK_PROCESSOR) // concistency check for debugging - for (typename std::map::const_iterator j = m_cm2join_map.begin (); j != m_cm2join_map.end (); ++j) { + for (auto j = m_cm2join_map.begin (); j != m_cm2join_map.end (); ++j) { tl_assert (j->second->find (j->first) != j->second->end ()); } - for (typename std::list >::const_iterator i = m_cm2join_sets.begin (); i != m_cm2join_sets.end (); ++i) { - for (typename std::set::const_iterator j = i->begin(); j != i->end(); ++j) { + for (auto i = m_cm2join_sets.begin (); i != m_cm2join_sets.end (); ++i) { + for (auto j = i->begin(); j != i->end(); ++j) { tl_assert(m_cm2join_map.find (*j) != m_cm2join_map.end ()); tl_assert(m_cm2join_map[*j] == i); } @@ -2604,8 +2612,8 @@ private: // the sets must be disjunct std::set all; - for (typename std::list >::const_iterator i = m_cm2join_sets.begin (); i != m_cm2join_sets.end (); ++i) { - for (typename std::set::const_iterator j = i->begin(); j != i->end(); ++j) { + for (auto i = m_cm2join_sets.begin (); i != m_cm2join_sets.end (); ++i) { + for (auto j = i->begin(); j != i->end(); ++j) { tl_assert(all.find (*j) == all.end()); all.insert(*j); } @@ -2700,23 +2708,13 @@ private: } else if (x1 != x2) { int soft = ic->soft; - - // for instance-to-instance interactions the number of connections is more important for the - // cost of the join operation: make the one with more connections the target - // TODO: this will be SLOW for STL's not providing a fast size() - if (mp_cell_clusters->connections_for_cluster (x1).size () < mp_cell_clusters->connections_for_cluster (x2).size ()) { - std::swap (x1, x2); - soft = -soft; - } - if (soft != 0) { register_soft_connection (x1, x2, soft); } else { - mp_cell_clusters->join_cluster_with (x1, x2); - mp_cell_clusters->remove_cluster (x2); + mark_to_join (x1, x2); }