Skip to content

Commit 1d16e1a

Browse files
authored
Merge pull request #85 from igchor/touch_value_develop
Extend cachbench with touch value
2 parents 681bcbc + 21c2e31 commit 1d16e1a

File tree

5 files changed

+28
-39
lines changed

5 files changed

+28
-39
lines changed

cachelib/cachebench/cache/Cache-inl.h

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,10 @@ uint64_t Cache<Allocator>::fetchNandWrites() const {
5050
template <typename Allocator>
5151
Cache<Allocator>::Cache(const CacheConfig& config,
5252
ChainedItemMovingSync movingSync,
53-
std::string cacheDir)
53+
std::string cacheDir,
54+
bool touchValue)
5455
: config_(config),
56+
touchValue_(touchValue),
5557
nandBytesBegin_{fetchNandWrites()},
5658
itemRecords_(config_.enableItemDestructorCheck) {
5759
constexpr size_t MB = 1024ULL * 1024ULL;
@@ -325,22 +327,13 @@ template <typename Allocator>
325327
void Cache<Allocator>::enableConsistencyCheck(
326328
const std::vector<std::string>& keys) {
327329
XDCHECK(valueTracker_ == nullptr);
328-
XDCHECK(!valueValidatingEnabled());
329330
valueTracker_ =
330331
std::make_unique<ValueTracker>(ValueTracker::wrapStrings(keys));
331332
for (const std::string& key : keys) {
332333
invalidKeys_[key] = false;
333334
}
334335
}
335336

336-
template <typename Allocator>
337-
void Cache<Allocator>::enableValueValidating(
338-
const std::string &expectedValue) {
339-
XDCHECK(!valueValidatingEnabled());
340-
XDCHECK(!consistencyCheckEnabled());
341-
this->expectedValue_ = expectedValue;
342-
}
343-
344337
template <typename Allocator>
345338
typename Cache<Allocator>::RemoveRes Cache<Allocator>::remove(Key key) {
346339
if (!consistencyCheckEnabled()) {
@@ -434,17 +427,15 @@ typename Cache<Allocator>::ItemHandle Cache<Allocator>::insertOrReplace(
434427
}
435428

436429
template <typename Allocator>
437-
void Cache<Allocator>::validateValue(const ItemHandle &it) const {
438-
XDCHECK(valueValidatingEnabled());
439-
440-
const auto &expected = expectedValue_.value();
430+
void Cache<Allocator>::touchValue(const ItemHandle& it) const {
431+
XDCHECK(touchValueEnabled());
441432

442433
auto ptr = reinterpret_cast<const uint8_t*>(getMemory(it));
443-
auto cmp = std::memcmp(ptr, expected.data(), std::min<size_t>(expected.size(),
444-
getSize(it)));
445-
if (cmp != 0) {
446-
throw std::runtime_error("Value does not match!");
447-
}
434+
435+
/* The accumulate call is intended to access all bytes of the value
436+
* and nothing more. */
437+
auto sum = std::accumulate(ptr, ptr + getSize(it), 0ULL);
438+
folly::doNotOptimizeAway(sum);
448439
}
449440

450441
template <typename Allocator>
@@ -459,9 +450,8 @@ typename Cache<Allocator>::ItemHandle Cache<Allocator>::find(Key key,
459450
auto it = cache_->find(key, mode);
460451
it.wait();
461452

462-
if (valueValidatingEnabled()) {
463-
XDCHECK(!consistencyCheckEnabled());
464-
validateValue(it);
453+
if (touchValueEnabled()) {
454+
touchValue(it);
465455
}
466456

467457
return it;
@@ -472,8 +462,6 @@ typename Cache<Allocator>::ItemHandle Cache<Allocator>::find(Key key,
472462
return it;
473463
}
474464

475-
XDCHECK(!valueValidatingEnabled());
476-
477465
auto opId = valueTracker_->beginGet(key);
478466
auto it = findFn();
479467
if (checkGet(opId, it)) {

cachelib/cachebench/cache/Cache.h

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,11 @@ class Cache {
6464
// cache.
6565
// @param cacheDir optional directory for the cache to enable
6666
// persistence across restarts.
67+
// @param touchValue read entire value on find
6768
explicit Cache(const CacheConfig& config,
6869
ChainedItemMovingSync movingSync = {},
69-
std::string cacheDir = "");
70+
std::string cacheDir = "",
71+
bool touchValue = true);
7072

7173
~Cache();
7274

@@ -168,8 +170,8 @@ class Cache {
168170
return getSize(item.get());
169171
}
170172

171-
// checks if values stored in it matches expectedValue_.
172-
void validateValue(const ItemHandle &it) const;
173+
// read entire value on find.
174+
void touchValue(const ItemHandle& it) const;
173175

174176
// returns the size of the item, taking into account ItemRecords could be
175177
// enabled.
@@ -228,14 +230,11 @@ class Cache {
228230
// @param keys list of keys that the stressor uses for the workload.
229231
void enableConsistencyCheck(const std::vector<std::string>& keys);
230232

231-
// enables validating all values on find. Each value is compared to
232-
// expected Value.
233-
void enableValueValidating(const std::string &expectedValue);
234-
235233
// returns true if the consistency checking is enabled.
236234
bool consistencyCheckEnabled() const { return valueTracker_ != nullptr; }
237235

238-
bool valueValidatingEnabled() const { return expectedValue_.has_value(); }
236+
// returns true if touching value is enabled.
237+
bool touchValueEnabled() const { return touchValue_; }
239238

240239
// return true if the key was previously detected to be inconsistent. This
241240
// is useful only when consistency checking is enabled by calling
@@ -359,8 +358,8 @@ class Cache {
359358
// tracker for consistency monitoring.
360359
std::unique_ptr<ValueTracker> valueTracker_;
361360

362-
// exceptected value of all items in Cache.
363-
std::optional<std::string> expectedValue_;
361+
// read entire value on find.
362+
bool touchValue_{true};
364363

365364
// reading of the nand bytes written for the benchmark if enabled.
366365
const uint64_t nandBytesBegin_{0};

cachelib/cachebench/runner/CacheStressor.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ class CacheStressor : public Stressor {
9393
cacheConfig.ticker = ticker_;
9494
}
9595

96-
cache_ = std::make_unique<CacheT>(cacheConfig, movingSync);
96+
cache_ = std::make_unique<CacheT>(cacheConfig, movingSync, "",
97+
config_.touchValue);
9798
if (config_.opPoolDistribution.size() > cache_->numPools()) {
9899
throw std::invalid_argument(folly::sformat(
99100
"more pools specified in the test than in the cache. "
@@ -110,9 +111,6 @@ class CacheStressor : public Stressor {
110111
if (config_.checkConsistency) {
111112
cache_->enableConsistencyCheck(wg_->getAllKeys());
112113
}
113-
if (config_.validateValue) {
114-
cache_->enableValueValidating(hardcodedString_);
115-
}
116114
if (config_.opRatePerSec > 0) {
117115
rateLimiter_ = std::make_unique<folly::BasicTokenBucket<>>(
118116
config_.opRatePerSec, config_.opRatePerSec);

cachelib/cachebench/util/Config.cpp

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

3636
JSONSetVal(configJson, checkConsistency);
37-
JSONSetVal(configJson, validateValue);
37+
JSONSetVal(configJson, touchValue);
3838

3939
JSONSetVal(configJson, numOps);
4040
JSONSetVal(configJson, numThreads);

cachelib/cachebench/util/Config.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,10 @@ struct StressorConfig : public JSONConfig {
195195
// Mutually exclusive with checkConsistency
196196
bool validateValue{false};
197197

198+
// If enabled, each value will be read on find. This is useful for measuring
199+
// performance of value access.
200+
bool touchValue{true};
201+
198202
uint64_t numOps{0}; // operation per thread
199203
uint64_t numThreads{0}; // number of threads that will run
200204
uint64_t numKeys{0}; // number of keys that will be used

0 commit comments

Comments
 (0)