-
Notifications
You must be signed in to change notification settings - Fork 538
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
[One .NET] Profiled AOT support #6171
Conversation
The moves from mono to monovm+corefx, from Xamarin to Maui, and the work in dotnet on linkers all have had no effect? |
@charlesroddie the HelloMaui full AOT app size is bigger (from what we've seen), due to two things:
We hope these numbers will get better by the time .NET 6 is released. |
cf41e25
to
b118180
Compare
Context: dotnet/android#6171 Fixes: dotnet#56989 In order for the Android workload to be able to record `.aotprof`/`.aotprofile` files, we need `libmono-profiler-aot.so` to be available. Down the road this feature could be provided by the Mono diagnostics component, but will probably not happen in .NET 6. These changes build `libmono-profiler-aot.so` for Android, and includes it in the `Microsoft.NETCore.App.Runtime.Mono.android-*` runtime packs. In the Android workload's MSBuild targets we exclude this native library unless the app is configured to record an AOT profile. I also included in `CMakeLists.txt`: target_compile_definitions(mono-profiler-aot PRIVATE -DMONO_DLL_EXPORT) Otherwise, the AOT profiler cannot be loaded: 08-12 16:01:39.817 3003 3003 I monodroid-assembly: Trying to load shared library '/data/app/com.microsoft.net6.helloandroid-4u8tNHoPAh4zSZMaf2FsnA==/lib/x86_64/libmono-profiler-aot.so' 08-12 16:01:39.818 3003 3003 W monodroid: Looking for profiler init symbol 'mono_profiler_init_aot'? 0x0 08-12 16:01:39.818 3003 3003 W monodroid: The 'aot' profiler wasn't found in the main executable nor could it be loaded from 'libmono-profiler-aot.so'. With these changes, I can successfully record an AOT profile on Android: Reading from '127.0.0.1:9999'... Read 4096 bytes... ... Read 2671 bytes... Read total 72303 bytes... Summary: Modules: 8 Types: 197 Methods: 910 Going to write the profile to 'custom.aprof' When using the profile, I get improved startup times: 08-12 16:56:33.940 1624 1874 I ActivityTaskManager: Displayed com.microsoft.net6.helloandroid/crc6490bfc84a0f5dff7a.MainActivity: +217ms
b118180
to
b9faaf6
Compare
@@ -680,6 +680,12 @@ because xbuild doesn't support framework reference assemblies. | |||
/> | |||
</CreateProperty> | |||
|
|||
<CreateProperty Value="$(MonoAndroidBinDirectory)"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we start using <PropertyGroup/>
here? :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I started a new <PropertyGroup/>
and we can port all these in the future.
Fixes: dotnet#6053 This enables the ability to set: <PropertyGroup Condition=" '$(Configuration)' == 'Release' "> <RunAOTCompilation>true</RunAOTCompilation> <AndroidEnableProfiledAot>true</AndroidEnableProfiledAot> </PropertyGroup> And a default `dotnet.aotprofile` will be passed to the `<MonoAOTCompiler/>` MSBuild task. There will not be a way to "record" profiles in the Android workload in .NET 6. This is because it relies on legacy Mono infrastructure that is not implemented in .NET 6. I created a Github repo for recording profiles, where I committed the necessary binaries such as `aprofutil` and `libmono-profiler-aot.so`: https://github.com/jonathanpeppers/android-profiled-aot I recorded a `dotnet.aotprofile` with the contents: Modules: 6799590C-2963-4835-AEDC-20C67D875132 System.Private.CoreLib 2CC403AF-60DC-48A9-9B69-FF254277AEA0 Mono.Android 92FF7068-2EA9-4681-B340-44E91077417A Java.Interop 008C0F24-5014-4D41-AAB9-DDFCEA59E171 Xamarin.Google.Android.Material 7CEE6098-BE9F-4043-B35A-B8B0684EF0CB Xamarin.AndroidX.AppCompat 20D1FBB8-829A-4618-8E82-8047C8827EA8 Xamarin.AndroidX.Fragment CC363D7A-9CDB-4999-9E10-279412B14A1B Xamarin.AndroidX.Activity 21CF52B7-0256-4838-848C-DA026B2F1789 Xamarin.AndroidX.Core D1DE5607-BC27-45FC-93EC-0542C787E5FF Xamarin.AndroidX.DrawerLayout Summary: Modules: 9 Types: 229 Methods: 1,010 `AndroidApp1` is the `Navigation Drawer App` template from "legacy" Xamarin.Android. I ported this template to .NET 6 and dropped usage of Xamarin.Essentials. I thought this was a good target for a default profile, because of its heavy usage of AndroidX and Google Material. In a future PR, I will add a default AOT profile for .NET MAUI to be shipped inside the `maui` workload. ~~ Results ~~ All tests: 1. Were running on a [Google Pixel 5][0], and 2. Enabled two architectures, arm64 and x86, and 3. **JIT time** was average of 10 runs with `-c Release`, no AOT 4. **AOT time** was average of 10 runs with `-c Release -p:RunAOTCompilation=true`, with the`Activity: Displayed` time 5. **Profiled AOT time** was average of 10 runs with `-c Release -p:RunAOTCompilation=true -p:AndroidEnableProfiledAot=true` with the `Activity: Displayed` time. | Test | JIT time | AOT time | Profiled AOT time | JIT apk size | AOT apk size | Profiled AOT apk size | | ------------------ | ----------: | ----------: | ----------------: | ------------: | ------------: | --------------------: | | [AndroidApp1][1] | 00:00.4387 | 00:00:3317 | 00:00.3093 | 9,155,954 | 12,755,672 | 9,777,880 | | [MauiApp1][2] | 00:01.4205 | 00:00:7285 | 00:00.7098 | 17,435,225 | 44,751,651 | 23,210,787 | [0]: store.google.com/us/product/pixel_5_specs?hl=en-US [1]: jonathanpeppers/android-profiled-aot@e48c6df/AndroidApp1 [2]: jonathanpeppers/android-profiled-aot@e48c6df/MauiApp1
b9faaf6
to
73a20a6
Compare
Fixes: https://github.com/xamarin/xamarin-android/issues/6053
Context: https://github.com/jonathanpeppers/android-profiled-aot
This enables the ability to set:
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<RunAOTCompilation>true</RunAOTCompilation>
<AndroidEnableProfiledAot>true</AndroidEnableProfiledAot>
</PropertyGroup>
Add a default `dotnet.aotprofile` which will be passed to the
`<MonoAOTCompiler/>` MSBuild task.
There will not be a way to "record" profiles in the Android workload
in .NET 6. This is because it relies on legacy Mono infrastructure
that is not implemented in .NET 6.
I created a Github repo for recording profiles, where I committed the
necessary binaries such as `aprofutil` and `libmono-profiler-aot.so`:
* https://github.com/jonathanpeppers/android-profiled-aot
I recorded a `dotnet.aotprofile` with the contents:
Modules:
6799590C-2963-4835-AEDC-20C67D875132 System.Private.CoreLib
2CC403AF-60DC-48A9-9B69-FF254277AEA0 Mono.Android
92FF7068-2EA9-4681-B340-44E91077417A Java.Interop
008C0F24-5014-4D41-AAB9-DDFCEA59E171 Xamarin.Google.Android.Material
7CEE6098-BE9F-4043-B35A-B8B0684EF0CB Xamarin.AndroidX.AppCompat
20D1FBB8-829A-4618-8E82-8047C8827EA8 Xamarin.AndroidX.Fragment
CC363D7A-9CDB-4999-9E10-279412B14A1B Xamarin.AndroidX.Activity
21CF52B7-0256-4838-848C-DA026B2F1789 Xamarin.AndroidX.Core
D1DE5607-BC27-45FC-93EC-0542C787E5FF Xamarin.AndroidX.DrawerLayout
Summary:
Modules: 9
Types: 229
Methods: 1,010
`AndroidApp1` is the `Navigation Drawer App` template from "legacy"
Xamarin.Android. I ported this template to .NET 6 and dropped usage
of Xamarin.Essentials. I thought this was a good target for a default
profile, because of its heavy usage of AndroidX and Google Material.
In a future PR, I will add a default AOT profile for .NET MAUI to be
shipped inside the `maui` workload.
~~ Results ~~
All tests:
1. Were running on a [Google Pixel 5][0], and
2. Enabled two architectures, arm64 and x86, and
3. **JIT time** was average of 10 runs with `-c Release`, no AOT
4. **AOT time** was average of 10 runs with `-c Release
-p:RunAOTCompilation=true`, with the`Activity: Displayed` time
5. **Profiled AOT time** was average of 10 runs with `-c Release
-p:RunAOTCompilation=true -p:AndroidEnableProfiledAot=true` with
the `Activity: Displayed` time.
| | [AndroidApp1][1] | [MauiApp1][2] |
| ----------------------------------: | ------------------: | ----------------: |
| JIT startup time (s) | 00:00.4387 | 00:01.4205 |
| AOT startup time (vs. JIT) | 00:00.3317 ( 76%) | 00:00.7285 ( 51%) |
| Profiled AOT startup time (vs. JIT) | 00:00.3093 ( 71%) | 00:00.7098 ( 50%) |
| JIT `.apk` size (B) | 9,155,954 | 17,435,225 |
| AOT `.apk` size (vs. JIT) | 12,755,672 (139%) | 44,751,651 (257%) |
| Profiled AOT `.apk` size (vs. JIT) | 9,777,880 (107%) | 23,210,787 (133%) |
[0]: store.google.com/us/product/pixel_5_specs?hl=en-US
[1]: jonathanpeppers/android-profiled-aot@e48c6df/AndroidApp1
[2]: jonathanpeppers/android-profiled-aot@e48c6df/MauiApp1
Co-authored-by: Marek Habersack <[email protected]> |
Context: dotnet/maui#4355 Context: https://github.com/jonathanpeppers/android-profiled-aot Context: #6171 Context: 3e699d6 I found that when I went to update the .NET MAUI AOT profile in dotnet/maui#4355, the profiler crashed with: 01-27 11:10:16.119 28922 28922 W monodroid: Creating public update directory: `/data/user/0/com.androidaot.MauiApp1/files/.__override__` ... 01-27 11:10:16.119 28922 28922 W monodroid: Initializing profiler with options: aot:port=9999output=/data/user/0/com.androidaot.MauiApp1/files/.__override__/profile.aotprofile 01-27 11:10:16.119 28922 28922 W monodroid: Looking for profiler init symbol 'mono_profiler_init_aot'? 0x7325b6355c 01-27 11:10:16.119 28922 28922 E mono-prof: Could not create AOT profiler output file 'output.aotprofile': Read-only file system But the directory was writeable? adb shell run-as com.androidaot.MauiApp1 touch files/.__override__/foo # no error After some digging, it turned out that *appending* `,` to the [`_SetAotProfilingPropsOnDevice` target's `<Exec/>`][0] fixed it: "$(AdbToolPath)adb" $(AdbTarget) shell setprop debug.mono.profile aot:port=$(AndroidAotProfilerPort), What happened was we "lost" a `,` somewhere in #6171, likely in: * f73a323 To fix this: 1. Prepend a `,` 2. I found a way to actually enable tests for Profiled AOT in .NET 6 by downloading binaries from my Github repo. In enabling the `ProfiledAOT` category for .NET 6, I found that this setting wasn't working: <AndroidExtraAotOptions>--verbose</AndroidExtraAotOptions> I updated `%(_MonoAOTAssemblies.ProcessArguments)` to solve this. [0]: https://github.com/xamarin/xamarin-android/blob/b7a368a27667c69117f64be81050403f2d5c8560/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Application.targets#L45
Fixes: #6053
This enables the ability to set:
And a default
dotnet.aotprofile
will be passed to the<MonoAOTCompiler/>
MSBuild task.There will not be a way to "record" profiles in the Android workload
in .NET 6. This is because it relies on legacy Mono infrastructure
that is not implemented in .NET 6.
I created a Github repo for recording profiles, where I committed the
necessary binaries such as
aprofutil
andlibmono-profiler-aot.so
:https://github.com/jonathanpeppers/android-profiled-aot
I recorded a
dotnet.aotprofile
with the contents:AndroidApp1
is theNavigation Drawer App
template from "legacy"Xamarin.Android. I ported this template to .NET 6 and dropped usage of
Xamarin.Essentials. I thought this was a good target for a default
profile, because of its heavy usage of AndroidX and Google Material.
In a future PR, I will add a default AOT profile for .NET MAUI to be
shipped inside the
maui
workload.Results
All tests:
-c Release
, no AOT-c Release -p:RunAOTCompilation=true
, with theActivity: Displayed
time-c Release -p:RunAOTCompilation=true -p:AndroidEnableProfiledAot=true
withthe
Activity: Displayed
time.