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

[monodroid, Xamarin.Android.Build.Tasks] Interpreter support (#4618) #4618

Merged
merged 1 commit into from
Apr 28, 2020

Conversation

grendello
Copy link
Contributor

@grendello grendello commented Apr 24, 2020

Context: https://www.mono-project.com/news/2017/11/13/mono-interpreter/

Add experimental support to use Mono's IL interpreter instead
of using the JIT or (Hybrid)AOT backends by setting the
$(_AndroidUseInterpreter) MSBuild property to True.

This is a proof-of-concept to explore how the interpreter backend
performs compared to the JIT backend at various tasks. It is not
currently intended for production use.

Note that Mono's IL interpreter does not currently support running
on x86 targets. Issue an XA0124 error if the interpreter is enabled
when targeting x86 devices.

One "interesting" -- but not explored -- result is that startup time
is reduced when using the interpreter; on a Pixel 3 XL launching
a arm64-v8a build of tests/Xamarin.Forms-Performance-Integration:

Description native-to-managed Runtime.init ActivityDisplayed
JIT 53.660 ms 92.821 ms 1091.30 ms
Interpreter 32.019 ms 112.288 ms 897.50 ms

Here, native-to-managed time and ActivityDisplayed times are reduced,
while Runtime.init() time is increased.

We did not explore why this would be the case, or what other
performance changes would be present after app startup.

@grendello grendello force-pushed the interpreter branch 2 times, most recently from b973b9c to 19fcbca Compare April 27, 2020 12:17
@grendello grendello marked this pull request as ready for review April 27, 2020 14:55
@jonpryor
Copy link
Member

$(_AndroidUseInterpreter) is a "private" property. The question: what property & semantics should we have for this to be public?

Options:

  • Make it public: $(AndroidUseInterpreter) boolean property
  • Add to $(AndroidAotMode)?
  • New enum property: $(AndroidRuntimeModes)
  • Something else?

$(AndroidAotMode)

$(AndroidAotMode) is an "enum" property with the values: None, Normal, Hybrid, Full. Could we add an Interpreter value?

While this could be done, it was felt that this was exposing an "implementation detail" -- that while an "interpreter" value is used with mono_jit_set_aot_mode(), that need not be the case for all time.

The other problem is that we'll invariably want to be able to specify both interpreter and an AOT mode. A separate $(AndroidUseInterpreter) property works, or we could turn $(AndroidAotMode) into a comma-separated "flags enum" property as described in $(AndroidRuntimeModes).

$(AndroidRuntimeModes)

A possible scenario with more "robust" interpreter support is that Mono could support "tiered JIT" use: interpreter for starters, then JIT frequently used methods.

This suggests we could have a "[Flags]-enum like" comma-separated property value, being one or more of:

  • Aot
  • Jit
  • Interpreter

This allows combinations of:

  • Aot: $(AndroidAotMode)=Full [not currently supported]
  • Jit: aka $(AndroidAotMode)=None [or Normal?]; current default.
  • Interpreter: only interpreter, no JIT
  • Interpreter,Jit: Tiered JIT use, if/when that is ever supported.
  • Aot,Jit: $(AndroidAotMode)=Normal or Hybrid [ambiguous; suggests this entire idea needs more thought]
  • Aot,Interpreter: $(AndroidAotMode)=Normal or Hybrid [also ambiguous]
  • Aot,Interpreter,Jit: All The Things! Not sure if this combination actually makes sense, but if it did, it would be tiered JIT for non-AOT'd methods.

On the one hand, this could plausibly "subsume" $(AndroidAotMode) allowing for a nice "semantic cleanup," but on the other hand such "subsume-ation" makes for potential confusion about priority and ordering of properties when both $(AndroidRuntimeModes) and $(AndroidAotMode) are set. It also contains ambiguities around Hybrid vs. Full AOT.

@grendello
Copy link
Contributor Author

@jonp I'd use $(AndroidUseInterpreter) as it doesn't expose any technicalities to the users.

abiName: AbiNames.TargetJit.AndroidX86,
interpreter: true,
enabledCheck: (Context ctx) => ctx.IsTargetJitAbiEnabled (AbiNames.TargetJit.AndroidX86)
),
Copy link
Contributor

@lewurm lewurm Apr 28, 2020

Choose a reason for hiding this comment

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

Alas we do not support the interpreter on x86.

Is this fairly common? Or does everyone use x86_64 anyway as emulator?

Edit: I just saw we ship the x86 interpreter bits in the Mono SDK 😅 that will assert on startup though.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We actually use x86 emulators on CI...

Copy link
Contributor

Choose a reason for hiding this comment

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

I meant with "everyone" the average Xamarin.Android developer 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Developers will most definitely run emulators using either x86 or x86_64 images, but I don't know which one of those is more popular. Both are accelerated and x86_64 can run x86 apps, so I'd hope that this one's more popular, but that's just my hope not supported by any data :)

Copy link
Contributor

Choose a reason for hiding this comment

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

ok, I created mono/mono#19669

Copy link
Member

Choose a reason for hiding this comment

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

I think most devs use x86 right now as Visual Studio suggests it by default.

Copy link
Contributor

@JonDouglas JonDouglas Apr 28, 2020

Choose a reason for hiding this comment

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

@lewurm x86 is like 90% with x86_64 in the < 10% range. ARM even lower here.

Copy link
Contributor

Choose a reason for hiding this comment

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

ABI/CPU -

88/10/3/2% for x86/x86_64/armeabi-v7a/arm64-v8a on Mac.

90/7/1/1% for x86/x86_64/armeabi-v7a/arm64-v8a on Windows.

Doesn't work yet - XA runtime is not placed in the `interpreter-` dirs yet
@jonpryor jonpryor merged commit 42822e0 into dotnet:master Apr 28, 2020
@grendello grendello changed the title [WIP] Interpreted apps [monodroid, Xamarin.Android.Build.Tasks] Interpreter support (#4618) Apr 28, 2020
@grendello grendello deleted the interpreter branch April 28, 2020 20:59
jonpryor pushed a commit that referenced this pull request Apr 28, 2020
Context: https://www.mono-project.com/news/2017/11/13/mono-interpreter/

Add *experimental* support to use [Mono's IL interpreter][0] instead
of using the JIT or (Hybrid)AOT backends by setting the
`$(_AndroidUseInterpreter)` MSBuild property to True.

This is a proof-of-concept to explore how the interpreter backend
performs compared to the JIT backend at various tasks.  It is not
currently intended for production use.

Note that Mono's IL interpreter does *not* currently support running
on x86 targets.  Issue an XA0124 error if the interpreter is enabled
when targeting x86 devices.

One "interesting" -- but not explored -- result is that startup time
is [*reduced* when using the interpreter][1]; on a Pixel 3 XL launching
a arm64-v8a build of `tests/Xamarin.Forms-Performance-Integration`:

| Description | native-to-managed | Runtime.init | ActivityDisplayed |
|------------:|------------------:|-------------:|------------------:|
| JIT         |         53.660 ms |    92.821 ms |        1091.30 ms |
| Interpreter |         32.019 ms |   112.288 ms |         897.50 ms |

Here, native-to-managed time and ActivityDisplayed times are reduced,
while `Runtime.init()` time is increased.

We did not explore why this would be the case, or what other
performance changes would be present after app startup.

[0]: https://www.mono-project.com/news/2017/11/13/mono-interpreter/
[1]: https://gist.github.com/grendello/3510f2c0621eb360cd063d6c00b4b1e8#file-results-md
@github-actions github-actions bot locked and limited conversation to collaborators Jan 24, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants