From 1ebdc70d175bcc1320a4b42606aafbd54c08624c Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Wed, 28 Jul 2021 18:46:15 -0700 Subject: binderRpcBenchmark: device tests kernel as ctrl Host still tests RPC binder only since kernel binder is only on Android (by convention!). On local cuttlefish: Tests suffixes: \0 is KERNEL \1 is RPC ... --------------------------------------------------------------- Benchmark Time CPU Iterations --------------------------------------------------------------- BM_pingTransaction/0 28448 ns 18366 ns 36940 BM_pingTransaction/1 39291 ns 26773 ns 25295 BM_repeatString/0 184458 ns 96268 ns 7263 BM_repeatString/1 206385 ns 116369 ns 5947 BM_repeatBinder/0 50475 ns 43567 ns 15896 BM_repeatBinder/1 50722 ns 44386 ns 15857 So the takeaway is that RPC binder has some overhead for very small transactions. Future considerations: - make the RPC calls across processes instead of across threads - see how scheduler optimizations affect this Fixes: 194903439 Test: binderRpcBenchmark Change-Id: Ib7b680091979d142bca4716d62cc579f90bade0f --- libs/binder/tests/binderRpcBenchmark.cpp | 76 +++++++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 12 deletions(-) (limited to 'libs') diff --git a/libs/binder/tests/binderRpcBenchmark.cpp b/libs/binder/tests/binderRpcBenchmark.cpp index a457e67735..26a0b90977 100644 --- a/libs/binder/tests/binderRpcBenchmark.cpp +++ b/libs/binder/tests/binderRpcBenchmark.cpp @@ -18,21 +18,30 @@ #include #include #include +#include +#include +#include #include #include #include +#include #include #include using android::BBinder; +using android::defaultServiceManager; using android::IBinder; using android::interface_cast; +using android::IPCThreadState; +using android::IServiceManager; using android::OK; +using android::ProcessState; using android::RpcServer; using android::RpcSession; using android::sp; +using android::String16; using android::binder::Status; class MyBinderRpcBenchmark : public BnBinderRpcBenchmark { @@ -46,28 +55,51 @@ class MyBinderRpcBenchmark : public BnBinderRpcBenchmark { } }; -static sp gSession = RpcSession::make(); +enum Transport { + KERNEL, + RPC, +}; -void BM_getRootObject(benchmark::State& state) { - while (state.KeepRunning()) { - CHECK(gSession->getRootObject() != nullptr); +static void EachTransport(benchmark::internal::Benchmark* b) { +#ifdef __BIONIC__ + b->Args({Transport::KERNEL}); +#endif + b->Args({Transport::RPC}); +} + +static sp gSession = RpcSession::make(); +#ifdef __BIONIC__ +static const String16 kKernelBinderInstance = String16(u"binderRpcBenchmark-control"); +static sp gKernelBinder; +#endif + +static sp getBinderForOptions(benchmark::State& state) { + Transport transport = static_cast(state.range(0)); + switch (transport) { +#ifdef __BIONIC__ + case KERNEL: + return gKernelBinder; +#endif + case RPC: + return gSession->getRootObject(); + default: + LOG(FATAL) << "Unknown transport value: " << transport; + return nullptr; } } -BENCHMARK(BM_getRootObject); void BM_pingTransaction(benchmark::State& state) { - sp binder = gSession->getRootObject(); - CHECK(binder != nullptr); + sp binder = getBinderForOptions(state); while (state.KeepRunning()) { CHECK_EQ(OK, binder->pingBinder()); } } -BENCHMARK(BM_pingTransaction); +BENCHMARK(BM_pingTransaction)->Apply(EachTransport); void BM_repeatString(benchmark::State& state) { - sp binder = gSession->getRootObject(); - CHECK(binder != nullptr); + sp binder = getBinderForOptions(state); + sp iface = interface_cast(binder); CHECK(iface != nullptr); @@ -92,7 +124,7 @@ void BM_repeatString(benchmark::State& state) { CHECK(ret.isOk()) << ret; } } -BENCHMARK(BM_repeatString); +BENCHMARK(BM_repeatString)->Apply(EachTransport); void BM_repeatBinder(benchmark::State& state) { sp binder = gSession->getRootObject(); @@ -109,7 +141,7 @@ void BM_repeatBinder(benchmark::State& state) { CHECK(ret.isOk()) << ret; } } -BENCHMARK(BM_repeatBinder); +BENCHMARK(BM_repeatBinder)->Apply(EachTransport); int main(int argc, char** argv) { ::benchmark::Initialize(&argc, argv); @@ -118,6 +150,26 @@ int main(int argc, char** argv) { std::string addr = std::string(getenv("TMPDIR") ?: "/tmp") + "/binderRpcBenchmark"; (void)unlink(addr.c_str()); + std::cerr << "Tests suffixes:" << std::endl; + std::cerr << "\t\\" << Transport::KERNEL << " is KERNEL" << std::endl; + std::cerr << "\t\\" << Transport::RPC << " is RPC" << std::endl; + +#ifdef __BIONIC__ + if (0 == fork()) { + prctl(PR_SET_PDEATHSIG, SIGHUP); // racey, okay + CHECK_EQ(OK, + defaultServiceManager()->addService(kKernelBinderInstance, + sp::make())); + IPCThreadState::self()->joinThreadPool(); + } + + ProcessState::self()->setThreadPoolMaxThreadCount(1); + ProcessState::self()->startThreadPool(); + + gKernelBinder = defaultServiceManager()->waitForService(kKernelBinderInstance); + CHECK_NE(nullptr, gKernelBinder.get()); +#endif + std::thread([addr]() { sp server = RpcServer::make(); server->setRootObject(sp::make()); -- cgit v1.2.3-59-g8ed1b