-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
perf: don't use boost time in validation.cpp #5616
perf: don't use boost time in validation.cpp #5616
Conversation
src/validation.cpp
Outdated
@@ -944,7 +942,7 @@ bool MemPoolAccept::Finalize(ATMPArgs& args, Workspace& ws) | |||
|
|||
bool MemPoolAccept::AcceptSingleTransaction(const CTransactionRef& ptx, ATMPArgs& args) | |||
{ | |||
boost::posix_time::ptime start = boost::posix_time::microsec_clock::local_time(); | |||
auto start = GetTimeMicros(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
imo better to switch just to std::chrono::microseconds
rather than int64_t counter.
Helper GetTimeMicro
has been introduced back in 2014 year:
+int64_t GetTimeMicros()
+{
+ return (boost::posix_time::ptime(boost::posix_time::microsec_clock::universal_time()) -
+ boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_microseconds();
+}
But now wrapper over std::chrono is useful only for the old already written code; it has std::chrono inside since this commit a3bc3fd
int64_t GetTimeMicros()
{
- int64_t now = (boost::posix_time::microsec_clock::universal_time() -
- boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_microseconds();
+ int64_t now = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
assert(now > 0);
return now;
}
Let's use std::chrono directly instead wrappers.
Btw, conceptually ACK, bitcoin switched from posix time to std::chrono long time ago, for example this PR: https://github.com/bitcoin/bitcoin/pull/18234/files
auto start = GetTimeMicros(); | |
auto start = std::chrono::system_clock::now() |
(over a 13 minute segment of reindex) boost time took about 9+9+9 = 27%!! of total cycles!!! During the same time segment, GetTimeMicros() used roughly 0.2% of total cycles! (even though it's used a lot more) Over my entire roughly 40 minute profiling session, boost time appears to use about 6% of cycles; still too much, while GetTimeMicros used about 0.4% (now using std::chrono directly)
7a9235e
to
56c3e6d
Compare
Updated to std::chrono directly; should be (very marginally) faster also as we avoid an assert here now inside of GetTimeMicros() |
CI fails |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
several nits
src/validation.cpp
Outdated
@@ -1498,7 +1496,7 @@ void InitScriptExecutionCache() { | |||
*/ | |||
bool CheckInputScripts(const CTransaction& tx, TxValidationState &state, const CCoinsViewCache &inputs, unsigned int flags, bool cacheSigStore, bool cacheFullScriptStore, PrecomputedTransactionData& txdata, std::vector<CScriptCheck> *pvChecks) EXCLUSIVE_LOCKS_REQUIRED(cs_main) | |||
{ | |||
boost::posix_time::ptime start = boost::posix_time::microsec_clock::local_time(); | |||
auto start = std::chrono::system_clock::now(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: maybe const here (and similar places)?
auto start = std::chrono::system_clock::now(); | |
const auto start = std::chrono::system_clock::now(); |
src/validation.cpp
Outdated
statsClient.timing("CheckInputScripts_ms", diff.total_milliseconds(), 1.0f); | ||
auto finish = std::chrono::system_clock::now(); | ||
auto diff = finish - start; | ||
statsClient.timing("CheckInputScripts_ms", count_microseconds(diff), 1.0f); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: doesn't seems as finish
is used anywhere else
- auto finish = std::chrono::system_clock::now();
- auto diff = finish - start;
+ const auto diff = std::chrono::system_clock::now() - start;
statsClient.timing("CheckInputScripts_ms", count_microseconds(diff), 1.0f);
src/validation.cpp
Outdated
statsClient.timing("CheckInputScripts_ms", diff.total_milliseconds(), 1.0f); | ||
auto finish = std::chrono::system_clock::now(); | ||
auto diff = finish - start; | ||
statsClient.timing("CheckInputScripts_ms", count_microseconds(diff), 1.0f); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
statsClient.timing("CheckInputScripts_ms", count_microseconds(diff), 1.0f); | |
statsClient.timing("CheckInputScripts_µs", count_microseconds(diff), 1.0f); |
or
statsClient.timing("CheckInputScripts_ms", count_microseconds(diff), 1.0f); | |
statsClient.timing("CheckInputScripts_us", count_microseconds(diff), 1.0f); |
UPD: should be miliseconds
validation.cpp: In member function ‘bool CChainState::ActivateBestChain(BlockValidationState&, std::shared_ptr<const CBlock>)’:
validation.cpp:3203:67: error: could not convert ‘diff’ from ‘duration<[...],ratio<[...],1000000000>>’ to ‘duration<[...],ratio<[...],1000000>>’
3203 | statsClient.timing("ActivateBestChain_ms", count_microseconds(diff), 1.0f);
src/validation.cpp
Outdated
statsClient.timing("ActivateBestChain_ms", diff.total_milliseconds(), 1.0f); | ||
auto finish = std::chrono::system_clock::now(); | ||
auto diff = finish - start; | ||
statsClient.timing("ActivateBestChain_ms", count_microseconds(diff), 1.0f); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
statsClient.timing("ActivateBestChain_ms", count_microseconds(diff), 1.0f); | |
statsClient.timing("ActivateBestChain_us", count_microseconds(diff), 1.0f); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(CI)
src/validation.cpp
Outdated
statsClient.timing("AcceptToMemoryPool_ms", diff.total_milliseconds(), 1.0f); | ||
auto finish = std::chrono::system_clock::now(); | ||
auto diff = finish - start; | ||
statsClient.timing("AcceptToMemoryPool_us", count_microseconds(diff), 1.0f); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm... I think this is going to break stats on already running instances (if there any). Should keep string the same and use count_milliseconds
instead imo. (same for similar changes below)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I change it to count_milliseconds it doesn't compile; I'd probably need to duration_cast it to milliseconds or something like that. Do you think would be good?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could do it like 4b57881 maybe?
Class std::chrono::steady_clock represents a monotonic clock. The time points of this clock cannot decrease as physical time moves forward and the time between ticks of this clock is constant. This clock is not related to wall clock time (for example, it can be time since last reboot), and is most suitable for measuring intervals.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that seems pretty reasonable to me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
utACK
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
utACK
## Issue being fixed or feature implemented We went from milliseconds to microseconds for these silently in #5616 🙈 ## What was done? make it milliseconds again ## How Has This Been Tested? n/a ## Breaking Changes n/a ## Checklist: - [x] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have added or updated relevant unit/integration/functional/e2e tests - [ ] I have made corresponding changes to the documentation - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_
(over a 13 minute segment of reindex) boost time took about 9+9+9 = 27%!! of total cycles!!!
During the same time segment, GetTimeMicros() used roughly 0.2% of total cycles! (even though it's used a lot more)
Over my entire roughly 40 minute profiling session, boost time appears to use about 6% of cycles; still too much, while GetTimeMicros used about 0.4%
Checklist:
Go over all the following points, and put an
x
in all the boxes that apply.