mirror of https://github.com/KLayout/klayout.git
Refining shape iterator optimization, so it checks instances for overlap with shapes rather the other way round. This suits better to real test cases.
This commit is contained in:
parent
5699c91d3f
commit
cb5a1f7d3e
|
|
@ -680,13 +680,17 @@ bool run_tiled_xor (const XORData &xor_data)
|
|||
if (ll->second.first < 0) {
|
||||
proc.input (in_a, db::RecursiveShapeIterator ());
|
||||
} else {
|
||||
proc.input (in_a, db::RecursiveShapeIterator (*xor_data.layout_a, xor_data.layout_a->cell (xor_data.cell_a), ll->second.first));
|
||||
db::RecursiveShapeIterator si (*xor_data.layout_a, xor_data.layout_a->cell (xor_data.cell_a), ll->second.first);
|
||||
si.set_for_merged_input (true);
|
||||
proc.input (in_a, si);
|
||||
}
|
||||
|
||||
if (ll->second.second < 0) {
|
||||
proc.input (in_b, db::RecursiveShapeIterator ());
|
||||
} else {
|
||||
proc.input (in_b, db::RecursiveShapeIterator (*xor_data.layout_b, xor_data.layout_b->cell (xor_data.cell_b), ll->second.second));
|
||||
db::RecursiveShapeIterator si (*xor_data.layout_b, xor_data.layout_b->cell (xor_data.cell_b), ll->second.second);
|
||||
si.set_for_merged_input (true);
|
||||
proc.input (in_b, si);
|
||||
}
|
||||
|
||||
std::string expr = "var x=" + in_a + "^" + in_b + "; ";
|
||||
|
|
@ -805,10 +809,12 @@ bool run_deep_xor (const XORData &xor_data)
|
|||
|
||||
if (ll->second.first >= 0) {
|
||||
ri_a = db::RecursiveShapeIterator (*xor_data.layout_a, xor_data.layout_a->cell (xor_data.cell_a), ll->second.first);
|
||||
ri_a.set_for_merged_input (true);
|
||||
}
|
||||
|
||||
if (ll->second.second >= 0) {
|
||||
ri_b = db::RecursiveShapeIterator (*xor_data.layout_b, xor_data.layout_b->cell (xor_data.cell_b), ll->second.second);
|
||||
ri_b.set_for_merged_input (true);
|
||||
}
|
||||
|
||||
db::Region in_a (ri_a, dss, db::ICplxTrans (xor_data.layout_a->dbu () / dbu));
|
||||
|
|
|
|||
|
|
@ -933,35 +933,6 @@ RecursiveShapeIterator::new_cell (RecursiveShapeReceiver *receiver) const
|
|||
|
||||
new_layer ();
|
||||
|
||||
// try some optimization - only consider optimizing by dropping the shape-covered area under certain circumstances:
|
||||
// - single layer
|
||||
// - at least one shape to consider and it is a box
|
||||
// - that box clips the region entirely on one side
|
||||
//
|
||||
// NOTE that this implementation can modify the search box on the box stack
|
||||
// because we did "new_layer()" already and this function is not going to
|
||||
// be called, because we do so only for single layers.
|
||||
|
||||
if (m_for_merged_input && (! m_has_layers || m_layers.size () == 1) && ! m_shape.at_end ()) {
|
||||
|
||||
box_type box = m_shape->rectangle ();
|
||||
if (! box.empty ()) {
|
||||
|
||||
// Need to enlarge the empty area somewhat so we really exclude instances
|
||||
// entirely enclosed by the shape - also the ones at the border.
|
||||
if (! m_overlapping) {
|
||||
box.enlarge (box_type::vector_type (1, 1));
|
||||
}
|
||||
|
||||
const box_type ®ion = m_local_region_stack.back ();
|
||||
unsigned int l = m_has_layers ? m_layers.front () : m_layer;
|
||||
box = (cell ()->bbox (l) & region) - box;
|
||||
m_local_region_stack.back () = box;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (m_overlapping) {
|
||||
m_inst = cell ()->begin_touching (m_local_region_stack.back ().enlarged (box_type::vector_type (-1, -1)));
|
||||
} else {
|
||||
|
|
@ -994,6 +965,33 @@ RecursiveShapeIterator::new_inst (RecursiveShapeReceiver *receiver) const
|
|||
}
|
||||
}
|
||||
|
||||
if (m_for_merged_input && (! m_has_layers || m_layers.size () == 1)) {
|
||||
|
||||
// Try some optimization: if the instance we're looking at is entirely covered
|
||||
// by a rectangle (other objects are too expensive to check), then wil skip it
|
||||
//
|
||||
// We check 10 shapes max.
|
||||
|
||||
unsigned int l = m_has_layers ? m_layers.front () : m_layer;
|
||||
box_type inst_bx = m_inst->bbox (m_box_convert);
|
||||
auto si = cell ()->shapes (l).begin_overlapping (inst_bx, m_shape_flags, mp_shape_prop_sel, m_shape_inv_prop_sel);
|
||||
bool skip = false;
|
||||
size_t nmax = 10;
|
||||
while (! skip && ! si.at_end () && nmax-- > 0) {
|
||||
if (inst_bx.inside (si->rectangle ())) {
|
||||
skip = true;
|
||||
break;
|
||||
}
|
||||
++si;
|
||||
}
|
||||
|
||||
if (skip) {
|
||||
++m_inst;
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool all_of_instance = false;
|
||||
bool with_region = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -1683,7 +1683,7 @@ TEST(13_ForMergedPerformance)
|
|||
++n;
|
||||
}
|
||||
tl::info << "Counted " << n << " shapes on 66/20";
|
||||
EXPECT_EQ (n, size_t (1217072));
|
||||
EXPECT_EQ (n, size_t (1212844));
|
||||
}
|
||||
|
||||
{
|
||||
|
|
@ -1694,7 +1694,7 @@ TEST(13_ForMergedPerformance)
|
|||
++n;
|
||||
}
|
||||
tl::info << "Counted " << n << " shapes on 235/4";
|
||||
EXPECT_EQ (n, size_t (919));
|
||||
EXPECT_EQ (n, size_t (10));
|
||||
}
|
||||
|
||||
si1.set_for_merged_input (false);
|
||||
|
|
@ -1735,7 +1735,7 @@ TEST(13_ForMergedPerformance)
|
|||
++n;
|
||||
}
|
||||
tl::info << "Counted " << n << " shapes on 66/20";
|
||||
EXPECT_EQ (n, size_t (218736));
|
||||
EXPECT_EQ (n, size_t (218552));
|
||||
}
|
||||
|
||||
{
|
||||
|
|
@ -1746,7 +1746,7 @@ TEST(13_ForMergedPerformance)
|
|||
++n;
|
||||
}
|
||||
tl::info << "Counted " << n << " shapes on 235/4";
|
||||
EXPECT_EQ (n, size_t (1));
|
||||
EXPECT_EQ (n, size_t (2));
|
||||
}
|
||||
|
||||
{
|
||||
|
|
@ -1757,7 +1757,7 @@ TEST(13_ForMergedPerformance)
|
|||
db::Region r2 (si1);
|
||||
|
||||
EXPECT_EQ (r1.count (), size_t (218823));
|
||||
EXPECT_EQ (r2.count (), size_t (218736));
|
||||
EXPECT_EQ (r2.count (), size_t (218552));
|
||||
EXPECT_EQ ((r1 ^ r2).count (), size_t (0));
|
||||
}
|
||||
|
||||
|
|
@ -1769,7 +1769,7 @@ TEST(13_ForMergedPerformance)
|
|||
db::Region r2 (si2);
|
||||
|
||||
EXPECT_EQ (r1.count (), size_t (2578));
|
||||
EXPECT_EQ (r2.count (), size_t (1));
|
||||
EXPECT_EQ (r2.count (), size_t (2));
|
||||
EXPECT_EQ ((r1 ^ r2).count (), size_t (0));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue