From 2bf8b78fa590c675db39d0f63625e0b16ed97853 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Sat, 7 Sep 2019 12:37:05 -0700 Subject: [PATCH] thread speed --- dcalc/GraphDelayCalc1.cc | 42 +++++++++++++++++++++++++++------------- dcalc/GraphDelayCalc1.hh | 4 +++- sdc/Sdc.cc | 35 +++++++++++++++++---------------- sdc/Sdc.hh | 5 +++-- search/Bfs.cc | 4 +++- search/Sim.cc | 5 +---- search/VertexVisitor.hh | 5 +++-- 7 files changed, 60 insertions(+), 40 deletions(-) diff --git a/dcalc/GraphDelayCalc1.cc b/dcalc/GraphDelayCalc1.cc index 8c7c993a..3e606e63 100644 --- a/dcalc/GraphDelayCalc1.cc +++ b/dcalc/GraphDelayCalc1.cc @@ -359,6 +359,7 @@ class FindVertexDelays : public VertexVisitor virtual ~FindVertexDelays(); virtual void visit(Vertex *vertex); virtual VertexVisitor *copy(); + virtual void levelFinished(); protected: GraphDelayCalc1 *graph_delay_calc1_; @@ -396,6 +397,24 @@ FindVertexDelays::visit(Vertex *vertex) graph_delay_calc1_->findVertexDelay(vertex, arc_delay_calc_, true); } +void +FindVertexDelays::levelFinished() +{ + graph_delay_calc1_->mergeIdealClks(); +} + +void +GraphDelayCalc1::mergeIdealClks() +{ + for (auto vertex_clks : ideal_clks_map_next_) { + const Vertex *vertex = vertex_clks.first; + ClockSet *prev_clks = ideal_clks_map_.findKey(vertex); + delete prev_clks; + ideal_clks_map_[vertex] = vertex_clks.second; + } + ideal_clks_map_next_.clear(); +} + // The logical structure of incremental delay calculation closely // resembles the incremental search arrival time algorithm // (Search::findArrivals). @@ -417,16 +436,14 @@ GraphDelayCalc1::findDelays(Level level) if (incremental_) seedInvalidDelays(); + mergeIdealClks(); FindVertexDelays visitor(this, arc_delay_calc_, false); dcalc_count += iter_->visitParallel(level, &visitor); // Timing checks require slews at both ends of the arc, // so find their delays after all slews are known. - VertexSet::Iterator check_iter(invalid_checks_); - while (check_iter.hasNext()) { - Vertex *check_vertex = check_iter.next(); + for (Vertex *check_vertex : invalid_checks_) findCheckDelays(check_vertex, arc_delay_calc_); - } invalid_checks_.clear(); delays_exist_ = true; @@ -1628,6 +1645,7 @@ void GraphDelayCalc1::clearIdealClkMap() { ideal_clks_map_.deleteContentsClear(); + ideal_clks_map_next_.deleteContentsClear(); } bool @@ -1635,13 +1653,13 @@ GraphDelayCalc1::setIdealClks(const Vertex *vertex, ClockSet *clks) { bool changed = false; - UniqueLock lock(ideal_clks_map_lock_); ClockSet *clks1 = ideal_clks_map_.findKey(vertex); - if (ClockSet::equal(clks, clks1)) - delete clks; - else { - delete clks1; - ideal_clks_map_[vertex] = clks; + if (!ClockSet::equal(clks, clks1)) { + // Only lock for updates to vertex ideal clks. + // Finding ideal clks by level means only changes at the current + // delay calc level are changed. + UniqueLock lock(ideal_clks_map_next_lock_); + ideal_clks_map_next_[vertex] = clks; changed = true; } return changed; @@ -1650,9 +1668,7 @@ GraphDelayCalc1::setIdealClks(const Vertex *vertex, ClockSet * GraphDelayCalc1::idealClks(const Vertex *vertex) { - UniqueLock lock(ideal_clks_map_lock_); - ClockSet *clks = ideal_clks_map_.findKey(vertex); - return clks; + return ideal_clks_map_.findKey(vertex); } bool diff --git a/dcalc/GraphDelayCalc1.hh b/dcalc/GraphDelayCalc1.hh index 17b0f269..6a323bc8 100644 --- a/dcalc/GraphDelayCalc1.hh +++ b/dcalc/GraphDelayCalc1.hh @@ -213,6 +213,7 @@ protected: Parasitic *drvr_parasitic, const TransRiseFall *tr, const DcalcAnalysisPt *dcalc_ap) const; + void mergeIdealClks(); // Observer for edge delay changes. DelayCalcObserver *observer_; @@ -234,7 +235,8 @@ protected: // delays to be recomputed during incremental delay calculation. float incremental_delay_tolerance_; VertexIdealClksMap ideal_clks_map_; - std::mutex ideal_clks_map_lock_; + VertexIdealClksMap ideal_clks_map_next_; + std::mutex ideal_clks_map_next_lock_; friend class FindVertexDelays; friend class MultiDrvrNet; diff --git a/sdc/Sdc.cc b/sdc/Sdc.cc index 26d01aa0..434649e8 100644 --- a/sdc/Sdc.cc +++ b/sdc/Sdc.cc @@ -2502,13 +2502,17 @@ Sdc::cycleAccting(const ClockEdge *src, CycleAccting probe(src, tgt); CycleAccting *acct = cycle_acctings_.findKey(&probe); if (acct == nullptr) { - acct = new CycleAccting(src, tgt); - if (src == defaultArrivalClockEdge()) - acct->findDefaultArrivalSrcDelays(); - else - acct->findDelays(this); UniqueLock lock(cycle_acctings_lock_); - cycle_acctings_.insert(acct); + // Recheck with lock. + acct = cycle_acctings_.findKey(&probe); + if (acct == nullptr) { + acct = new CycleAccting(src, tgt); + if (src == defaultArrivalClockEdge()) + acct->findDefaultArrivalSrcDelays(); + else + acct->findDelays(this); + cycle_acctings_.insert(acct); + } } return acct; } @@ -2520,7 +2524,9 @@ Sdc::reportClkToClkMaxCycleWarnings() // duplicate warnings between different src/tgt clk edges. ClockPairSet clk_warnings; ClockPairSeq clk_warnings2; - for (auto acct : cycle_acctings_) { + CycleAcctingSet::Iterator acct_iter(cycle_acctings_); + while (acct_iter.hasNext()) { + CycleAccting *acct = acct_iter.next(); if (acct->maxCyclesExceeded()) { Clock *src = acct->src()->clock(); Clock *tgt = acct->target()->clock(); @@ -3301,22 +3307,17 @@ Sdc::setNetWireCap(Net *net, } if (net_wire_cap_map_ == nullptr) net_wire_cap_map_ = new NetWireCapMap[corners_->count()]; - bool make_drvr_entry = net_wire_cap_map_[corner->index()].hasKey(net); + bool make_drvr_entry = !net_wire_cap_map_[corner->index()].hasKey(net); MinMaxFloatValues &values = net_wire_cap_map_[corner->index()][net]; values.setValue(min_max, wire_cap); // Only need to do this when there is new net_wire_cap_map_ entry. if (make_drvr_entry) { - NetConnectedPinIterator *pin_iter = network_->connectedPinIterator(net); - while (pin_iter->hasNext()) { - Pin *pin = pin_iter->next(); - if (network_->isDriver(pin)) { - if (drvr_pin_wire_cap_map_ == nullptr) - drvr_pin_wire_cap_map_ = new PinWireCapMap[corners_->count()]; - drvr_pin_wire_cap_map_[corner->index()][pin] = &values; - } + for (Pin *pin : *network_->drivers(net)) { + if (drvr_pin_wire_cap_map_ == nullptr) + drvr_pin_wire_cap_map_ = new PinWireCapMap[corners_->count()]; + drvr_pin_wire_cap_map_[corner->index()][pin] = &values; } - delete pin_iter; } } diff --git a/sdc/Sdc.hh b/sdc/Sdc.hh index a6b27ae0..873b0df1 100644 --- a/sdc/Sdc.hh +++ b/sdc/Sdc.hh @@ -22,7 +22,7 @@ #include "StringUtil.hh" #include "StringSet.hh" #include "Map.hh" -#include "UnorderedSet.hh" +#include "HashSet.hh" #include "UnorderedMap.hh" #include "MinMax.hh" #include "RiseFallValues.hh" @@ -114,7 +114,8 @@ typedef Set InputDelaySet; typedef Map InputDelayRefPinMap; typedef Map InputDelayInternalPinMap; typedef Map OutputDelayMap; -typedef UnorderedSet CycleAcctingSet; +// Use HashSet so no read lock is required. +typedef HashSet CycleAcctingSet; typedef Set InstanceSet; typedef UnorderedMap PinExceptionsMap; typedef Map ClockExceptionsMap; diff --git a/search/Bfs.cc b/search/Bfs.cc index b717614c..0ffdb333 100644 --- a/search/Bfs.cc +++ b/search/Bfs.cc @@ -153,6 +153,7 @@ BfsIterator::visit(Level to_level, } } level_vertices.clear(); + visitor->levelFinished(); } } return visit_count; @@ -224,7 +225,7 @@ BfsIterator::visitParallel(Level to_level, for (int i = 0; i < thread_count_; i++) { ForEachArg arg(&iter, lock, - visitor->copy()); + visitor->copy()); // Missing check for null vertex. threads.push_back(std::thread(forEachBegin, arg)); @@ -235,6 +236,7 @@ BfsIterator::visitParallel(Level to_level, thread.join(); visit_count += iter.count(); + visitor->levelFinished(); level = first_level_; } else { diff --git a/search/Sim.cc b/search/Sim.cc index 9768a61c..624a3f44 100644 --- a/search/Sim.cc +++ b/search/Sim.cc @@ -1079,12 +1079,9 @@ Sim::annotateVertexEdges(const Instance *inst, InstancePinIterator *pin_iter = network_->pinIterator(inst); while (pin_iter->hasNext()) { Pin *pin = pin_iter->next(); - Vertex *vertex, *bidirect_drvr_vertex; - graph_->pinVertices(pin, vertex, bidirect_drvr_vertex); + Vertex *vertex = graph_->pinDrvrVertex(pin); if (vertex) annotateVertexEdges(inst, pin, vertex, annotate); - if (bidirect_drvr_vertex) - annotateVertexEdges(inst, pin, bidirect_drvr_vertex, annotate); } delete pin_iter; } diff --git a/search/VertexVisitor.hh b/search/VertexVisitor.hh index 87a9d713..267e33a9 100644 --- a/search/VertexVisitor.hh +++ b/search/VertexVisitor.hh @@ -32,19 +32,20 @@ public: virtual VertexVisitor *copy() = 0; virtual void visit(Vertex *vertex) = 0; void operator()(Vertex *vertex) { visit(vertex); } + virtual void levelFinished() {} private: DISALLOW_COPY_AND_ASSIGN(VertexVisitor); }; -// Collector visited pins into a PinSet. +// Collect visited pins into a PinSet. class VertexPinCollector : public VertexVisitor { public: VertexPinCollector(PinSet *pins); PinSet *pins() const { return pins_; } void visit(Vertex *vertex); - VertexVisitor *copy(); + virtual VertexVisitor *copy(); protected: PinSet *pins_;