/*
- * Copyright 2013 Facebook, Inc.
+ * Copyright 2017 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
// @author: Xin Liu <xliux@fb.com>
#include <map>
+#include <memory>
+#include <random>
#include <set>
#include <thread>
-#include <gflags/gflags.h>
+#include <folly/Benchmark.h>
+#include <folly/ConcurrentSkipList.h>
+#include <folly/RWSpinLock.h>
+#include <folly/hash/Hash.h>
+#include <folly/portability/GFlags.h>
#include <glog/logging.h>
-#include "folly/Benchmark.h"
-#include "folly/ConcurrentSkipList.h"
-#include "folly/Hash.h"
-#include "folly/RWSpinLock.h"
-
DEFINE_int32(num_threads, 12, "num concurrent threads to test");
for (int i = 0; i < kMaxValue; ++i) {
gData[i] = i;
}
- std::random_shuffle(gData.begin(), gData.end());
+ std::shuffle(gData.begin(), gData.end(), std::mt19937{});
}
// single thread benchmarks
auto iter = a_set.begin();
for (int i = 0; i < iters; ++i) {
sum += *iter++;
- if (iter == a_set.end()) iter = a_set.begin();
+ if (iter == a_set.end()) {
+ iter = a_set.begin();
+ }
}
BENCHMARK_SUSPEND {
// VLOG(20) << "sum = " << sum;
auto iter = skipList.begin();
for (int i = 0; i < iters; ++i) {
sum += *iter++;
- if (iter == skipList.end()) iter = skipList.begin();
+ if (iter == skipList.end()) {
+ iter = skipList.begin();
+ }
}
BENCHMARK_SUSPEND {
int64_t mergedSum = 0;
FOR_EACH(it, a_set) {
- if (b_set.find(*it) != b_set.end()) mergedSum += *it;
+ if (b_set.find(*it) != b_set.end()) {
+ mergedSum += *it;
+ }
}
BENCHMARK_SUSPEND {
// VLOG(20) << mergedSum;
SkipListType::Skipper skipper(skipList2);
FOR_EACH(it, skipList) {
- if (skipper.to(*it)) mergedSum += *it;
+ if (skipper.to(*it)) {
+ mergedSum += *it;
+ }
}
BENCHMARK_SUSPEND {
auto sl = skiplist.get();
susp.dismiss();
- for (int i = 0; i < iters; ++i) {
+ for (size_t i = 0; i < iters; ++i) {
SkipListAccessor accessor(sl);
}
}
l.init();
susp.dismiss();
- for (int i = 0; i < iters; ++i) {
+ for (size_t i = 0; i < iters; ++i) {
value->fetch_add(1, std::memory_order_relaxed);
if (dirty->load(std::memory_order_acquire) != 0) {
folly::MSLGuard g(l);
for (int i = 0; i < FLAGS_num_sets; ++i) {
locks_[i] = new RWSpinLock();
- if (i > 0) sets_[i] = sets_[0];
+ if (i > 0) {
+ sets_[i] = sets_[0];
+ }
}
+// This requires knowledge of the C++ library internals. Only use it if we're
+// using the GNU C++ library.
+#ifdef _GLIBCXX_SYMVER
// memory usage
int64_t setMemorySize = sets_[0].size() * sizeof(*sets_[0].begin()._M_node);
int64_t cslMemorySize = 0;
LOG(INFO) << "size=" << sets_[0].size()
<< "; std::set memory size=" << setMemorySize
<< "; csl memory size=" << cslMemorySize;
+#endif
readValues_.reserve(size);
deleteValues_.reserve(size);
// half new values and half already in the list
writeValues_.push_back((rand() % 2) + 2 * i);
}
- std::random_shuffle(readValues_.begin(), readValues_.end());
- std::random_shuffle(deleteValues_.begin(), deleteValues_.end());
- std::random_shuffle(writeValues_.begin(), writeValues_.end());
+ std::shuffle(readValues_.begin(), readValues_.end(), std::mt19937{});
+ std::shuffle(deleteValues_.begin(), deleteValues_.end(), std::mt19937{});
+ std::shuffle(writeValues_.begin(), writeValues_.end(), std::mt19937{});
}
~ConcurrentAccessData() {
FOR_EACH(lock, locks_) delete *lock;
}
- inline bool skipListFind(int idx, ValueType val) {
+ inline bool skipListFind(int /* idx */, ValueType val) {
return skipList_.contains(val);
}
- inline void skipListInsert(int idx, ValueType val) {
+ inline void skipListInsert(int /* idx */, ValueType val) {
skipList_.add(val);
}
- inline void skipListErase(int idx, ValueType val) {
+ inline void skipListErase(int /* idx */, ValueType val) {
skipList_.remove(val);
}
sets_[idx].erase(val);
}
- void runSkipList(int id, int iters) {
+ void runSkipList(int id, size_t iters) {
int sum = 0;
- for (int i = 0; i < iters; ++i) {
+ for (size_t i = 0; i < iters; ++i) {
sum += accessSkipList(id, i);
}
// VLOG(20) << sum;
}
- void runSet(int id, int iters) {
+ void runSet(size_t id, size_t iters) {
int sum = 0;
- for (int i = 0; i < iters; ++i) {
+ for (size_t i = 0; i < iters; ++i) {
sum += accessSet(id, i);
}
// VLOG(20) << sum;
}
- bool accessSkipList(int64_t id, int t) {
+ bool accessSkipList(int64_t id, size_t t) {
if (t > readValues_.size()) {
t = t % readValues_.size();
}
} else {
skipListInsert(0, writeValues_[t]);
}
- return 0;
+ return false;
default:
return skipListFind(0, readValues_[t]);
}
}
- bool accessSet(int64_t id, int t) {
+ bool accessSet(int64_t id, size_t t) {
if (t > readValues_.size()) {
t = t % readValues_.size();
}
} else {
setInsert(idx, writeValues_[t]);
}
- return 0;
+ return false;
default:
return setFind(idx, readValues_[t]);
}
static ConcurrentAccessData *mayInitTestData(int size) {
auto it = g_data.find(size);
if (it == g_data.end()) {
- auto ptr = std::shared_ptr<ConcurrentAccessData>(
- new ConcurrentAccessData(size));
+ auto ptr = std::make_shared<ConcurrentAccessData>(size);
g_data[size] = ptr;
return ptr.get();
}
BENCHMARK_PARAM(BM_ContentionCSL, 1048576);
BENCHMARK_DRAW_LINE();
-}
+} // namespace
int main(int argc, char** argv) {
google::InitGoogleLogging(argv[0]);
- google::ParseCommandLineFlags(&argc, &argv, true);
+ gflags::ParseCommandLineFlags(&argc, &argv, true);
initData();
runBenchmarks();