Join GitHub today
GitHub is home to over 20 million developers working together to host and review code, manage projects, and build software together.
Structure Packing Optimizations in CTransaction and CTxMemPoolEntry #8330
Conversation
jonasschnelli
commented on an outdated diff
Jul 12, 2016
jonasschnelli
and 2 others
commented on an outdated diff
Jul 12, 2016
| + // Space that is typically used as padding. Commented out so that it doesn't cause extra memory use on different architectures. | ||
| + // char PADDING_FREE_SPACE[2]; | ||
| + | ||
| + // Bool flags | ||
| + struct CTxMemPoolEntryFlags { | ||
| + int UNUSED_BITS : 6; |
jonasschnelli
Member
|
jonasschnelli
added the
Refactoring
label
Jul 12, 2016
|
Concept ACK |
|
No, I'm not. I haven't actually tried. But I assume the int before the bitfield is 4-aligned, which would make the end of the bitfield byte be at a multiple of 4 plus 1? |
|
Needs rebase. Concept ACK, on the placeholder bitfield, perhaps better to make that a comment? |
|
rebased and addressed feedback |
JeremyRubin
changed the title from
WIP: Structure Packing Optimizations in CTransaction and CTxMemPoolEntry to Structure Packing Optimizations in CTransaction and CTxMemPoolEntry
Mar 27, 2017
|
Rebased! (removing priority conflicted with this) |
| - bool spendsCoinbase; //!< keep track of transactions that spend a coinbase | ||
| + struct CTxMemPoolEntryFlags { | ||
| + //int UNUSED_BITS : 7; | ||
| + bool spendsCoinbase : 1; //!< keep track of transactions that spend a coinbase |
ryanofsky
Mar 27, 2017
Contributor
Kind of a lonely bitfield now with just one bool. But maybe it will have some more flags later.
| @@ -94,7 +89,17 @@ class CTxMemPoolEntry | ||
| uint64_t nSizeWithAncestors; | ||
| CAmount nModFeesWithAncestors; | ||
| int64_t nSigOpCostWithAncestors; | ||
| + size_t nTxWeight; //!< ... and avoid recomputing tx weight (also used for GetTxSize()) | ||
| + size_t nModSize; //!< ... and modified size for priority |
ryanofsky
Mar 27, 2017
Contributor
In commit "Re-pack the CTxMempoolEntry to be closer to optimally packed":
This isn't used, guessing bad rebase.
| + // Bool flags | ||
| + bool hadNoDependencies; //!< Not dependent on any other txs when it entered the mempool |
ryanofsky
Mar 27, 2017
Contributor
In commit "Re-pack the CTxMempoolEntry to be closer to optimally packed":
Also unused.
| @@ -76,9 +76,12 @@ uint256 CTransaction::GetWitnessHash() const | ||
| } | ||
| /* For backward compatibility, the hash is initialized to 0. TODO: remove the need for this default constructor entirely. */ | ||
| -CTransaction::CTransaction() : nVersion(CTransaction::CURRENT_VERSION), vin(), vout(), nLockTime(0), hash() {} | ||
| -CTransaction::CTransaction(const CMutableTransaction &tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime), hash(ComputeHash()) {} |
ryanofsky
Mar 27, 2017
Contributor
In commit "Reorder C{,Mutable}Transaction for better packing":
Seems like you could remove ComputeHash now, it doesn't appear to be called anywhere else.
| - tx(_tx), nFee(_nFee), nTime(_nTime), entryHeight(_entryHeight), | ||
| - spendsCoinbase(_spendsCoinbase), sigOpCost(_sigOpsCost), lockPoints(lp) | ||
| + bool _spendsCoinbase, int64_t _sigOpsCost, LockPoints lp): | ||
| +lockPoints(lp), tx(_tx), nFee(_nFee) |
ryanofsky
Mar 28, 2017
Contributor
In commit "Re-pack the CTxMempoolEntry to be closer to optimally packed"
Unusual indentation here, maybe reformat.
| + //int UNUSED_BITS : 7; | ||
| + bool spendsCoinbase : 1; //!< keep track of transactions that spend a coinbase | ||
| + }; | ||
| + CTxMemPoolEntryFlags flags; |
TheBlueMatt
Jul 11, 2017
Contributor
Ehh, why not just have the single bool spendsCoinbase : 1 here instead of making a struct for it?
JeremyRubin
Jul 12, 2017
Contributor
It's somewhat vestigial; iirc when I originally wrote this patch last year there was another bool that got removed in a later PR.
The only real remaining reason is to make the code "self documenting" so that when/if someone later adds another flag to mempool (or even adds the flag back), they are encouraged to dtrt rather than adding more memory bloat.
TheBlueMatt
Jul 12, 2017
Contributor
Is there harm in having
bool spendsCoinbase : 1;
bool newFlags : 1;
instead of encapsulating the booleans in a flags struct?
|
This reduces CTransaction from 96 bytes to 88 bytes for me (great), but increases CTxMemPoolEntry from 160 bytes to 168 bytes (not so great). NACK as long as that is the case. |
|
@sipa I rewrote this PR to repack the CTransaction versions via a minimal patch. I'm not sure what was going on with the CTxMemPoolEntry version, I just think it became stale. At the time I wrote the patch initially they were 192 bytes, so 160 bytes/entry is a good improvement anyways (perhaps from removing priority). |
|
utACK 37495e0. Verified with |
|
utACK 37495e0 |
ryanofsky
reviewed
Jul 25, 2017
utACK 37495e0. Should update outdated PR description though to avoid misleading text in git history.
JeremyRubin commentedJul 11, 2016
These commits revise the layout of a few key classes to eliminate padding, eliminating useless memory overhead.
CTxMemPoolEntry is decreased to 184 bytes from 192. CTransaction is decreased to 112 bytes from 120.
Furthermore, it is clarified in CTxMempoolEntry where the extra space is (2 bytes) for future overhead-free use.
The introduction of CTxMemPoolEntryFlags is used to bit-pack the bool flags, making room for 6 more future-flags. I have not performance tested this, but it should not be much. It does not save any space at the moment due to padding, but if more bools are added it would compared to naive.
To finish this work, the following should be done: profiling of access patterns to class fields to guarantee cache-line co-residency, cross architecture padding optimizations.