in cachelib/benchmarks/CacheAllocatorOpsMicroBench.cpp [249:315]
void runAllocateMultiThreads(int numThreads,
bool preFillupCache,
std::vector<uint32_t> payloadSizes) {
constexpr uint64_t kLoops = 1;
constexpr uint64_t kObjects = 100'000;
auto cache = getCache();
std::vector<std::string> keys;
for (uint64_t i = 0; i < kObjects; i++) {
// Length of key should be 10 bytes
auto key = folly::sformat("k_{: <8}", i);
keys.push_back(key);
}
if (preFillupCache) {
uint64_t i = keys.size();
std::vector<LruAllocator::ItemHandle> handles;
while (true) {
// Length of key should be 10 bytes
auto key = folly::sformat("k_{: <8}", i);
auto hdl = cache->allocate(0, key, payloadSizes[i % payloadSizes.size()]);
if (!hdl) {
// Cache is full. Stop prefill.
break;
}
cache->insertOrReplace(hdl);
handles.push_back(std::move(hdl));
i++;
}
}
navy::SeqPoints sp;
auto writeOps = [&](uint64_t start, uint64_t end) {
sp.wait(0);
for (uint64_t loops = 0; loops < kLoops; loops++) {
for (uint64_t i = start; i < end; i++) {
auto& key = keys[i];
auto hdl =
cache->allocate(0, key, payloadSizes[i % payloadSizes.size()]);
XCHECK(hdl);
cache->insertOrReplace(hdl);
}
}
};
// Create writers
std::vector<std::thread> ws;
uint64_t startIndex = 0;
uint64_t chunkSize = kObjects / numThreads;
uint64_t totalItemsPerThread = chunkSize * kLoops;
for (int i = 0; i < numThreads; i++) {
ws.push_back(std::thread{writeOps, startIndex, startIndex + chunkSize});
startIndex += chunkSize;
}
{
Timer t{folly::sformat("Allocate - {} - {: <2} Threads, {: <2} Sizes",
preFillupCache ? "Eviction" : "New ", numThreads,
payloadSizes.size()),
totalItemsPerThread};
sp.reached(0); // Start the operations
for (auto& w : ws) {
w.join();
}
}
}