4 Commits

Author SHA1 Message Date
c46f633dbf Skip sorting if already sorted for skip list
All checks were successful
Tests / 64 bit versions total: 7950, passed: 7950
Tests / Debug total: 7948, passed: 7948
Tests / SIMD fallback total: 7950, passed: 7950
Tests / Release [clang] total: 7950, passed: 7950
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc] total: 7950, passed: 7950
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [clang,aarch64] total: 5268, passed: 5268
Tests / Coverage total: 5316, passed: 5316
Code Coverage #### Project Overview No changes detected, that affect the code coverage. * Line Coverage: 97.67% (3138/3213) * Branch Coverage: 42.05% (18734/44548) * Complexity Density: 0.00 * Lines of Code: 3213 #### Quality Gates Summary Output truncated.
weaselab/conflict-set/pipeline/head This commit looks good
2024-11-12 13:25:29 -08:00
400350946c Point read/write workload for server_bench 2024-11-12 10:50:03 -08:00
607a4ef6e2 Require musttail and preserve_none for interleaved 2024-11-11 21:40:05 -08:00
b0750772ec Don't do hardening check if cross compiling
All checks were successful
Tests / 64 bit versions total: 7950, passed: 7950
Tests / Debug total: 7948, passed: 7948
Tests / SIMD fallback total: 7950, passed: 7950
Tests / Release [clang] total: 7950, passed: 7950
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc] total: 7950, passed: 7950
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [clang,aarch64] total: 5268, passed: 5268
Tests / Coverage total: 5316, passed: 5316
Code Coverage #### Project Overview No changes detected, that affect the code coverage. * Line Coverage: 97.67% (3139/3214) * Branch Coverage: 42.05% (18734/44548) * Complexity Density: 0.00 * Lines of Code: 3214 #### Quality Gates Summary Output truncated.
weaselab/conflict-set/pipeline/head This commit looks good
2024-11-11 16:56:28 -08:00
4 changed files with 82 additions and 62 deletions

View File

@@ -380,11 +380,13 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR AND BUILD_TESTING)
${symbol_imports}) ${symbol_imports})
endif() endif()
find_program(HARDENING_CHECK hardening-check) if(NOT CMAKE_CROSSCOMPILING)
if(HARDENING_CHECK) find_program(HARDENING_CHECK hardening-check)
add_test(NAME hardening_check if(HARDENING_CHECK)
COMMAND ${HARDENING_CHECK} $<TARGET_FILE:${PROJECT_NAME}> add_test(NAME hardening_check
--nofortify --nostackprotector) COMMAND ${HARDENING_CHECK} $<TARGET_FILE:${PROJECT_NAME}>
--nofortify --nostackprotector)
endif()
endif() endif()
# bench # bench

View File

@@ -3183,6 +3183,12 @@ Node *firstGeqPhysical(Node *n, const TrivialSpan key) {
#define PRESERVE_NONE #define PRESERVE_NONE
#endif #endif
#if __has_attribute(musttail) && __has_attribute(preserve_none)
constexpr bool kEnableInterleaved = true;
#else
constexpr bool kEnableInterleaved = false;
#endif
namespace check { namespace check {
typedef PRESERVE_NONE void (*Continuation)(struct Job *, struct Context *); typedef PRESERVE_NONE void (*Continuation)(struct Job *, struct Context *);
@@ -4969,51 +4975,50 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
check::Context context; check::Context context;
context.readContext.impl = this; context.readContext.impl = this;
#if __has_attribute(musttail) if constexpr (kEnableInterleaved) {
if (count == 1) { if (count == 1) {
useSequential(reads, result, count, context); useSequential(reads, result, count, context);
} else { } else {
constexpr int kConcurrent = 16; constexpr int kConcurrent = 16;
check::Job inProgress[kConcurrent]; check::Job inProgress[kConcurrent];
context.count = count; context.count = count;
context.oldestVersionFullPrecision = oldestVersionFullPrecision; context.oldestVersionFullPrecision = oldestVersionFullPrecision;
context.root = root; context.root = root;
context.queries = reads; context.queries = reads;
context.results = result; context.results = result;
int64_t started = std::min(kConcurrent, count); int64_t started = std::min(kConcurrent, count);
context.started = started; context.started = started;
for (int i = 0; i < started; i++) { for (int i = 0; i < started; i++) {
inProgress[i].init(reads + i, result + i, root, inProgress[i].init(reads + i, result + i, root,
oldestVersionFullPrecision); oldestVersionFullPrecision);
} }
for (int i = 0; i < started - 1; i++) { for (int i = 0; i < started - 1; i++) {
inProgress[i].next = inProgress + i + 1; inProgress[i].next = inProgress + i + 1;
} }
for (int i = 1; i < started; i++) { for (int i = 1; i < started; i++) {
inProgress[i].prev = inProgress + i - 1; inProgress[i].prev = inProgress + i - 1;
} }
inProgress[0].prev = inProgress + started - 1; inProgress[0].prev = inProgress + started - 1;
inProgress[started - 1].next = inProgress; inProgress[started - 1].next = inProgress;
// Kick off the sequence of tail calls that finally returns once all jobs // Kick off the sequence of tail calls that finally returns once all
// are done // jobs are done
inProgress->continuation(inProgress, &context); inProgress->continuation(inProgress, &context);
#ifndef NDEBUG #ifndef NDEBUG
Arena arena; Arena arena;
auto *results2 = new (arena) Result[count]; auto *results2 = new (arena) Result[count];
check::Context context2; check::Context context2;
context2.readContext.impl = this; context2.readContext.impl = this;
useSequential(reads, results2, count, context2); useSequential(reads, results2, count, context2);
assert(memcmp(result, results2, count) == 0); assert(memcmp(result, results2, count) == 0);
assert(context.readContext == context2.readContext); assert(context.readContext == context2.readContext);
#endif #endif
}
} else {
useSequential(reads, result, count, context);
} }
#else
useSequential(reads, result, count, context);
#endif
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
assert(reads[i].readVersion >= 0); assert(reads[i].readVersion >= 0);
assert(reads[i].readVersion <= newestVersionFullPrecision); assert(reads[i].readVersion <= newestVersionFullPrecision);
@@ -5186,11 +5191,6 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
assert(allPointWrites || sorted); assert(allPointWrites || sorted);
#endif #endif
#if __has_attribute(musttail)
constexpr bool kEnableInterleaved = true;
#else
constexpr bool kEnableInterleaved = false;
#endif
if (kEnableInterleaved && count > 1) { if (kEnableInterleaved && count > 1) {
interleavedWrites(writes, count, InternalVersionT(writeVersion)); interleavedWrites(writes, count, InternalVersionT(writeVersion));
} else { } else {

View File

@@ -64,31 +64,47 @@ template <class... Ts> std::string tupleKey(const Ts &...ts) {
return result; return result;
} }
constexpr int kWindowSize = 300000; constexpr int kTotalKeyRange = 1'000'000'000;
constexpr int kWindowSize = 1'000'000;
constexpr int kNumKeys = 10;
void workload(weaselab::ConflictSet *cs) { void workload(weaselab::ConflictSet *cs) {
int64_t version = kWindowSize; int64_t version = kWindowSize;
constexpr int kNumWrites = 16;
for (;; transactions.fetch_add(1, std::memory_order_relaxed)) { for (;; transactions.fetch_add(1, std::memory_order_relaxed)) {
std::vector<int64_t> keyIndices; std::vector<int64_t> keyIndices;
for (int i = 0; i < kNumWrites; ++i) { for (int i = 0; i < kNumKeys; ++i) {
keyIndices.push_back(rand() % 100'000'000); keyIndices.push_back(rand() % kTotalKeyRange);
} }
std::sort(keyIndices.begin(), keyIndices.end()); std::sort(keyIndices.begin(), keyIndices.end());
std::vector<std::string> keys; std::vector<std::string> keys;
std::vector<weaselab::ConflictSet::WriteRange> writes; constexpr std::string_view fullString =
constexpr std::string_view suffix = "this is a suffix"; "this is a string, where a prefix of it is used as an element of the "
for (int i = 0; i < kNumWrites; ++i) { "tuple forming the key";
keys.push_back(tupleKey(0x100, i, keyIndices[i], for (int i = 0; i < kNumKeys; ++i) {
suffix.substr(0, rand() % suffix.size()), keys.push_back(
rand())); tupleKey(0x100, keyIndices[i] / fullString.size(),
fullString.substr(0, keyIndices[i] % fullString.size())));
// printf("%s\n", printable(keys.back()).c_str()); // printf("%s\n", printable(keys.back()).c_str());
} }
for (int i = 0; i < kNumWrites; ++i) {
std::vector<weaselab::ConflictSet::ReadRange> reads;
std::vector<weaselab::ConflictSet::WriteRange> writes;
std::vector<weaselab::ConflictSet::Result> results;
for (int i = 0; i < kNumKeys; ++i) {
writes.push_back({{(const uint8_t *)keys[i].data(), int(keys[i].size())}, writes.push_back({{(const uint8_t *)keys[i].data(), int(keys[i].size())},
{nullptr, 0}}); {nullptr, 0}});
reads.push_back({{(const uint8_t *)keys[i].data(), int(keys[i].size())},
{nullptr, 0},
version - kWindowSize});
} }
cs->addWrites(writes.data(), writes.size(), version); results.resize(reads.size());
cs->check(reads.data(), results.data(), reads.size());
bool ok = true;
for (auto result : results) {
ok &= result == weaselab::ConflictSet::Commit;
}
cs->addWrites(writes.data(), ok ? writes.size() : 0, version);
cs->setOldestVersion(version - kWindowSize); cs->setOldestVersion(version - kWindowSize);
++version; ++version;
} }

View File

@@ -767,7 +767,9 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
false, true); false, true);
} }
sortPoints(points); if (!std::is_sorted(points.begin(), points.end())) {
sortPoints(points);
}
int activeWriteCount = 0; int activeWriteCount = 0;
std::vector<std::pair<StringRef, StringRef>> combinedWriteConflictRanges; std::vector<std::pair<StringRef, StringRef>> combinedWriteConflictRanges;