X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=tests%2Fbinder%2Fbenchmarks%2FbinderAddInts.cpp;h=7ac53601940786fd22aa3a1c2c9508a23e71e087;hb=187816e5793ad177f6f70fe6270baf1475d74149;hp=69e47ff915e923e3247e82458fc1b454b5b36a40;hpb=4697d834a79f3f997443a1d4625655dd0303464c;p=android-x86%2Fsystem-extras.git diff --git a/tests/binder/benchmarks/binderAddInts.cpp b/tests/binder/benchmarks/binderAddInts.cpp index 69e47ff9..7ac53601 100644 --- a/tests/binder/benchmarks/binderAddInts.cpp +++ b/tests/binder/benchmarks/binderAddInts.cpp @@ -16,21 +16,8 @@ */ /* - * Binder add integers benchmark + * Binder add integers benchmark (Using google-benchmark library) * - * Measures the rate at which a short binder IPC operation can be - * performed. The operation consists of the client sending a parcel - * that contains two integers. For each parcel that the server - * receives, it adds the two integers and sends the sum back to - * the client. - * - * This benchmark supports the following command-line options: - * - * -c cpu - bind client to specified cpu (default: unbound) - * -s cpu - bind server to specified cpu (default: unbound) - * -n num - perform IPC operation num times (default: 1000) - * -d time - delay specified amount of seconds after each - * IPC operation. (default 1e-3) */ #include @@ -49,6 +36,9 @@ #include #include #include + +#include + #include #include @@ -62,13 +52,11 @@ String16 serviceName("test.binderAddInts"); struct options { int serverCPU; int clientCPU; - unsigned int iterations; float iterDelay; // End of iteration delay in seconds } options = { // Set defaults unbound, // Server CPU unbound, // Client CPU - 1000, // Iterations - 1e-3, // End of iteration delay + 0.0, // End of iteration delay }; class AddIntsService : public BBinder @@ -89,152 +77,13 @@ class AddIntsService : public BBinder int cpu_; }; -struct Duration { - double value; - friend std::ostream& operator<<(std::ostream& stream, const Duration& d) { - static const char *SUFFIXES[] = {"s", "ms", "us", "ns"}; - size_t suffix = 0; - double temp = d.value; - while (temp < .1 && suffix < 3) { - temp *= 1000; - suffix++; - } - stream << temp << SUFFIXES[suffix]; - return stream; - } -}; - // File scope function prototypes static bool server(void); -static void client(void); +static void BM_addInts(benchmark::State& state); static void bindCPU(unsigned int cpu); static ostream &operator<<(ostream &stream, const String16& str); static ostream &operator<<(ostream &stream, const cpu_set_t& set); -int main(int argc, char *argv[]) -{ - int rv; - - // Determine CPUs available for use. - // This testcase limits its self to using CPUs that were - // available at the start of the benchmark. - cpu_set_t availCPUs; - if ((rv = sched_getaffinity(0, sizeof(availCPUs), &availCPUs)) != 0) { - cerr << "sched_getaffinity failure, rv: " << rv - << " errno: " << errno << endl; - exit(1); - } - - // Parse command line arguments - int opt; - while ((opt = getopt(argc, argv, "s:c:n:d:?")) != -1) { - char *chptr; // character pointer for command-line parsing - - switch (opt) { - case 'c': // client CPU - case 's': { // server CPU - // Parse the CPU number - int cpu = strtoul(optarg, &chptr, 10); - if (*chptr != '\0') { - cerr << "Invalid cpu specified for -" << (char) opt - << " option of: " << optarg << endl; - exit(2); - } - - // Is the CPU available? - if (!CPU_ISSET(cpu, &availCPUs)) { - cerr << "CPU " << optarg << " not currently available" << endl; - cerr << " Available CPUs: " << availCPUs << endl; - exit(3); - } - - // Record the choice - *((opt == 'c') ? &options.clientCPU : &options.serverCPU) = cpu; - break; - } - - case 'n': // iterations - options.iterations = strtoul(optarg, &chptr, 10); - if (*chptr != '\0') { - cerr << "Invalid iterations specified of: " << optarg << endl; - exit(4); - } - if (options.iterations < 1) { - cerr << "Less than 1 iteration specified by: " - << optarg << endl; - exit(5); - } - break; - - case 'd': // Delay between each iteration - options.iterDelay = strtod(optarg, &chptr); - if ((*chptr != '\0') || (options.iterDelay < 0.0)) { - cerr << "Invalid delay specified of: " << optarg << endl; - exit(6); - } - break; - - case '?': - default: - cerr << basename(argv[0]) << " [options]" << endl; - cerr << " options:" << endl; - cerr << " -s cpu - server CPU number" << endl; - cerr << " -c cpu - client CPU number" << endl; - cerr << " -n num - iterations" << endl; - cerr << " -d time - delay after operation in seconds" << endl; - exit(((optopt == 0) || (optopt == '?')) ? 0 : 7); - } - } - - // Display selected options - cout << "serverCPU: "; - if (options.serverCPU == unbound) { - cout << " unbound"; - } else { - cout << options.serverCPU; - } - cout << endl; - cout << "clientCPU: "; - if (options.clientCPU == unbound) { - cout << " unbound"; - } else { - cout << options.clientCPU; - } - cout << endl; - cout << "iterations: " << options.iterations << endl; - cout << "iterDelay: " << options.iterDelay << endl; - - // Fork client, use this process as server - fflush(stdout); - switch (pid_t pid = fork()) { - case 0: // Child - client(); - return 0; - - default: // Parent - if (!server()) { break; } - - // Wait for all children to end - do { - int stat; - rv = wait(&stat); - if ((rv == -1) && (errno == ECHILD)) { break; } - if (rv == -1) { - cerr << "wait failed, rv: " << rv << " errno: " - << errno << endl; - perror(NULL); - exit(8); - } - } while (1); - return 0; - - case -1: // Error - exit(9); - } - - return 0; -} - static bool server(void) { int rv; @@ -254,12 +103,10 @@ static bool server(void) return true; } -static void client(void) +static void BM_addInts(benchmark::State& state) { int rv; sp sm = defaultServiceManager(); - double min = FLT_MAX, max = 0.0, total = 0.0; // Time in seconds for all - // the IPC calls. // If needed bind to client CPU if (options.clientCPU != unbound) { bindCPU(options.clientCPU); } @@ -278,38 +125,31 @@ static void client(void) return; } - // Perform the IPC operations - for (unsigned int iter = 0; iter < options.iterations; iter++) { + unsigned int iter = 0; + // Perform the IPC operations in the benchmark + while (state.KeepRunning()) { Parcel send, reply; // Create parcel to be sent. Will use the iteration cound // and the iteration count + 3 as the two integer values // to be sent. + state.PauseTiming(); int val1 = iter; int val2 = iter + 3; int expected = val1 + val2; // Expect to get the sum back send.writeInt32(val1); send.writeInt32(val2); - + state.ResumeTiming(); // Send the parcel, while timing how long it takes for // the answer to return. - struct timespec start; - clock_gettime(CLOCK_MONOTONIC, &start); if ((rv = binder->transact(AddIntsService::ADD_INTS, send, &reply)) != 0) { cerr << "binder->transact failed, rv: " << rv << " errno: " << errno << endl; exit(10); } - struct timespec current; - clock_gettime(CLOCK_MONOTONIC, ¤t); - - // Calculate how long this operation took and update the stats - struct timespec deltaTimespec = tsDelta(&start, ¤t); - double delta = ts2double(&deltaTimespec); - min = (delta < min) ? delta : min; - max = (delta > max) ? delta : max; - total += delta; + + state.PauseTiming(); int result = reply.readInt32(); if (result != (int) (iter + iter + 3)) { cerr << "Unexpected result for iteration " << iter << endl; @@ -318,15 +158,11 @@ static void client(void) } if (options.iterDelay > 0.0) { testDelaySpin(options.iterDelay); } + state.ResumeTiming(); } - - // Display the results - cout << fixed << setprecision(2) - << "Time per iteration min: " << Duration{min} - << " avg: " << Duration{total / options.iterations} - << " max: " << Duration{max} - << endl; } +BENCHMARK(BM_addInts); + AddIntsService::AddIntsService(int cpu): cpu_(cpu) { if (cpu != unbound) { bindCPU(cpu); } @@ -334,7 +170,7 @@ AddIntsService::AddIntsService(int cpu): cpu_(cpu) { // Server function that handles parcels received from the client status_t AddIntsService::onTransact(uint32_t code, const Parcel &data, - Parcel* reply, uint32_t flags) { + Parcel* reply, uint32_t /* flags */) { int val1, val2; status_t rv(0); int cpu; @@ -406,3 +242,92 @@ static ostream &operator<<(ostream &stream, const cpu_set_t& set) return stream; } + +int main(int argc, char *argv[]) +{ + int rv; + ::benchmark::Initialize(&argc, argv); + // Determine CPUs available for use. + // This testcase limits its self to using CPUs that were + // available at the start of the benchmark. + cpu_set_t availCPUs; + if ((rv = sched_getaffinity(0, sizeof(availCPUs), &availCPUs)) != 0) { + cerr << "sched_getaffinity failure, rv: " << rv + << " errno: " << errno << endl; + exit(1); + } + + // Parse command line arguments + int opt; + while ((opt = getopt(argc, argv, "s:c:d:?")) != -1) { + char *chptr; // character pointer for command-line parsing + + switch (opt) { + case 'c': // client CPU + case 's': { // server CPU + // Parse the CPU number + int cpu = strtoul(optarg, &chptr, 10); + if (*chptr != '\0') { + cerr << "Invalid cpu specified for -" << (char) opt + << " option of: " << optarg << endl; + exit(2); + } + + // Is the CPU available? + if (!CPU_ISSET(cpu, &availCPUs)) { + cerr << "CPU " << optarg << " not currently available" << endl; + cerr << " Available CPUs: " << availCPUs << endl; + exit(3); + } + + // Record the choice + *((opt == 'c') ? &options.clientCPU : &options.serverCPU) = cpu; + break; + } + + case 'd': // delay between each iteration + options.iterDelay = strtod(optarg, &chptr); + if ((*chptr != '\0') || (options.iterDelay < 0.0)) { + cerr << "Invalid delay specified of: " << optarg << endl; + exit(6); + } + break; + + case '?': + default: + cerr << basename(argv[0]) << " [options]" << endl; + cerr << " options:" << endl; + cerr << " -s cpu - server CPU number" << endl; + cerr << " -c cpu - client CPU number" << endl; + cerr << " -d time - delay after operation in seconds" << endl; + exit(((optopt == 0) || (optopt == '?')) ? 0 : 7); + } + } + + fflush(stdout); + switch (pid_t pid = fork()) { + case 0: // Child + ::benchmark::RunSpecifiedBenchmarks(); + return 0; + + default: // Parent + if (!server()) { break; } + + // Wait for all children to end + do { + int stat; + rv = wait(&stat); + if ((rv == -1) && (errno == ECHILD)) { break; } + if (rv == -1) { + cerr << "wait failed, rv: " << rv << " errno: " + << errno << endl; + perror(NULL); + exit(8); + } + } while (1); + return 0; + + case -1: // Error + exit(9); + } +}