Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RPC] Android RPC Performance Regression Fix, Update Android RPC to use Tracker #1457

Merged
merged 32 commits into from
Jul 20, 2018

Conversation

eqy
Copy link
Contributor

@eqy eqy commented Jul 19, 2018

#1433 and #1426 raise the issue of a performance regression introduced in #1387, due to a change in the Activity/Service Layout of the app.

Originally, the RPC App used a single process, and a single Activity for the entire app, comprising both the RPC Server and UI.
#1387 moved the RPC Server to an Android Service in an isolated process, and added a watchdog to the main Activity. Unfortunately, processes running Services in Android are treated as lower priority than processes running Activities, so this caused a CPU performance regression in Android RPC.

We investigated reversing the layout to run the watchdog in a ForegroundService and instead run the RPC server in an Activity, but keeping the (watchdog) Service alive when the RPC server's Activity and process crash proved to be difficult and unreliable. We now choose to run the RPC server in a separate Activity isolated from the main Activity's process. This way, if the RPC server crashes, it takes its Activity down by itself and resumes the main Activity of the app, which can trigger a restart of the RPC server. Using a separate Activity also addresses the CPU performance regression issue. (ForegroundServices also complicated handling API levels >= 26 vs. < 26, which we are now happy to avoid).

The watchdog implementation has also been tweaked to use notify and wait instead of a polling mechanism, which should minimize any additional CPU overhead (though we believe the regression was due to using a Service).

Additionally, the introduction of the RPC Tracker in #1080 duplicates much of the functionality of the RPC Proxy that the Android RPC app was originally designed to use. We now switch the Android RPC app to use the RPC Tracker protocol.

This leaves us with a few UI changes to the Android app:

  • Address now corresponds to the address of the RPC Tracker
  • Port now corresponds to the port of the RPC Tracker
  • Key now corresponds to the device key reported to the RPC Tracker
  • The switch now controls whether the RPC server should automatically restart if crashed/closed
  • The RPC server is now started with a button that launches a new Activity
  • The new Activity has a button to stop the RPC server (note that if the switch is ON, the RPC server will restart itself)

CC @alex-weaver @merrymercy @yzhliu



/**
* Server processor with tracker connection (based on standalone).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

put a bit more document in here

private final SocketFileDescriptorGetter socketFileDescriptorGetter;
private final String trackerHost;
private final int trackerPort;
private final String key;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

document the key and matchkey

return trackerSocket;
}

private void register(Socket trackerSocket) throws IOException {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

document this function

}
}

private Socket connectToTracker() throws IOException{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IOException {

continue;
}
int keyLen = Utils.wrapBytes(Utils.recvAll(in, 4)).getInt();
recvKey = Utils.decodeToStr(Utils.recvAll(in, keyLen));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adds Utils.recvStr and Utils.sendStr since it is commonly used

Socket trackerSocket = null;
String recvKey = null;
try {
trackerSocket = connectToTracker();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider wrap a standalone class TrackerClient and move all related logics to there, to make the logic cleaner

Socket trackerSocket = null;
String recvKey = null;
try {
// open a socket and handshake with tracker
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put more comment in here, document the general steps in the protocol

}

// if we find the matchKey, we do not need to refresh
private boolean checkMatchKey(Socket trackerSocket) throws IOException {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function name is a bit confusing, maybe we can do needRefreshMatchKey

@tqchen
Copy link
Member

tqchen commented Jul 19, 2018

Please update the android_rpc/README.md to include instructions to use rpc_tracker

@merrymercy
Copy link
Member

merrymercy commented Jul 24, 2018

@tqchen
Copy link
Member

tqchen commented Jul 24, 2018

@eqy can you followup on @merrymercy 's comment?

@eqy eqy mentioned this pull request Jul 24, 2018
tqchen pushed a commit to tqchen/tvm that referenced this pull request Aug 4, 2018
sergei-mironov pushed a commit to sergei-mironov/tvm that referenced this pull request Aug 8, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants