Skip to content

Commit 74af02b

Browse files
committed
Extend cachbench with value validation
The main purpose of this patch is to better simulate workloads in cachebench. Setting validateValue to true allows to see performance impact of using different mediums for memory cache.
1 parent fa2e533 commit 74af02b

File tree

5 files changed

+51
-0
lines changed

5 files changed

+51
-0
lines changed

cachelib/cachebench/cache/Cache-inl.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,13 +298,21 @@ template <typename Allocator>
298298
void Cache<Allocator>::enableConsistencyCheck(
299299
const std::vector<std::string>& keys) {
300300
XDCHECK(valueTracker_ == nullptr);
301+
XDCHECK(!valueValidatingEnabled());
301302
valueTracker_ =
302303
std::make_unique<ValueTracker>(ValueTracker::wrapStrings(keys));
303304
for (const std::string& key : keys) {
304305
invalidKeys_[key] = false;
305306
}
306307
}
307308

309+
template <typename Allocator>
310+
void Cache<Allocator>::enableValueValidating(const std::string& expectedValue) {
311+
XDCHECK(!valueValidatingEnabled());
312+
XDCHECK(!consistencyCheckEnabled());
313+
this->expectedValue_ = expectedValue;
314+
}
315+
308316
template <typename Allocator>
309317
typename Cache<Allocator>::RemoveRes Cache<Allocator>::remove(Key key) {
310318
if (!consistencyCheckEnabled()) {
@@ -397,6 +405,20 @@ typename Cache<Allocator>::ItemHandle Cache<Allocator>::insertOrReplace(
397405
return rv;
398406
}
399407

408+
template <typename Allocator>
409+
void Cache<Allocator>::validateValue(const ItemHandle& it) const {
410+
XDCHECK(valueValidatingEnabled());
411+
412+
const auto& expected = expectedValue_.value();
413+
414+
auto ptr = reinterpret_cast<const uint8_t*>(getMemory(it));
415+
auto cmp = std::memcmp(ptr, expected.data(),
416+
std::min<size_t>(expected.size(), getSize(it)));
417+
if (cmp != 0) {
418+
throw std::runtime_error("Value does not match!");
419+
}
420+
}
421+
400422
template <typename Allocator>
401423
typename Cache<Allocator>::ItemHandle Cache<Allocator>::find(Key key,
402424
AccessMode mode) {
@@ -408,13 +430,21 @@ typename Cache<Allocator>::ItemHandle Cache<Allocator>::find(Key key,
408430
// find from cache and wait for the result to be ready.
409431
auto it = cache_->findImpl(key, mode);
410432
it.wait();
433+
434+
if (valueValidatingEnabled()) {
435+
XDCHECK(!consistencyCheckEnabled());
436+
validateValue(it);
437+
}
438+
411439
return it;
412440
};
413441

414442
if (!consistencyCheckEnabled()) {
415443
return findFn();
416444
}
417445

446+
XDCHECK(!valueValidatingEnabled());
447+
418448
auto opId = valueTracker_->beginGet(key);
419449
auto it = findFn();
420450
if (checkGet(opId, it)) {

cachelib/cachebench/cache/Cache.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,9 @@ class Cache {
168168
return getSize(item.get());
169169
}
170170

171+
// checks if values stored in it matches expectedValue_.
172+
void validateValue(const ItemHandle& it) const;
173+
171174
// returns the size of the item, taking into account ItemRecords could be
172175
// enabled.
173176
uint32_t getSize(const Item* item) const noexcept;
@@ -227,9 +230,15 @@ class Cache {
227230
// @param keys list of keys that the stressor uses for the workload.
228231
void enableConsistencyCheck(const std::vector<std::string>& keys);
229232

233+
// enables validating all values on find. Each value is compared to
234+
// expected Value.
235+
void enableValueValidating(const std::string& expectedValue);
236+
230237
// returns true if the consistency checking is enabled.
231238
bool consistencyCheckEnabled() const { return valueTracker_ != nullptr; }
232239

240+
bool valueValidatingEnabled() const { return expectedValue_.has_value(); }
241+
233242
// return true if the key was previously detected to be inconsistent. This
234243
// is useful only when consistency checking is enabled by calling
235244
// enableConsistencyCheck()
@@ -352,6 +361,9 @@ class Cache {
352361
// tracker for consistency monitoring.
353362
std::unique_ptr<ValueTracker> valueTracker_;
354363

364+
// expected value of all items in Cache.
365+
std::optional<std::string> expectedValue_;
366+
355367
// reading of the nand bytes written for the benchmark if enabled.
356368
const uint64_t nandBytesBegin_{0};
357369

cachelib/cachebench/runner/CacheStressor.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,9 @@ class CacheStressor : public Stressor {
112112
if (config_.checkConsistency) {
113113
cache_->enableConsistencyCheck(wg_->getAllKeys());
114114
}
115+
if (config_.validateValue) {
116+
cache_->enableValueValidating(hardcodedString_);
117+
}
115118
if (config_.opRatePerSec > 0) {
116119
rateLimiter_ = std::make_unique<folly::BasicTokenBucket<>>(
117120
config_.opRatePerSec, config_.opRatePerSec);

cachelib/cachebench/util/Config.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ StressorConfig::StressorConfig(const folly::dynamic& configJson) {
3434
JSONSetVal(configJson, samplingIntervalMs);
3535

3636
JSONSetVal(configJson, checkConsistency);
37+
JSONSetVal(configJson, validateValue);
3738

3839
JSONSetVal(configJson, numOps);
3940
JSONSetVal(configJson, numThreads);

cachelib/cachebench/util/Config.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,12 +188,17 @@ struct StressorConfig : public JSONConfig {
188188
uint64_t samplingIntervalMs{1000};
189189

190190
// If enabled, stressor will verify operations' results are consistent.
191+
// Mutually exclusive with validateValue
191192
bool checkConsistency{false};
192193

193194
// If enabled, stressor will check whether nvm cache has been warmed up and
194195
// output stats after warmup.
195196
bool checkNvmCacheWarmUp{false};
196197

198+
// If enable, stressor will verify if value read is equal to value written.
199+
// Mutually exclusive with checkConsistency
200+
bool validateValue{false};
201+
197202
uint64_t numOps{0}; // operation per thread
198203
uint64_t numThreads{0}; // number of threads that will run
199204
uint64_t numKeys{0}; // number of keys that will be used

0 commit comments

Comments
 (0)