From 7c5ae471aba71ec74d17980fba15fb9f8dd93df5 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Thu, 3 Oct 2019 22:53:38 +0200 Subject: [PATCH] WIP: performance improvement of hier local processor The solution is to take intruder instances from as far as possible in the hierarchy. This provides a performance improvement in some cases, specifically if this leads to compression of contexts. --- src/db/db/dbHierProcessor.cc | 66 +++++++++++++++++++++- src/db/db/dbHierProcessor.h | 1 + src/drc/drc/built-in-macros/_drc_engine.rb | 12 ++++ 3 files changed, 77 insertions(+), 2 deletions(-) diff --git a/src/db/db/dbHierProcessor.cc b/src/db/db/dbHierProcessor.cc index 8b9de21bf..63129fdb6 100644 --- a/src/db/db/dbHierProcessor.cc +++ b/src/db/db/dbHierProcessor.cc @@ -1235,7 +1235,7 @@ void local_processor::compute_contexts (local_processor_contextsbegin (); !i.at_end (); ++i) { unsigned int iid = ++id; @@ -1327,7 +1327,11 @@ void local_processor::compute_contexts (local_processor_contextscomplex_trans (*k); // NOTE: no self-interactions if (i->first != *j || tn != tk) { - intruders_below.first.insert (db::CellInstArray (db::CellInst ((*j)->object ().cell_index ()), tni * tk)); + // optimize the intruder instance so it will be as low as possible + std::pair ei = effective_instance (contexts, i->first->object ().cell_index (), (*j)->object ().cell_index (), tni * tk, dist); + if (ei.first) { + intruders_below.first.insert (ei.second); + } } } } @@ -1342,6 +1346,64 @@ void local_processor::compute_contexts (local_processor_contexts +std::pair +local_processor::effective_instance (local_processor_contexts &contexts, db::cell_index_type subject_cell_index, db::cell_index_type intruder_cell_index, const db::ICplxTrans &ti2s, db::Coord dist) const +{ + db::Box bbox = safe_box_enlarged (mp_subject_layout->cell (subject_cell_index).bbox (contexts.subject_layer ()), dist - 1, dist - 1); + if (bbox.empty ()) { + // should not happen, but skip if it does + return std::make_pair (false, db::CellInstArray ()); + } + + db::Box ibbox = bbox.transformed (ti2s.inverted ()); + + const db::Cell &intruder_cell = mp_intruder_layout->cell (intruder_cell_index); + const db::Shapes &intruder_shapes = intruder_cell.shapes (contexts.intruder_layer ()); + if (! intruder_shapes.empty () && ! intruder_shapes.begin_touching (ibbox, db::ShapeIterator::All).at_end ()) { + return std::make_pair (true, db::CellInstArray (db::CellInst (intruder_cell_index), ti2s)); + } + + db::box_convert inst_bcii (*mp_intruder_layout, contexts.intruder_layer ()); + + size_t ni = 0; + db::cell_index_type eff_cell_index = 0; + db::ICplxTrans eff_trans; + + for (db::Cell::touching_iterator i = intruder_cell.begin_touching (ibbox); ! i.at_end() && ni < 2; ++i) { + const db::CellInstArray &ci = i->cell_inst (); + db::Box cbox = mp_intruder_layout->cell (ci.object ().cell_index ()).bbox (contexts.intruder_layer ()); + for (db::CellInstArray::iterator k = ci.begin_touching (ibbox, inst_bcii); ! k.at_end () && ni < 2; ++k) { + db::ICplxTrans tk = ci.complex_trans (*k); + if (ibbox.overlaps (cbox.transformed (tk))) { + eff_trans = tk; + eff_cell_index = ci.object ().cell_index (); + ++ni; + } + } + } + + if (ni == 0) { + // should not happen, but skip if it does + return std::make_pair (false, db::CellInstArray ()); + } else if (ni == 1) { + // one instance - dive down + return effective_instance (contexts, subject_cell_index, eff_cell_index, ti2s * eff_trans, dist); + } else { + return std::make_pair (true, db::CellInstArray (db::CellInst (intruder_cell_index), ti2s)); + } } template diff --git a/src/db/db/dbHierProcessor.h b/src/db/db/dbHierProcessor.h index 1326cffa9..72b95cc1a 100644 --- a/src/db/db/dbHierProcessor.h +++ b/src/db/db/dbHierProcessor.h @@ -434,6 +434,7 @@ private: void issue_compute_contexts (db::local_processor_contexts &contexts, db::local_processor_cell_context *parent_context, db::Cell *subject_parent, db::Cell *subject_cell, const db::ICplxTrans &subject_cell_inst, const db::Cell *intruder_cell, typename local_processor_cell_contexts::context_key_type &intruders, db::Coord dist) const; void push_results (db::Cell *cell, unsigned int output_layer, const std::unordered_set &result) const; void compute_local_cell (const db::local_processor_contexts &contexts, db::Cell *subject_cell, const db::Cell *intruder_cell, const local_operation *op, const typename local_processor_cell_contexts::context_key_type &intruders, std::unordered_set &result) const; + std::pair effective_instance (local_processor_contexts &contexts, db::cell_index_type subject_cell_index, db::cell_index_type intruder_cell_index, const db::ICplxTrans &ti2s, db::Coord dist) const; }; } diff --git a/src/drc/drc/built-in-macros/_drc_engine.rb b/src/drc/drc/built-in-macros/_drc_engine.rb index f513aef6d..997255a24 100644 --- a/src/drc/drc/built-in-macros/_drc_engine.rb +++ b/src/drc/drc/built-in-macros/_drc_engine.rb @@ -1296,10 +1296,16 @@ CODE end else + + if @dss + @dss.threads = (@tt || 1) + end + res = nil run_timed("\"#{method}\" in: #{src_line}", obj) do res = obj.send(method, *args) end + end # enable progress @@ -1333,10 +1339,16 @@ CODE res = res.value else + + if @dss + @dss.threads = (@tt || 1) + end + res = nil run_timed("\"#{method}\" in: #{src_line}", obj) do res = obj.send(method) end + end # enable progress