Use 8 byte pages for "max of max"

This seems to benchmark better
This commit is contained in:
2024-06-26 19:18:38 -07:00
parent c882d7663d
commit 08f2998a85

View File

@@ -309,8 +309,11 @@ struct Node256 : Node {
constexpr static auto kType = Type_Node256; constexpr static auto kType = Type_Node256;
BitSet bitSet; BitSet bitSet;
Child children[256]; Child children[256];
// Max of each "page" of 16 children constexpr static int kMaxOfMaxPageSize = 8;
int64_t maxOfMax[16]; constexpr static int kMaxOfMaxShift =
std::countr_zero(uint32_t(kMaxOfMaxPageSize));
constexpr static int kMaxOfMaxTotalPages = 256 / kMaxOfMaxPageSize;
int64_t maxOfMax[kMaxOfMaxTotalPages];
uint8_t *partialKey() { return (uint8_t *)(this + 1); } uint8_t *partialKey() { return (uint8_t *)(this + 1); }
void copyChildrenAndKeyFrom(const Node48 &other); void copyChildrenAndKeyFrom(const Node48 &other);
void copyChildrenAndKeyFrom(const Node256 &other); void copyChildrenAndKeyFrom(const Node256 &other);
@@ -471,8 +474,9 @@ inline void Node256::copyChildrenAndKeyFrom(const Node48 &other) {
children[c] = other.children[other.index[c]]; children[c] = other.children[other.index[c]];
assert(children[c].child->parent == &other); assert(children[c].child->parent == &other);
children[c].child->parent = this; children[c].child->parent = this;
maxOfMax[c >> 4] = maxOfMax[c >> Node256::kMaxOfMaxShift] =
std::max(maxOfMax[c >> 4], children[c].childMaxVersion); std::max(maxOfMax[c >> Node256::kMaxOfMaxShift],
children[c].childMaxVersion);
}, },
0, 256); 0, 256);
memcpy(partialKey(), &other + 1, partialKeyLen); memcpy(partialKey(), &other + 1, partialKeyLen);
@@ -1713,10 +1717,10 @@ bool checkMaxBetweenExclusive(Node *n, int begin, int end,
case Type_Node256: { case Type_Node256: {
auto *self = static_cast<Node256 *>(n); auto *self = static_cast<Node256 *>(n);
// Check the first page // Check the first page
if (self->maxOfMax[begin >> 4] > readVersion) { if (self->maxOfMax[begin >> Node256::kMaxOfMaxShift] > readVersion) {
bool result = true; bool result = true;
for (int i = 0; i < 16; ++i) { for (int i = 0; i < Node256::kMaxOfMaxPageSize; ++i) {
int j = (begin & ~15) + i; int j = (begin & ~(Node256::kMaxOfMaxPageSize - 1)) + i;
result &= !((self->children[j].childMaxVersion > readVersion) & result &= !((self->children[j].childMaxVersion > readVersion) &
(begin <= j) & (j < end)); (begin <= j) & (j < end));
} }
@@ -1725,10 +1729,11 @@ bool checkMaxBetweenExclusive(Node *n, int begin, int end,
} }
} }
// Check the last page // Check the last page
if (end >= 1 && self->maxOfMax[(end - 1) >> 4] > readVersion) { if (end >= 1 &&
self->maxOfMax[(end - 1) >> Node256::kMaxOfMaxShift] > readVersion) {
bool result = true; bool result = true;
for (int i = 0; i < 16; ++i) { for (int i = 0; i < Node256::kMaxOfMaxPageSize; ++i) {
int j = ((end - 1) & ~15) + i; int j = ((end - 1) & ~(Node256::kMaxOfMaxPageSize - 1)) + i;
result &= !((self->children[j].childMaxVersion > readVersion) & result &= !((self->children[j].childMaxVersion > readVersion) &
(begin <= j) & (j < end)); (begin <= j) & (j < end));
} }
@@ -1738,9 +1743,10 @@ bool checkMaxBetweenExclusive(Node *n, int begin, int end,
} }
// Check inner pages // Check inner pages
bool result = true; bool result = true;
for (int i = 0; i < 16; ++i) { for (int i = 1; i < Node256::kMaxOfMaxTotalPages - 1; ++i) {
result &= !((self->maxOfMax[i] > readVersion) & ((begin >> 4) + 1 <= i) & result &= !((self->maxOfMax[i] > readVersion) &
(i < ((end - 1) >> 4))); ((begin >> Node256::kMaxOfMaxShift) + 1 <= i) &
(i < ((end - 1) >> Node256::kMaxOfMaxShift)));
} }
return result; return result;
} }
@@ -2676,7 +2682,8 @@ void setMaxVersion(Node *n, ConflictSet::Impl *impl, int64_t newMax) {
auto *n256 = static_cast<Node256 *>(n); auto *n256 = static_cast<Node256 *>(n);
assert(n256->bitSet.test(index)); assert(n256->bitSet.test(index));
n256->children[index].childMaxVersion = newMax; n256->children[index].childMaxVersion = newMax;
n256->maxOfMax[index >> 4] = std::max(n256->maxOfMax[index >> 4], newMax); n256->maxOfMax[index >> Node256::kMaxOfMaxShift] =
std::max(n256->maxOfMax[index >> Node256::kMaxOfMaxShift], newMax);
return; return;
} }
default: // GCOVR_EXCL_LINE default: // GCOVR_EXCL_LINE