From 49f8682ffb17514a2d0b84ba091045e52763fcaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kjetil=20=C3=98rbekk?= Date: Thu, 7 Jun 2012 14:40:40 +0200 Subject: Add benchmark activity for Experiment 2. --- .../android/benchmark/Experiment2Activity.java | 223 +++++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 same-android/src/main/java/com/orbekk/same/android/benchmark/Experiment2Activity.java diff --git a/same-android/src/main/java/com/orbekk/same/android/benchmark/Experiment2Activity.java b/same-android/src/main/java/com/orbekk/same/android/benchmark/Experiment2Activity.java new file mode 100644 index 0000000..2c60d9a --- /dev/null +++ b/same-android/src/main/java/com/orbekk/same/android/benchmark/Experiment2Activity.java @@ -0,0 +1,223 @@ +/** + * Copyright 2012 Kjetil Ørbekk + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.orbekk.same.android.benchmark; + +import java.io.IOException; +import java.net.UnknownHostException; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import android.app.Activity; +import android.os.Bundle; +import android.widget.Toast; + +import com.google.protobuf.RpcCallback; +import com.orbekk.protobuf.Rpc; +import com.orbekk.protobuf.RpcChannel; +import com.orbekk.same.Services; +import com.orbekk.same.Types; +import com.orbekk.same.Variable; +import com.orbekk.same.Variable.OnChangeListener; +import com.orbekk.same.VariableUpdaterTask; +import com.orbekk.same.android.ClientInterfaceBridge; +import com.orbekk.same.android.SameService; +import com.orbekk.stats.Common; +import com.orbekk.stats.Experiments.Empty; +import com.orbekk.stats.Experiments.Experiment2; +import com.orbekk.stats.Experiments.SimpleTiming; + +public class Experiment2Activity extends Activity { + private Logger logger = LoggerFactory.getLogger(getClass()); + public static final int WARMUP_ITERATIONS = 2; + public static final int ITERATIONS = 50; + private ClientInterfaceBridge client; + + private int warmupIterationsPerformed; + private int iterationsPerformed; + private volatile Timer timer; + + private volatile VariableUpdaterTask updater; + private volatile Variable variable; + private volatile RpcChannel channel; + + private OnChangeListener changeListener = + new OnChangeListener() { + @Override + public void valueChanged(Variable variable) { + stopIteration(); + if (iterationsPerformed < ITERATIONS) { + startIteration(); + } else { + finalizeBenchmark(); + } + } + }; + + private void startIteration() { + class Callback implements RpcCallback { + private Rpc rpc; + + public Callback(Rpc rpc) { + this.rpc = rpc; + } + + @Override public void run(Services.Empty response) { + if (response == null) { + logger.error("Benchmark failed: " + rpc); + } + } + } + Rpc rpc = new Rpc(); + try { + Services.SystemService system = Services.SystemService.newStub(channel); + rpc.setTimeout(15000); + system.killMaster(rpc, Services.Empty.getDefaultInstance(), new Callback(rpc)); + rpc.await(); + Thread.sleep(200); + if (rpc.isOk()) { + logger.info("Master killed. Timing recovery."); + } + } catch (InterruptedException e) { + logger.error("Benchmark failed."); + e.printStackTrace(); + } + + timer.start(); + variable.update(); + updater.set(0); + } + + private void finalizeBenchmark() { + Variable> participants = + client.createVariableFactory().create( + ".participants0", Types.STRING_LIST); + int numDevices = participants.get().size(); + RpcChannel channel = null; + try { + RpcCallback done = new RpcCallback() { + @Override public void run(Empty response) { + } + }; + channel = RpcChannel.create(Common.HOSTNAME, Common.PORT); + Experiment2 exp2 = Experiment2.newStub(channel); + int warmupIterationsLeft = WARMUP_ITERATIONS; + for (Long sample : timer.getTimes()) { + if (warmupIterationsLeft-- > 0) { + continue; + } + SimpleTiming timing = SimpleTiming.newBuilder() + .setTiming(sample) + .setNumDevices(numDevices) + .build(); + Rpc rpc = new Rpc(); + rpc.setTimeout(5000); + exp2.registerSample(rpc, timing, done); + rpc.await(); + if (!rpc.isOk()) { + logger.warn("Could not register data: " + rpc.toString()); + } + } + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + if (channel != null) { + channel.close(); + } + } + Toast.makeText(this, "Finished benchmark", Toast.LENGTH_LONG).show(); + } + + private void stopIteration() { + timer.stop(); + if (warmupIterationsPerformed < WARMUP_ITERATIONS) { + warmupIterationsPerformed += 1; + logger.info("Recovered. Finished warmup iteration " + warmupIterationsPerformed + "/" + WARMUP_ITERATIONS); + } else { + iterationsPerformed += 1; + logger.info("Recovered. Finished iteration " + iterationsPerformed + "/" + ITERATIONS); + } + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + logger.error("Interrupted!"); + e.printStackTrace(); + } + } + + @Override public void onCreate(Bundle savedBundle) { + super.onCreate(savedBundle); + } + + public void onResume() { + super.onResume(); + try { + channel = RpcChannel.create("localhost", SameService.PPORT); + } catch (UnknownHostException e) { + logger.error("Unable to create RPC channel."); + e.printStackTrace(); + } catch (IOException e) { + logger.error("Unable to create RPC channel."); + e.printStackTrace(); + } + +// java.util.logging.Level level = java.util.logging.Level.FINEST; +// java.util.logging.Logger rpcLog = java.util.logging.Logger.getLogger( +// com.orbekk.protobuf.RequestDispatcher.class.getName()); +// rpcLog.setLevel(level); +// java.util.logging.Logger channelLog = java.util.logging.Logger.getLogger( +// com.orbekk.protobuf.RpcChannel.class.getName()); +// channelLog.setLevel(level); +// java.util.logging.Handler handler = new java.util.logging.ConsoleHandler(); +// handler.setLevel(level); +// rpcLog.addHandler(handler); +// channelLog.addHandler(handler); + + Toast.makeText(this, "Starting benchmark", Toast.LENGTH_LONG).show(); + + timer = new Timer(WARMUP_ITERATIONS + ITERATIONS); + warmupIterationsPerformed = 0; + iterationsPerformed = 0; + client = new ClientInterfaceBridge(this); + client.connect(); + initializeVariable(); + startIteration(); + } + + public void initializeVariable() { + variable = client.createVariableFactory() + .create("BenchmarkVariable", Types.INTEGER); + variable.addOnChangeListener(changeListener); + updater = new VariableUpdaterTask(variable); + updater.start(); + } + + public void onPause() { + super.onPause(); + if (channel != null) { + channel.close(); + } + updater.interrupt(); + client.disconnect(); + } + +} -- cgit v1.2.3