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

[One .NET] Profiled AOT support #6171

Merged
merged 2 commits into from Sep 2, 2021

Conversation

jonathanpeppers
Copy link
Member

@jonathanpeppers jonathanpeppers commented Aug 6, 2021

Fixes: #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, 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 theActivity: 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 00:00.4387 00:00:3317 00:00.3093 9,155,954 12,755,672 9,777,880
MauiApp1 00:01.4205 00:00:7285 00:00.7098 17,435,225 44,751,651 23,210,787

@charlesroddie
Copy link

HelloMaui ... 43,442,233

The moves from mono to monovm+corefx, from Xamarin to Maui, and the work in dotnet on linkers all have had no effect?

@jonathanpeppers
Copy link
Member Author

@charlesroddie the HelloMaui full AOT app size is bigger (from what we've seen), due to two things:

  • The AOT compiler's output is larger (iOS team had similar results)
  • dotnet/maui is not setup to be Trimmable yet

We hope these numbers will get better by the time .NET 6 is released.

@jonathanpeppers jonathanpeppers force-pushed the dotnet-profiled-aot branch 3 times, most recently from cf41e25 to b118180 Compare August 16, 2021 15:54
jonathanpeppers added a commit to jonathanpeppers/runtime that referenced this pull request Aug 16, 2021
Context: xamarin/xamarin-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
@@ -680,6 +680,12 @@ because xbuild doesn't support framework reference assemblies.
/>
</CreateProperty>

<CreateProperty Value="$(MonoAndroidBinDirectory)">
Copy link
Member

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? :-)

Copy link
Member Author

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: xamarin#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
@jonpryor
Copy link
Member

jonpryor commented Sep 2, 2021

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 <grendel@twistedcode.net>

@jonpryor jonpryor merged commit 3e699d6 into xamarin:main Sep 2, 2021
jonpryor pushed a commit that referenced this pull request Feb 1, 2022
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
@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.

[One .NET] Record new AOT Profiles
4 participants