2 * Copyright 2017 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <folly/fibers/FiberManager.h>
18 #include <folly/fibers/FiberManagerMap.h>
22 #include <folly/Benchmark.h>
23 #include <folly/fibers/SimpleLoopController.h>
24 #include <folly/init/Init.h>
25 #include <folly/io/async/EventBase.h>
27 using namespace folly::fibers;
29 static size_t sNumAwaits;
31 void runBenchmark(size_t numAwaits, size_t toSend) {
32 sNumAwaits = numAwaits;
34 FiberManager fiberManager(folly::make_unique<SimpleLoopController>());
35 auto& loopController =
36 dynamic_cast<SimpleLoopController&>(fiberManager.loopController());
38 std::queue<Promise<int>> pendingRequests;
39 static const size_t maxOutstanding = 5;
41 auto loop = [&fiberManager, &loopController, &pendingRequests, &toSend]() {
42 if (pendingRequests.size() == maxOutstanding || toSend == 0) {
43 if (pendingRequests.empty()) {
46 pendingRequests.front().setValue(0);
47 pendingRequests.pop();
49 fiberManager.addTask([&pendingRequests]() {
50 for (size_t i = 0; i < sNumAwaits; ++i) {
51 auto result = await([&pendingRequests](Promise<int> promise) {
52 pendingRequests.push(std::move(promise));
59 loopController.stop();
64 loopController.loop(std::move(loop));
67 BENCHMARK(FiberManagerBasicOneAwait, iters) {
68 runBenchmark(1, iters);
71 BENCHMARK(FiberManagerBasicFiveAwaits, iters) {
72 runBenchmark(5, iters);
75 BENCHMARK(FiberManagerCreateDestroy, iters) {
76 for (size_t i = 0; i < iters; ++i) {
78 auto& fm = folly::fibers::getFiberManager(evb);
84 BENCHMARK(FiberManagerAllocateDeallocatePattern, iters) {
85 static const size_t kNumAllocations = 10000;
87 FiberManager::Options opts;
88 opts.maxFibersPoolSize = 0;
90 FiberManager fiberManager(folly::make_unique<SimpleLoopController>(), opts);
92 for (size_t iter = 0; iter < iters; ++iter) {
93 DCHECK_EQ(0, fiberManager.fibersPoolSize());
97 for (size_t i = 0; i < kNumAllocations; ++i) {
98 fiberManager.addTask([&fibersRun] { ++fibersRun; });
99 fiberManager.loopUntilNoReady();
102 DCHECK_EQ(10000, fibersRun);
103 DCHECK_EQ(0, fiberManager.fibersPoolSize());
107 BENCHMARK(FiberManagerAllocateLargeChunk, iters) {
108 static const size_t kNumAllocations = 10000;
110 FiberManager::Options opts;
111 opts.maxFibersPoolSize = 0;
113 FiberManager fiberManager(folly::make_unique<SimpleLoopController>(), opts);
115 for (size_t iter = 0; iter < iters; ++iter) {
116 DCHECK_EQ(0, fiberManager.fibersPoolSize());
118 size_t fibersRun = 0;
120 for (size_t i = 0; i < kNumAllocations; ++i) {
121 fiberManager.addTask([&fibersRun] { ++fibersRun; });
124 fiberManager.loopUntilNoReady();
126 DCHECK_EQ(10000, fibersRun);
127 DCHECK_EQ(0, fiberManager.fibersPoolSize());
131 int main(int argc, char** argv) {
132 folly::init(&argc, &argv, true);
134 folly::runBenchmarks();