xref: /aosp_15_r20/system/libhwbinder/vts/performance/PerfTest.cpp (revision 77b80299c8bdfeca3ae6d0ce27ae1ad3db289be3)
1*77b80299SAndroid Build Coastguard Worker /*
2*77b80299SAndroid Build Coastguard Worker  * Copyright (C) 2016 The Android Open Source Project
3*77b80299SAndroid Build Coastguard Worker  *
4*77b80299SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*77b80299SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*77b80299SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*77b80299SAndroid Build Coastguard Worker  *
8*77b80299SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*77b80299SAndroid Build Coastguard Worker  *
10*77b80299SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*77b80299SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*77b80299SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*77b80299SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*77b80299SAndroid Build Coastguard Worker  * limitations under the License.
15*77b80299SAndroid Build Coastguard Worker  */
16*77b80299SAndroid Build Coastguard Worker 
17*77b80299SAndroid Build Coastguard Worker #include "PerfTest.h"
18*77b80299SAndroid Build Coastguard Worker #include <fstream>
19*77b80299SAndroid Build Coastguard Worker #include <iomanip>
20*77b80299SAndroid Build Coastguard Worker #include <iostream>
21*77b80299SAndroid Build Coastguard Worker #include <string>
22*77b80299SAndroid Build Coastguard Worker 
23*77b80299SAndroid Build Coastguard Worker #ifdef ASSERT
24*77b80299SAndroid Build Coastguard Worker #undef ASSERT
25*77b80299SAndroid Build Coastguard Worker #endif
26*77b80299SAndroid Build Coastguard Worker #define ASSERT(cond)                                                                              \
27*77b80299SAndroid Build Coastguard Worker     do {                                                                                          \
28*77b80299SAndroid Build Coastguard Worker         if (!(cond)) {                                                                            \
29*77b80299SAndroid Build Coastguard Worker             cerr << __func__ << ":" << __LINE__ << " condition:" << #cond << " failed\n" << endl; \
30*77b80299SAndroid Build Coastguard Worker             exit(EXIT_FAILURE);                                                                   \
31*77b80299SAndroid Build Coastguard Worker         }                                                                                         \
32*77b80299SAndroid Build Coastguard Worker     } while (0)
33*77b80299SAndroid Build Coastguard Worker 
34*77b80299SAndroid Build Coastguard Worker // the ratio that the service is synced on the same cpu beyond
35*77b80299SAndroid Build Coastguard Worker // GOOD_SYNC_MIN is considered as good
36*77b80299SAndroid Build Coastguard Worker #define GOOD_SYNC_MIN (0.6)
37*77b80299SAndroid Build Coastguard Worker 
38*77b80299SAndroid Build Coastguard Worker // the precision used for cout to dump float
39*77b80299SAndroid Build Coastguard Worker #define DUMP_PRICISION 2
40*77b80299SAndroid Build Coastguard Worker 
41*77b80299SAndroid Build Coastguard Worker using std::cerr;
42*77b80299SAndroid Build Coastguard Worker using std::cout;
43*77b80299SAndroid Build Coastguard Worker using std::endl;
44*77b80299SAndroid Build Coastguard Worker using std::left;
45*77b80299SAndroid Build Coastguard Worker using std::ios;
46*77b80299SAndroid Build Coastguard Worker using std::min;
47*77b80299SAndroid Build Coastguard Worker using std::max;
48*77b80299SAndroid Build Coastguard Worker using std::to_string;
49*77b80299SAndroid Build Coastguard Worker using std::setprecision;
50*77b80299SAndroid Build Coastguard Worker using std::setw;
51*77b80299SAndroid Build Coastguard Worker using std::ofstream;
52*77b80299SAndroid Build Coastguard Worker using std::make_tuple;
53*77b80299SAndroid Build Coastguard Worker 
createPipePair()54*77b80299SAndroid Build Coastguard Worker tuple<Pipe, Pipe> Pipe::createPipePair() {
55*77b80299SAndroid Build Coastguard Worker     int a[2];
56*77b80299SAndroid Build Coastguard Worker     int b[2];
57*77b80299SAndroid Build Coastguard Worker 
58*77b80299SAndroid Build Coastguard Worker     int error1 = pipe(a);
59*77b80299SAndroid Build Coastguard Worker     int error2 = pipe(b);
60*77b80299SAndroid Build Coastguard Worker     ASSERT(error1 >= 0);
61*77b80299SAndroid Build Coastguard Worker     ASSERT(error2 >= 0);
62*77b80299SAndroid Build Coastguard Worker 
63*77b80299SAndroid Build Coastguard Worker     return make_tuple(Pipe(a[0], b[1]), Pipe(b[0], a[1]));
64*77b80299SAndroid Build Coastguard Worker }
65*77b80299SAndroid Build Coastguard Worker 
Pipe(Pipe && rval)66*77b80299SAndroid Build Coastguard Worker Pipe::Pipe(Pipe&& rval) noexcept {
67*77b80299SAndroid Build Coastguard Worker     fd_read_ = rval.fd_read_;
68*77b80299SAndroid Build Coastguard Worker     fd_write_ = rval.fd_write_;
69*77b80299SAndroid Build Coastguard Worker     rval.fd_read_ = 0;
70*77b80299SAndroid Build Coastguard Worker     rval.fd_write_ = 0;
71*77b80299SAndroid Build Coastguard Worker }
72*77b80299SAndroid Build Coastguard Worker 
~Pipe()73*77b80299SAndroid Build Coastguard Worker Pipe::~Pipe() {
74*77b80299SAndroid Build Coastguard Worker     if (fd_read_) {
75*77b80299SAndroid Build Coastguard Worker         close(fd_read_);
76*77b80299SAndroid Build Coastguard Worker     }
77*77b80299SAndroid Build Coastguard Worker     if (fd_write_) {
78*77b80299SAndroid Build Coastguard Worker         close(fd_write_);
79*77b80299SAndroid Build Coastguard Worker     }
80*77b80299SAndroid Build Coastguard Worker }
81*77b80299SAndroid Build Coastguard Worker 
combine(const Results & a,const Results & b)82*77b80299SAndroid Build Coastguard Worker Results Results::combine(const Results& a, const Results& b) {
83*77b80299SAndroid Build Coastguard Worker     Results ret;
84*77b80299SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kNumBuckets; i++) {
85*77b80299SAndroid Build Coastguard Worker         ret.buckets_[i] = a.buckets_[i] + b.buckets_[i];
86*77b80299SAndroid Build Coastguard Worker     }
87*77b80299SAndroid Build Coastguard Worker     ret.worst_ = max(a.worst_, b.worst_);
88*77b80299SAndroid Build Coastguard Worker     ret.best_ = min(a.best_, b.best_);
89*77b80299SAndroid Build Coastguard Worker     ret.transactions_ = a.transactions_ + b.transactions_;
90*77b80299SAndroid Build Coastguard Worker     ret.miss_ = a.miss_ + b.miss_;
91*77b80299SAndroid Build Coastguard Worker     ret.total_time_ = a.total_time_ + b.total_time_;
92*77b80299SAndroid Build Coastguard Worker     return ret;
93*77b80299SAndroid Build Coastguard Worker }
94*77b80299SAndroid Build Coastguard Worker 
traceStop()95*77b80299SAndroid Build Coastguard Worker static void traceStop() {
96*77b80299SAndroid Build Coastguard Worker     ofstream file;
97*77b80299SAndroid Build Coastguard Worker     file.open(TRACE_PATH "/tracing_on", ios::out | ios::trunc);
98*77b80299SAndroid Build Coastguard Worker     file << '0' << endl;
99*77b80299SAndroid Build Coastguard Worker     file.close();
100*77b80299SAndroid Build Coastguard Worker }
101*77b80299SAndroid Build Coastguard Worker 
addTime(uint64_t nano)102*77b80299SAndroid Build Coastguard Worker void Results::addTime(uint64_t nano) {
103*77b80299SAndroid Build Coastguard Worker     buckets_[min(nano, kMaxTimeBucket - 1) / kTimePerBucket] += 1;
104*77b80299SAndroid Build Coastguard Worker     best_ = min(nano, best_);
105*77b80299SAndroid Build Coastguard Worker     worst_ = max(nano, worst_);
106*77b80299SAndroid Build Coastguard Worker     if (raw_dump_) {
107*77b80299SAndroid Build Coastguard Worker         raw_data_->push_back(nano);
108*77b80299SAndroid Build Coastguard Worker     }
109*77b80299SAndroid Build Coastguard Worker     transactions_ += 1;
110*77b80299SAndroid Build Coastguard Worker     total_time_ += nano;
111*77b80299SAndroid Build Coastguard Worker     if (missDeadline(nano)) {
112*77b80299SAndroid Build Coastguard Worker         miss_++;
113*77b80299SAndroid Build Coastguard Worker         if (tracing_) {
114*77b80299SAndroid Build Coastguard Worker             // There might be multiple process pair running the test concurrently
115*77b80299SAndroid Build Coastguard Worker             // each may execute following statements and only the first one actually
116*77b80299SAndroid Build Coastguard Worker             // stop the trace and any traceStop() after then has no effect.
117*77b80299SAndroid Build Coastguard Worker             traceStop();
118*77b80299SAndroid Build Coastguard Worker             cerr << endl;
119*77b80299SAndroid Build Coastguard Worker             cerr << "deadline triggered: halt & stop trace" << endl;
120*77b80299SAndroid Build Coastguard Worker             cerr << "log:" TRACE_PATH "/trace" << endl;
121*77b80299SAndroid Build Coastguard Worker             cerr << endl;
122*77b80299SAndroid Build Coastguard Worker             exit(EXIT_FAILURE);
123*77b80299SAndroid Build Coastguard Worker         }
124*77b80299SAndroid Build Coastguard Worker     }
125*77b80299SAndroid Build Coastguard Worker }
126*77b80299SAndroid Build Coastguard Worker 
setupRawData()127*77b80299SAndroid Build Coastguard Worker void Results::setupRawData() {
128*77b80299SAndroid Build Coastguard Worker     raw_dump_ = true;
129*77b80299SAndroid Build Coastguard Worker     if (raw_data_ == nullptr) {
130*77b80299SAndroid Build Coastguard Worker         raw_data_ = new list<uint64_t>;
131*77b80299SAndroid Build Coastguard Worker     } else {
132*77b80299SAndroid Build Coastguard Worker         raw_data_->clear();
133*77b80299SAndroid Build Coastguard Worker     }
134*77b80299SAndroid Build Coastguard Worker }
135*77b80299SAndroid Build Coastguard Worker 
flushRawData()136*77b80299SAndroid Build Coastguard Worker void Results::flushRawData() {
137*77b80299SAndroid Build Coastguard Worker     if (raw_dump_) {
138*77b80299SAndroid Build Coastguard Worker         bool first = true;
139*77b80299SAndroid Build Coastguard Worker         cout << "[";
140*77b80299SAndroid Build Coastguard Worker         for (auto nano : *raw_data_) {
141*77b80299SAndroid Build Coastguard Worker             cout << (first ? "" : ",") << to_string(nano);
142*77b80299SAndroid Build Coastguard Worker             first = false;
143*77b80299SAndroid Build Coastguard Worker         }
144*77b80299SAndroid Build Coastguard Worker         cout << "]," << endl;
145*77b80299SAndroid Build Coastguard Worker         delete raw_data_;
146*77b80299SAndroid Build Coastguard Worker         raw_data_ = nullptr;
147*77b80299SAndroid Build Coastguard Worker     }
148*77b80299SAndroid Build Coastguard Worker }
149*77b80299SAndroid Build Coastguard Worker 
dump() const150*77b80299SAndroid Build Coastguard Worker void Results::dump() const {
151*77b80299SAndroid Build Coastguard Worker     double best = (double)best_ / 1.0E6;
152*77b80299SAndroid Build Coastguard Worker     double worst = (double)worst_ / 1.0E6;
153*77b80299SAndroid Build Coastguard Worker     double average = (double)total_time_ / transactions_ / 1.0E6;
154*77b80299SAndroid Build Coastguard Worker     int W = DUMP_PRICISION + 2;
155*77b80299SAndroid Build Coastguard Worker     cout << std::setprecision(DUMP_PRICISION) << "{ \"avg\":" << setw(W) << left << average
156*77b80299SAndroid Build Coastguard Worker          << ", \"wst\":" << setw(W) << left << worst << ", \"bst\":" << setw(W) << left << best
157*77b80299SAndroid Build Coastguard Worker          << ", \"miss\":" << left << miss_ << ", \"meetR\":" << setprecision(DUMP_PRICISION + 3)
158*77b80299SAndroid Build Coastguard Worker          << left << (1.0 - (double)miss_ / transactions_) << "}";
159*77b80299SAndroid Build Coastguard Worker }
160*77b80299SAndroid Build Coastguard Worker 
dumpDistribution() const161*77b80299SAndroid Build Coastguard Worker void Results::dumpDistribution() const {
162*77b80299SAndroid Build Coastguard Worker     uint64_t cur_total = 0;
163*77b80299SAndroid Build Coastguard Worker     cout << "{ ";
164*77b80299SAndroid Build Coastguard Worker     cout << std::setprecision(DUMP_PRICISION + 3);
165*77b80299SAndroid Build Coastguard Worker     for (uint32_t i = 0; i < kNumBuckets; i++) {
166*77b80299SAndroid Build Coastguard Worker         float cur_time = kTimePerBucketMS * i + 0.5f * kTimePerBucketMS;
167*77b80299SAndroid Build Coastguard Worker         float accumulation = cur_total + buckets_[i];
168*77b80299SAndroid Build Coastguard Worker         if ((cur_total < 0.5f * transactions_) && (accumulation >= 0.5f * transactions_)) {
169*77b80299SAndroid Build Coastguard Worker             cout << "\"p50\":" << cur_time << ", ";
170*77b80299SAndroid Build Coastguard Worker         }
171*77b80299SAndroid Build Coastguard Worker         if ((cur_total < 0.9f * transactions_) && (accumulation >= 0.9f * transactions_)) {
172*77b80299SAndroid Build Coastguard Worker             cout << "\"p90\":" << cur_time << ", ";
173*77b80299SAndroid Build Coastguard Worker         }
174*77b80299SAndroid Build Coastguard Worker         if ((cur_total < 0.95f * transactions_) && (accumulation >= 0.95f * transactions_)) {
175*77b80299SAndroid Build Coastguard Worker             cout << "\"p95\":" << cur_time << ", ";
176*77b80299SAndroid Build Coastguard Worker         }
177*77b80299SAndroid Build Coastguard Worker         if ((cur_total < 0.99f * transactions_) && (accumulation >= 0.99f * transactions_)) {
178*77b80299SAndroid Build Coastguard Worker             cout << "\"p99\": " << cur_time;
179*77b80299SAndroid Build Coastguard Worker         }
180*77b80299SAndroid Build Coastguard Worker         cur_total += buckets_[i];
181*77b80299SAndroid Build Coastguard Worker     }
182*77b80299SAndroid Build Coastguard Worker     cout << "}";
183*77b80299SAndroid Build Coastguard Worker }
184*77b80299SAndroid Build Coastguard Worker 
combine(const PResults & a,const PResults & b)185*77b80299SAndroid Build Coastguard Worker PResults PResults::combine(const PResults& a, const PResults& b) {
186*77b80299SAndroid Build Coastguard Worker     PResults ret;
187*77b80299SAndroid Build Coastguard Worker     ret.nNotInherent = a.nNotInherent + b.nNotInherent;
188*77b80299SAndroid Build Coastguard Worker     ret.nNotSync = a.nNotSync + b.nNotSync;
189*77b80299SAndroid Build Coastguard Worker     ret.other = Results::combine(a.other, b.other);
190*77b80299SAndroid Build Coastguard Worker     ret.fifo = Results::combine(a.fifo, b.fifo);
191*77b80299SAndroid Build Coastguard Worker     return ret;
192*77b80299SAndroid Build Coastguard Worker }
193*77b80299SAndroid Build Coastguard Worker 
dump() const194*77b80299SAndroid Build Coastguard Worker void PResults::dump() const {
195*77b80299SAndroid Build Coastguard Worker     int no_trans = other.getTransactions() + fifo.getTransactions();
196*77b80299SAndroid Build Coastguard Worker     double sync_ratio = (1.0 - (double)nNotSync / no_trans);
197*77b80299SAndroid Build Coastguard Worker     cout << "{\"SYNC\":\"" << ((sync_ratio > GOOD_SYNC_MIN) ? "GOOD" : "POOR") << "\","
198*77b80299SAndroid Build Coastguard Worker          << "\"S\":" << (no_trans - nNotSync) << ",\"I\":" << no_trans << ","
199*77b80299SAndroid Build Coastguard Worker          << "\"R\":" << sync_ratio << "," << endl;
200*77b80299SAndroid Build Coastguard Worker     cout << "  \"other_ms\":";
201*77b80299SAndroid Build Coastguard Worker     other.dump();
202*77b80299SAndroid Build Coastguard Worker     cout << "," << endl;
203*77b80299SAndroid Build Coastguard Worker     cout << "  \"fifo_ms\": ";
204*77b80299SAndroid Build Coastguard Worker     fifo.dump();
205*77b80299SAndroid Build Coastguard Worker     cout << "," << endl;
206*77b80299SAndroid Build Coastguard Worker     cout << "  \"otherdis\":";
207*77b80299SAndroid Build Coastguard Worker     other.dumpDistribution();
208*77b80299SAndroid Build Coastguard Worker     cout << "," << endl;
209*77b80299SAndroid Build Coastguard Worker     cout << "  \"fifodis\": ";
210*77b80299SAndroid Build Coastguard Worker     fifo.dumpDistribution();
211*77b80299SAndroid Build Coastguard Worker     cout << endl;
212*77b80299SAndroid Build Coastguard Worker     cout << "}," << endl;
213*77b80299SAndroid Build Coastguard Worker }
214