From 61a607c68b3aa03770a3cb71f9d3b19fd0736ab5 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Fri, 16 Aug 2024 16:50:57 -0700 Subject: [PATCH 1/4] Network::findInstPinsHierMatching speedup Signed-off-by: James Cherry --- network/Network.cc | 3 +-- search/Search.i | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/network/Network.cc b/network/Network.cc index eac5151f..6c8d8f90 100644 --- a/network/Network.cc +++ b/network/Network.cc @@ -1047,8 +1047,7 @@ Network::findInstPinsHierMatching(const Instance *instance, while (pin_iter->hasNext()) { const Pin *pin = pin_iter->next(); const char *port_name = name(port(pin)); - string pin_name; - stringPrint(pin_name, "%s%c%s", inst_name.c_str(), divider_, port_name); + string pin_name = inst_name + divider_ + port_name; if (pattern->match(pin_name.c_str())) matches.push_back(pin); } diff --git a/search/Search.i b/search/Search.i index a5c83a20..da07b521 100644 --- a/search/Search.i +++ b/search/Search.i @@ -1236,7 +1236,7 @@ use_default_arrival_clock() void set_use_default_arrival_clock(bool enable) { - return Sta::sta()->setUseDefaultArrivalClock(enable); + Sta::sta()->setUseDefaultArrivalClock(enable); } //////////////////////////////////////////////////////////////// From cb6922d743aa10a0e15c95d0ed0baccd40a94ce2 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Fri, 16 Aug 2024 17:09:58 -0700 Subject: [PATCH 2/4] use std::string instead of stringPrint Signed-off-by: James Cherry --- sdf/SdfReader.cc | 16 +++++++++++----- search/Property.cc | 22 +++++++--------------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/sdf/SdfReader.cc b/sdf/SdfReader.cc index 05515d27..9e470d91 100644 --- a/sdf/SdfReader.cc +++ b/sdf/SdfReader.cc @@ -1034,8 +1034,9 @@ Pin * SdfReader::findPin(const char *name) { if (path_) { - string path_name; - stringPrint(path_name, "%s%c%s", path_, divider_, name); + string path_name = path_; + path_name += divider_; + path_name += name; Pin *pin = network_->findPin(path_name.c_str()); return pin; } @@ -1046,9 +1047,14 @@ SdfReader::findPin(const char *name) Instance * SdfReader::findInstance(const char *name) { - string inst_name = name; - if (path_) - stringPrint(inst_name, "%s%c%s", path_, divider_, name); + string inst_name; + if (path_) { + inst_name = path_; + inst_name += divider_; + inst_name += name; + } + else + inst_name = name; Instance *inst = network_->findInstance(inst_name.c_str()); if (inst == nullptr) sdfWarn(195, "instance %s not found.", inst_name.c_str()); diff --git a/search/Property.cc b/search/Property.cc index 1477856f..01491905 100644 --- a/search/Property.cc +++ b/search/Property.cc @@ -713,13 +713,9 @@ getProperty(const LibertyCell *cell, else if (stringEqual(property, "full_name")) { auto network = sta->cmdNetwork(); auto lib = cell->libertyLibrary(); - const char *lib_name = lib->name(); - const char *cell_name = cell->name(); - string full_name; - stringPrint(full_name, "%s%c%s", - lib_name, - network->pathDivider(), - cell_name); + string lib_name = lib->name(); + string cell_name = cell->name(); + string full_name = lib_name + network->pathDivider() + cell_name; return PropertyValue(full_name); } else if (stringEqual(property, "filename")) @@ -748,14 +744,10 @@ getProperty(const Cell *cell, || stringEqual(property, "base_name")) return PropertyValue(network->name(cell)); else if (stringEqual(property, "full_name")) { - auto lib = network->library(cell); - const char *lib_name = network->name(lib); - const char *cell_name = network->name(cell); - string full_name; - stringPrint(full_name, "%s%c%s", - lib_name, - network->pathDivider(), - cell_name); + Library *lib = network->library(cell); + string lib_name = network->name(lib); + string cell_name = network->name(cell); + string full_name = lib_name + network->pathDivider() + cell_name; return PropertyValue(full_name); } else if (stringEqual(property, "library")) From b51885aa37a14aa557b15b7680400d95744d5699 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Sat, 17 Aug 2024 11:11:53 -0700 Subject: [PATCH 3/4] TmpString use thread_local instead of lock Signed-off-by: James Cherry --- include/sta/StringUtil.hh | 4 --- network/Network.cc | 2 +- search/Sta.cc | 2 -- util/StringUtil.cc | 75 +++++++++++++-------------------------- 4 files changed, 26 insertions(+), 57 deletions(-) diff --git a/include/sta/StringUtil.hh b/include/sta/StringUtil.hh index 9f87180f..c2a117a5 100644 --- a/include/sta/StringUtil.hh +++ b/include/sta/StringUtil.hh @@ -177,10 +177,6 @@ stringPrintTmp(const char *fmt, char * makeTmpString(size_t length); -void -initTmpStrings(); -void -deleteTmpStrings(); bool isTmpString(const char *str); diff --git a/network/Network.cc b/network/Network.cc index 6c8d8f90..da2f3af1 100644 --- a/network/Network.cc +++ b/network/Network.cc @@ -258,7 +258,7 @@ Network::pathName(const Instance *instance) const const Instance *inst = path_iter1.next(); name_length += strlen(name(inst)) + 1; } - char *path_name = makeTmpString(name_length); + char *path_name = makeTmpString(name_length + 1); char *path_ptr = path_name; // Top instance has null string name, so terminate the string here. *path_name = '\0'; diff --git a/search/Sta.cc b/search/Sta.cc index 06a7429f..1416edd6 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -225,7 +225,6 @@ initSta() initElapsedTime(); TimingRole::init(); PortDirection::init(); - initTmpStrings(); initLiberty(); initDelayConstants(); registerDelayCalcs(); @@ -244,7 +243,6 @@ deleteAllMemory() Sta::setSta(nullptr); } deleteDelayCalcs(); - deleteTmpStrings(); TimingRole::destroy(); PortDirection::destroy(); deleteLiberty(); diff --git a/util/StringUtil.cc b/util/StringUtil.cc index 7d67911a..659c06a4 100644 --- a/util/StringUtil.cc +++ b/util/StringUtil.cc @@ -19,6 +19,7 @@ #include #include #include +#include #include "Machine.hh" #include "Mutex.hh" @@ -152,69 +153,43 @@ stringPrintTmp(const char *fmt, //////////////////////////////////////////////////////////////// -static int tmp_string_count_ = 100; -static char **tmp_strings_ = nullptr; -static size_t *tmp_string_lengths_ = nullptr; -static int tmp_string_next_; -static std::mutex string_lock_; - -void -initTmpStrings() -{ - size_t initial_length = 100; - - tmp_strings_ = new char*[tmp_string_count_]; - tmp_string_lengths_ = new size_t[tmp_string_count_]; - for (int i = 0; i < tmp_string_count_; i++) { - tmp_strings_[i] = new char[initial_length]; - tmp_string_lengths_[i] = initial_length; - } - tmp_string_next_ = 0; -} - -void -deleteTmpStrings() -{ - if (tmp_strings_) { - for (int i = 0; i < tmp_string_count_; i++) - delete [] tmp_strings_[i]; - delete [] tmp_strings_; - tmp_strings_ = nullptr; - - delete [] tmp_string_lengths_; - tmp_string_lengths_ = nullptr; - } -} +static constexpr size_t tmp_string_count = 256; +static constexpr size_t tmp_string_initial_length = 256; +thread_local static std::array tmp_strings; +thread_local static std::array tmp_string_lengths; +thread_local static int tmp_string_next = 0; static void getTmpString(// Return values. char *&str, size_t &length) { - LockGuard lock(string_lock_); - if (tmp_string_next_ == tmp_string_count_) - tmp_string_next_ = 0; - str = tmp_strings_[tmp_string_next_]; - length = tmp_string_lengths_[tmp_string_next_]; - tmp_string_next_++; + if (tmp_string_next == tmp_string_count) + tmp_string_next = 0; + str = tmp_strings[tmp_string_next]; + length = tmp_string_lengths[tmp_string_next]; + if (str == nullptr) { + str = tmp_strings[tmp_string_next] = new char[tmp_string_initial_length]; + length = tmp_string_lengths[tmp_string_next] = tmp_string_initial_length; + } + tmp_string_next++; } char * makeTmpString(size_t length) { - LockGuard lock(string_lock_); - if (tmp_string_next_ == tmp_string_count_) - tmp_string_next_ = 0; - char *tmp_str = tmp_strings_[tmp_string_next_]; - size_t tmp_length = tmp_string_lengths_[tmp_string_next_]; + if (tmp_string_next == tmp_string_count) + tmp_string_next = 0; + char *tmp_str = tmp_strings[tmp_string_next]; + size_t tmp_length = tmp_string_lengths[tmp_string_next]; if (tmp_length < length) { // String isn't long enough. Make a new one. delete [] tmp_str; tmp_str = new char[length]; - tmp_strings_[tmp_string_next_] = tmp_str; - tmp_string_lengths_[tmp_string_next_] = length; + tmp_strings[tmp_string_next] = tmp_str; + tmp_string_lengths[tmp_string_next] = length; } - tmp_string_next_++; + tmp_string_next++; return tmp_str; } @@ -230,9 +205,9 @@ stringDeleteCheck(const char *str) bool isTmpString(const char *str) { - if (tmp_strings_) { - for (int i = 0; i < tmp_string_count_; i++) { - if (str == tmp_strings_[i]) + if (!tmp_strings.empty()) { + for (size_t i = 0; i < tmp_string_count; i++) { + if (str == tmp_strings[i]) return true; } } From f54ab5b17003b5fe721c88d443156bb209718ac7 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Sat, 17 Aug 2024 11:39:47 -0700 Subject: [PATCH 4/4] prima thread safety Signed-off-by: James Cherry --- include/sta/Liberty.hh | 3 +++ liberty/Liberty.cc | 33 +++++++++++++++++++-------------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/include/sta/Liberty.hh b/include/sta/Liberty.hh index a18cceec..4763a8d0 100644 --- a/include/sta/Liberty.hh +++ b/include/sta/Liberty.hh @@ -16,6 +16,8 @@ #pragma once +#include + #include "MinMax.hh" #include "RiseFallMinMax.hh" #include "ConcreteLibrary.hh" @@ -628,6 +630,7 @@ protected: LibertyPgPortMap pg_port_map_; bool has_internal_ports_; bool have_voltage_waveforms_; + std::mutex waveform_lock_; private: friend class LibertyLibrary; diff --git a/liberty/Liberty.cc b/liberty/Liberty.cc index 95a9cb48..ac15e702 100644 --- a/liberty/Liberty.cc +++ b/liberty/Liberty.cc @@ -16,6 +16,7 @@ #include "Liberty.hh" +#include "Mutex.hh" #include "EnumNameMap.hh" #include "Report.hh" #include "Debug.hh" @@ -1963,24 +1964,28 @@ void LibertyCell::ensureVoltageWaveforms(const DcalcAnalysisPtSeq &dcalc_aps) { if (!have_voltage_waveforms_) { - float vdd = 0.0; // shutup gcc - bool vdd_exists; - liberty_library_->supplyVoltage("VDD", vdd, vdd_exists); - if (!vdd_exists || vdd == 0.0) - criticalError(1120, "library missing vdd"); - for (TimingArcSet *arc_set : timingArcSets()) { - for (TimingArc *arc : arc_set->arcs()) { - for (const DcalcAnalysisPt *dcalc_ap : dcalc_aps) { - GateTableModel *model = arc->gateTableModel(dcalc_ap); - if (model) { - OutputWaveforms *output_waveforms = model->outputWaveforms(); - if (output_waveforms) - output_waveforms->ensureVoltageWaveforms(vdd); + LockGuard lock(waveform_lock_); + // Recheck with lock. + if (!have_voltage_waveforms_) { + float vdd = 0.0; // shutup gcc + bool vdd_exists; + liberty_library_->supplyVoltage("VDD", vdd, vdd_exists); + if (!vdd_exists || vdd == 0.0) + criticalError(1120, "library missing vdd"); + for (TimingArcSet *arc_set : timingArcSets()) { + for (TimingArc *arc : arc_set->arcs()) { + for (const DcalcAnalysisPt *dcalc_ap : dcalc_aps) { + GateTableModel *model = arc->gateTableModel(dcalc_ap); + if (model) { + OutputWaveforms *output_waveforms = model->outputWaveforms(); + if (output_waveforms) + output_waveforms->ensureVoltageWaveforms(vdd); + } } } } + have_voltage_waveforms_ = true; } - have_voltage_waveforms_ = true; } }