thread speed
This commit is contained in:
parent
f9bc74e962
commit
2bf8b78fa5
|
|
@ -359,6 +359,7 @@ public:
|
|||
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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
35
sdc/Sdc.cc
35
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<InputDelay*> InputDelaySet;
|
|||
typedef Map<const Pin*,InputDelaySet*> InputDelayRefPinMap;
|
||||
typedef Map<const Pin*,InputDelaySet*> InputDelayInternalPinMap;
|
||||
typedef Map<const Pin*,OutputDelay*> OutputDelayMap;
|
||||
typedef UnorderedSet<CycleAccting*, CycleAcctingHash, CycleAcctingEqual> CycleAcctingSet;
|
||||
// Use HashSet so no read lock is required.
|
||||
typedef HashSet<CycleAccting*, CycleAcctingHash, CycleAcctingEqual> CycleAcctingSet;
|
||||
typedef Set<Instance*> InstanceSet;
|
||||
typedef UnorderedMap<const Pin*,ExceptionPathSet*> PinExceptionsMap;
|
||||
typedef Map<const Clock*,ExceptionPathSet*> ClockExceptionsMap;
|
||||
|
|
|
|||
|
|
@ -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<QueueIterator, VertexVisitor> arg(&iter, lock,
|
||||
visitor->copy());
|
||||
visitor->copy());
|
||||
// Missing check for null vertex.
|
||||
threads.push_back(std::thread(forEachBegin<QueueIterator,
|
||||
VertexVisitor, Vertex*>, arg));
|
||||
|
|
@ -235,6 +236,7 @@ BfsIterator::visitParallel(Level to_level,
|
|||
thread.join();
|
||||
|
||||
visit_count += iter.count();
|
||||
visitor->levelFinished();
|
||||
level = first_level_;
|
||||
}
|
||||
else {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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_;
|
||||
|
|
|
|||
Loading…
Reference in New Issue