25 #include <glog/logging.h> 35 using namespace folly;
37 typedef unsigned int ThroughputType;
40 typedef unsigned long LatencyType;
43 template <
class QueueType>
44 struct ThroughputTest {
45 explicit ThroughputTest(
size_t size,
int iters,
int cpu0,
int cpu1)
46 : queue_(size), done_(false), iters_(iters), cpu0_(cpu0), cpu1_(cpu1) {}
52 CPU_SET(cpu0_, &cpuset);
53 pthread_setaffinity_np(pthread_self(),
sizeof(cpu_set_t), &cpuset);
55 for (
int i = 0;
i < iters_; ++
i) {
56 ThroughputType item =
i;
57 while (!queue_.write((ThroughputType)item)) {
66 CPU_SET(cpu1_, &cpuset);
67 pthread_setaffinity_np(pthread_self(),
sizeof(cpu_set_t), &cpuset);
69 for (
int i = 0;
i < iters_; ++
i) {
70 ThroughputType item = 0;
71 while (!queue_.read(item)) {
78 std::atomic<bool> done_;
84 template <
class QueueType>
86 explicit LatencyTest(
size_t size,
int iters,
int cpu0,
int cpu1)
97 if (end.tv_sec == start.tv_sec) {
98 assert(end.tv_nsec >= start.tv_nsec);
99 return uint64_t(end.tv_nsec - start.tv_nsec);
101 assert(end.tv_sec > start.tv_sec);
104 return diff * 1000000000ULL + end.tv_nsec - start.tv_nsec;
107 void computeTimeCost() {
110 for (
int i = 0;
i < iters_; ++
i) {
115 time_cost_ = 2 * timespecDiff(end, start) / iters_;
122 CPU_SET(cpu0_, &cpuset);
123 pthread_setaffinity_np(pthread_self(),
sizeof(cpu_set_t), &cpuset);
125 for (
int i = 0;
i < iters_; ++
i) {
126 timespec sleeptime, sleepstart;
130 }
while (timespecDiff(sleeptime, sleepstart) < 1000000);
134 while (!queue_.write((LatencyType)tv.tv_nsec)) {
143 CPU_SET(cpu1_, &cpuset);
144 pthread_setaffinity_np(pthread_self(),
sizeof(cpu_set_t), &cpuset);
146 for (
int i = 0;
i < iters_; ++
i) {
147 unsigned long enqueue_nsec;
148 while (!queue_.read(enqueue_nsec)) {
153 int diff = tv.tv_nsec - enqueue_nsec - time_cost_;
160 for (bucket = 0; bucket <= 30 && (1 << bucket) <= diff; ++bucket) {
162 hist_.addValue(bucket - 1);
166 void printHistogram() {
167 hist_.toTSV(std::cout);
171 std::atomic<bool> done_;
179 void BM_ProducerConsumer(
int iters,
int size) {
182 ThroughputTest<ThroughputQueueType>*
test =
183 new ThroughputTest<ThroughputQueueType>(
size, iters, -1, -1);
186 std::thread producer([test] { test->producer(); });
187 std::thread consumer([test] { test->consumer(); });
195 void BM_ProducerConsumerAffinity(
int iters,
int size) {
198 ThroughputTest<ThroughputQueueType>* test =
199 new ThroughputTest<ThroughputQueueType>(
size, iters, 0, 1);
202 std::thread producer([test] { test->producer(); });
203 std::thread consumer([test] { test->consumer(); });
211 void BM_ProducerConsumerLatency(
int ,
int size) {
214 LatencyTest<LatencyQueueType>* test =
215 new LatencyTest<LatencyQueueType>(
size, 100000, 0, 1);
218 std::thread producer([test] { test->producer(); });
219 std::thread consumer([test] { test->consumer(); });
224 test->printHistogram();
237 google::InitGoogleLogging(argv[0]);
238 gflags::ParseCommandLineFlags(&argc, &argv,
true);
int(* clock_gettime)(clockid_t, timespec *ts)
static uint64_t test(std::string name, bool fc_, bool dedicated_, bool tc_, bool syncops_, uint64_t base)
—— Concurrent Priority Queue Implementation ——
constexpr auto size(C const &c) -> decltype(c.size())
auto end(TestAdlIterable &instance)
int main(int argc, char **argv)
#define BENCHMARK_PARAM(name, param)
uint64_t diff(uint64_t a, uint64_t b)
auto doNotOptimizeAway(const T &datum) -> typename std::enable_if< !detail::DoNotOptimizeAwayNeedsIndirect< T >::value >::type