Skip to content

Commit 23684c2

Browse files
igchorroot
authored andcommitted
Extend cachbench with touch value
The main purpose of this patch is to better simulate workloads in cachebench. Setting touchValue to true allows to see performance impact of using different mediums for memory cache.
1 parent fa2e533 commit 23684c2

File tree

5 files changed

+38
-3
lines changed

5 files changed

+38
-3
lines changed

cachelib/cachebench/cache/Cache-inl.h

Lines changed: 19 additions & 1 deletion
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;
@@ -397,6 +399,15 @@ typename Cache<Allocator>::ItemHandle Cache<Allocator>::insertOrReplace(
397399
return rv;
398400
}
399401

402+
template <typename Allocator>
403+
void Cache<Allocator>::touchValue(const ItemHandle& it) const {
404+
XDCHECK(touchValueEnabled());
405+
406+
auto ptr = reinterpret_cast<const uint8_t*>(getMemory(it));
407+
auto sum = std::accumulate(ptr, ptr + getSize(it), 0ULL);
408+
folly::doNotOptimizeAway(sum);
409+
}
410+
400411
template <typename Allocator>
401412
typename Cache<Allocator>::ItemHandle Cache<Allocator>::find(Key key,
402413
AccessMode mode) {
@@ -408,13 +419,20 @@ typename Cache<Allocator>::ItemHandle Cache<Allocator>::find(Key key,
408419
// find from cache and wait for the result to be ready.
409420
auto it = cache_->findImpl(key, mode);
410421
it.wait();
422+
423+
if (touchValueEnabled()) {
424+
touchValue(it);
425+
}
426+
411427
return it;
412428
};
413429

414430
if (!consistencyCheckEnabled()) {
415431
return findFn();
416432
}
417433

434+
XDCHECK(!touchValueEnabled());
435+
418436
auto opId = valueTracker_->beginGet(key);
419437
auto it = findFn();
420438
if (checkGet(opId, it)) {

cachelib/cachebench/cache/Cache.h

Lines changed: 12 additions & 1 deletion
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 = false);
7072

7173
~Cache();
7274

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

173+
// read entire value on find.
174+
void touchValue(const ItemHandle& it) const;
175+
171176
// returns the size of the item, taking into account ItemRecords could be
172177
// enabled.
173178
uint32_t getSize(const Item* item) const noexcept;
@@ -230,6 +235,9 @@ class Cache {
230235
// returns true if the consistency checking is enabled.
231236
bool consistencyCheckEnabled() const { return valueTracker_ != nullptr; }
232237

238+
// returns true if touching value is enabled.
239+
bool touchValueEnabled() const { return touchValue_; }
240+
233241
// return true if the key was previously detected to be inconsistent. This
234242
// is useful only when consistency checking is enabled by calling
235243
// enableConsistencyCheck()
@@ -352,6 +360,9 @@ class Cache {
352360
// tracker for consistency monitoring.
353361
std::unique_ptr<ValueTracker> valueTracker_;
354362

363+
// read entire value on find.
364+
bool touchValue_{false};
365+
355366
// reading of the nand bytes written for the benchmark if enabled.
356367
const uint64_t nandBytesBegin_{0};
357368

cachelib/cachebench/runner/CacheStressor.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ class CacheStressor : public Stressor {
9595
cacheConfig.ticker = ticker_;
9696
}
9797

98-
cache_ = std::make_unique<CacheT>(cacheConfig, movingSync);
98+
cache_ = std::make_unique<CacheT>(cacheConfig, movingSync, "",
99+
config_.touchValue);
99100
if (config_.opPoolDistribution.size() > cache_->numPools()) {
100101
throw std::invalid_argument(folly::sformat(
101102
"more pools specified in the test than in the cache. "

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, touchValue);
3738

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

cachelib/cachebench/util/Config.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,10 @@ struct StressorConfig : public JSONConfig {
194194
// output stats after warmup.
195195
bool checkNvmCacheWarmUp{false};
196196

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

0 commit comments

Comments
 (0)