1 /*
2  * Copyright (c) Facebook, Inc. and its affiliates.
3  *
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
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 
17 #include <folly/Benchmark.h>
18 #include <folly/io/async/test/ZeroCopy.h>
19 #include <folly/portability/GFlags.h>
20 
21 using namespace folly;
22 namespace {
runClient(const std::string & host,uint16_t port,int numLoops,bool zeroCopy,size_t bufferSize)23 void runClient(
24     const std::string& host,
25     uint16_t port,
26     int numLoops,
27     bool zeroCopy,
28     size_t bufferSize) {
29   LOG(INFO) << "Running client. host = " << host << " port = " << port
30             << " numLoops = " << numLoops << " zeroCopy = " << zeroCopy
31             << " bufferSize = " << bufferSize;
32 
33   size_t counter = 1;
34   EventBase evb;
35   std::unique_ptr<ZeroCopyTestAsyncSocket> client(new ZeroCopyTestAsyncSocket(
36       &counter, &evb, numLoops, bufferSize, zeroCopy));
37   SocketAddress addr(host, port);
38   evb.runInEventBaseThread([&]() { client->connect(addr); });
39 
40   evb.loopForever();
41 }
42 
runServer(uint16_t port,int numLoops,bool zeroCopy,size_t bufferSize)43 void runServer(uint16_t port, int numLoops, bool zeroCopy, size_t bufferSize) {
44   LOG(INFO) << "Running server. port = " << port << " numLoops = " << numLoops
45             << " zeroCopy = " << zeroCopy << " bufferSize = " << bufferSize;
46 
47   EventBase evb;
48   folly::AsyncServerSocket::UniquePtr listenSock(
49       new folly::AsyncServerSocket(&evb));
50   ZeroCopyTestServer server(&evb, numLoops, bufferSize, zeroCopy);
51 
52   server.addCallbackToServerSocket(*listenSock);
53 
54   evb.runInEventBaseThread([&]() {
55     listenSock->bind(port);
56     listenSock->setZeroCopy(zeroCopy);
57     listenSock->listen(10);
58     listenSock->startAccepting();
59   });
60 
61   evb.loopForever();
62 }
63 } // namespace
64 
65 static auto constexpr kMaxLoops = 20000;
66 
zeroCopyOn(unsigned iters,size_t bufferSize,size_t numClients=1)67 void zeroCopyOn(unsigned iters, size_t bufferSize, size_t numClients = 1) {
68   BenchmarkSuspender susp;
69   ZeroCopyTest test(numClients, iters, true, bufferSize);
70   susp.dismiss();
71   test.run();
72   susp.rehire();
73 }
74 
zeroCopyOff(unsigned iters,size_t bufferSize,size_t numClients=1)75 void zeroCopyOff(unsigned iters, size_t bufferSize, size_t numClients = 1) {
76   BenchmarkSuspender susp;
77   ZeroCopyTest test(numClients, iters, false, bufferSize);
78   susp.dismiss();
79   test.run();
80   susp.rehire();
81 }
82 
83 static auto constexpr kNumClients = 40;
84 
zeroCopyOnMulti(unsigned iters,size_t bufferSize)85 void zeroCopyOnMulti(unsigned iters, size_t bufferSize) {
86   zeroCopyOn(iters, bufferSize, kNumClients);
87 }
88 
zeroCopyOffMulti(unsigned iters,size_t bufferSize)89 void zeroCopyOffMulti(unsigned iters, size_t bufferSize) {
90   zeroCopyOff(iters, bufferSize, kNumClients);
91 }
92 
93 BENCHMARK_PARAM(zeroCopyOn, 4096)
94 BENCHMARK_PARAM(zeroCopyOff, 4096)
95 BENCHMARK_DRAW_LINE();
96 BENCHMARK_PARAM(zeroCopyOn, 8192)
97 BENCHMARK_PARAM(zeroCopyOff, 8192)
98 BENCHMARK_DRAW_LINE();
99 BENCHMARK_PARAM(zeroCopyOn, 16384)
100 BENCHMARK_PARAM(zeroCopyOff, 16384)
101 BENCHMARK_DRAW_LINE();
102 BENCHMARK_PARAM(zeroCopyOn, 32768)
103 BENCHMARK_PARAM(zeroCopyOff, 32768)
104 BENCHMARK_DRAW_LINE();
105 BENCHMARK_PARAM(zeroCopyOn, 65536)
106 BENCHMARK_PARAM(zeroCopyOff, 65536)
107 BENCHMARK_DRAW_LINE();
108 BENCHMARK_PARAM(zeroCopyOn, 131072)
109 BENCHMARK_PARAM(zeroCopyOff, 131072)
110 BENCHMARK_DRAW_LINE();
111 BENCHMARK_PARAM(zeroCopyOn, 262144)
112 BENCHMARK_PARAM(zeroCopyOff, 262144)
113 BENCHMARK_DRAW_LINE();
114 BENCHMARK_PARAM(zeroCopyOn, 524288)
115 BENCHMARK_PARAM(zeroCopyOff, 524288)
116 BENCHMARK_DRAW_LINE();
117 BENCHMARK_PARAM(zeroCopyOn, 1048576)
118 BENCHMARK_PARAM(zeroCopyOff, 1048576)
119 BENCHMARK_DRAW_LINE();
120 BENCHMARK_PARAM(zeroCopyOnMulti, 1048576)
121 BENCHMARK_PARAM(zeroCopyOffMulti, 1048576)
122 BENCHMARK_DRAW_LINE();
123 
124 DEFINE_bool(client, false, "client mode");
125 DEFINE_bool(server, false, "server mode");
126 DEFINE_bool(zeroCopy, false, "use zerocopy");
127 DEFINE_int32(numLoops, kMaxLoops, "number of loops");
128 DEFINE_int32(bufferSize, 524288, "buffer size");
129 DEFINE_int32(port, 33130, "port");
130 DEFINE_string(host, "::1", "host");
131 
main(int argc,char ** argv)132 int main(int argc, char** argv) {
133   gflags::ParseCommandLineFlags(&argc, &argv, true);
134 
135   if (FLAGS_client) {
136     runClient(
137         FLAGS_host,
138         FLAGS_port,
139         FLAGS_numLoops,
140         FLAGS_zeroCopy,
141         FLAGS_bufferSize);
142   } else if (FLAGS_server) {
143     runServer(FLAGS_port, FLAGS_numLoops, FLAGS_zeroCopy, FLAGS_bufferSize);
144   } else {
145     runBenchmarks();
146   }
147 }
148