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] Record new AOT Profiles #6053

Closed
jonathanpeppers opened this issue Jun 28, 2021 · 1 comment · Fixed by #6171
Closed

[One .NET] Record new AOT Profiles #6053

jonathanpeppers opened this issue Jun 28, 2021 · 1 comment · Fixed by #6171
Assignees
Labels
Area: App+Library Build Issues when building Library projects or Application projects.
Milestone

Comments

@jonathanpeppers
Copy link
Member

Can be started after: #6052

TBD if anything is missing in dotnet/runtime to enable this.

@jonathanpeppers jonathanpeppers added Area: App+Library Build Issues when building Library projects or Application projects. needs-triage Issues that need to be assigned. labels Jun 28, 2021
@jonathanpeppers jonathanpeppers self-assigned this Jun 28, 2021
@jonathanpeppers jonathanpeppers added this to the .NET 6 milestone Jun 28, 2021
@jonathanpeppers jonathanpeppers removed the needs-triage Issues that need to be assigned. label Jun 28, 2021
jonathanpeppers added a commit that referenced this issue Jul 27, 2021
Fixes: #6052

Helpful reading:

* https://github.com/dotnet/runtime/blob/15dec9a2aa5a4236d6ba70de2e9c146867b9d2e0/src/tasks/AotCompilerTask/MonoAOTCompiler.cs
* https://github.com/dotnet/runtime/blob/15dec9a2aa5a4236d6ba70de2e9c146867b9d2e0/src/mono/netcore/nuget/Microsoft.NET.Runtime.MonoAOTCompiler.Task/README.md

To make this work, I moved the existing `<Aot/>` MSBuild task calls to
a new `_AndroidAot` MSBuild target in `Xamarin.Android.Legacy.targets`.

In the .NET 6 targets, there is a *different* `_AndroidAot` MSBuild
target that runs the new `<MonoAOTCompiler/>` MSBuild task. The
`_AndroidAot` target runs per `$(RuntimeIdentifier)` after the linker
completes. Native libraries are added to the
`@(ResolvedFileToPublish)` item group to be included in the final
`.apk`.

To follow convention with Blazor WASM:

https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in-net-6-preview-4/#blazor-webassembly-ahead-of-time-aot-compilation

The `$(RunAOTCompilation)` MSBuild property enables AOT. To help with
backwards compatibility with "legacy" Xamarin.Android, I kept the
`$(AotAssemblies)` MSBuild property intact.

Unfortunately, we have to manually import things to support
`$(AotAssemblies)`:

    <ImportGroup Condition=" '$(MonoAOTCompilerTasksAssemblyPath)' == '' and '$(AotAssemblies)' == 'true' ">
      <Import Project="Sdk.props" Sdk="Microsoft.NET.Runtime.MonoAOTCompiler.Task" />
      <Import Project="Sdk.props" Sdk="Microsoft.NETCore.App.Runtime.AOT.Cross.android-x86" />
      <Import Project="Sdk.props" Sdk="Microsoft.NETCore.App.Runtime.AOT.Cross.android-x64" />
      <Import Project="Sdk.props" Sdk="Microsoft.NETCore.App.Runtime.AOT.Cross.android-arm" />
      <Import Project="Sdk.props" Sdk="Microsoft.NETCore.App.Runtime.AOT.Cross.android-arm64" />
    </ImportGroup>

Since, the default Mono workload does not support `$(AotAssemblies)`:

https://github.com/dotnet/runtime/blob/69711860262e44458bbe276393ea3eb9f7a2192a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Manifest/WorkloadManifest.targets.in#L20-L25

I think this is reasonable for now.

~~ Limitations ~~

* Profiled AOT is not implemented yet:

#6053

* `$(EnableLLVM)` fails when locating `opt`:

dotnet/runtime#56386

* `AndroidClientHandler` usage causes runtime crash:

dotnet/runtime#56315

* Use of folder names like `Build AndÜmläüts` fails:

dotnet/runtime#56163

~~ Results ~~

All tests were running on a Pixel 5.

Using the HelloAndroid app:

https://github.com/dotnet/maui-samples/tree/main/HelloAndroid

Defaults to two architectures: arm64 and x86

Average of 10 runs with `-c Release` and no AOT:

    Activity: Displayed     00:00:00.308

Apk size: 8367969

Average of 10 runs with `-c Release -p:RunAOTCompilation=true`:

    Activity: Displayed     00:00:00.209

Apk size: 12082123

Using the HelloMaui app:

https://github.com/dotnet/maui-samples/tree/main/HelloMaui

Defaults to two architectures: arm64 and x86

Average of 10 runs with `-c Release` and no AOT:

    Activity: Displayed     00:00:01.117

Apk size: 16272964

Average of 10 runs with `-c Release -p:RunAOTCompilation=true`:

    Activity: Displayed     00:00:00.568

Apk size: 42869016
jonpryor pushed a commit that referenced this issue Jul 28, 2021
Fixes: #6052

Helpful reading:

  * https://github.com/dotnet/runtime/blob/15dec9a2aa5a4236d6ba70de2e9c146867b9d2e0/src/tasks/AotCompilerTask/MonoAOTCompiler.cs
  * https://github.com/dotnet/runtime/blob/15dec9a2aa5a4236d6ba70de2e9c146867b9d2e0/src/mono/netcore/nuget/Microsoft.NET.Runtime.MonoAOTCompiler.Task/README.md

To make this work, I moved the existing `<Aot/>` MSBuild task calls to
a new `_AndroidAot` MSBuild target in `Xamarin.Android.Legacy.targets`.

In the .NET 6 targets, there is a *different* `_AndroidAot` MSBuild
target that runs the new `<MonoAOTCompiler/>` MSBuild task. The
`_AndroidAot` target runs once per `$(RuntimeIdentifier)`, after the
linker completes.

Native libraries are added to the `@(ResolvedFileToPublish)` item
group to be included in the final `.apk`.

To follow [convention with Blazor WASM][0], the `$(RunAOTCompilation)`
MSBuild property enables AOT.

To help with backwards compatibility with "legacy" Xamarin.Android, I
kept the `$(AotAssemblies)` MSBuild property intact.

Unfortunately, we have to manually import things to support
`$(AotAssemblies)`:

	<ImportGroup Condition=" '$(MonoAOTCompilerTasksAssemblyPath)' == '' and '$(AotAssemblies)' == 'true' ">
	  <Import Project="Sdk.props" Sdk="Microsoft.NET.Runtime.MonoAOTCompiler.Task" />
	  <Import Project="Sdk.props" Sdk="Microsoft.NETCore.App.Runtime.AOT.Cross.android-x86" />
	  <Import Project="Sdk.props" Sdk="Microsoft.NETCore.App.Runtime.AOT.Cross.android-x64" />
	  <Import Project="Sdk.props" Sdk="Microsoft.NETCore.App.Runtime.AOT.Cross.android-arm" />
	  <Import Project="Sdk.props" Sdk="Microsoft.NETCore.App.Runtime.AOT.Cross.android-arm64" />
	</ImportGroup>

as the [default Mono workload does not support `$(AotAssemblies)`][1].
I think this is reasonable for now.


~~ Limitations ~~

Profiled AOT is not implemented yet:

  * #6053

`$(EnableLLVM)` fails when locating `opt`:

  * dotnet/runtime#56386

`$(AndroidClientHandler)` usage causes runtime crash:

  * dotnet/runtime#56315

Use of folder names like `Build AndÜmläüts` fails:

  * dotnet/runtime#56163


~~ Results ~~

All tests:

 1. Were running on a [Google Pixel 5][2], and
 2. Enabled two architectures, arm64 and x86, and
 3. **JIT time** was average of 10 runs with `-c Release`, with the
    `Activity: Displayed` time, and
 4. **AOT time** was average of 10 runs with
    `-c Release -p:RunAOTCompilation=true` with the
    `Activity: Displayed` time.
 5. Δ values are (AOT / JIT)*100.

| Test                |      JIT time |      AOT time |  Δ time |  JIT apk size |  AOT apk size | Δ size |
| ------------------- | ------------: | ------------: | ------: | ------------: | ------------: | -----: |
| [HelloAndroid][3]   |  00:00:00.308 |  00:00:00.209 |     68% |     8,367,969 |    12,082,123 | 144.4% |
| [HelloMaui][4]      |  00:00:01.117 |  00:00:00.568 |     51% |    16,272,964 |    42,869,016 | 263.4% |

[0]: https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in-net-6-preview-4/#blazor-webassembly-ahead-of-time-aot-compilation
[1]: https://github.com/dotnet/runtime/blob/69711860262e44458bbe276393ea3eb9f7a2192a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Manifest/WorkloadManifest.targets.in#L20-L25
[2]: https://store.google.com/us/product/pixel_5_specs?hl=en-US
[3]: https://github.com/dotnet/maui-samples/tree/714460431541f40570e91225e8ba4bc1fe08025f/HelloAndroid
[4]: https://github.com/dotnet/maui-samples/tree/714460431541f40570e91225e8ba4bc1fe08025f/HelloMaui
jonpryor pushed a commit that referenced this issue Jul 28, 2021
Fixes: #6052

Helpful reading:

  * https://github.com/dotnet/runtime/blob/15dec9a2aa5a4236d6ba70de2e9c146867b9d2e0/src/tasks/AotCompilerTask/MonoAOTCompiler.cs
  * https://github.com/dotnet/runtime/blob/15dec9a2aa5a4236d6ba70de2e9c146867b9d2e0/src/mono/netcore/nuget/Microsoft.NET.Runtime.MonoAOTCompiler.Task/README.md

To make this work, I moved the existing `<Aot/>` MSBuild task calls to
a new `_AndroidAot` MSBuild target in `Xamarin.Android.Legacy.targets`.

In the .NET 6 targets, there is a *different* `_AndroidAot` MSBuild
target that runs the new `<MonoAOTCompiler/>` MSBuild task. The
`_AndroidAot` target runs once per `$(RuntimeIdentifier)`, after the
linker completes.

Native libraries are added to the `@(ResolvedFileToPublish)` item
group to be included in the final `.apk`.

To follow [convention with Blazor WASM][0], the `$(RunAOTCompilation)`
MSBuild property enables AOT.

To help with backwards compatibility with "legacy" Xamarin.Android, I
kept the `$(AotAssemblies)` MSBuild property intact.

Unfortunately, we have to manually import things to support
`$(AotAssemblies)`:

	<ImportGroup Condition=" '$(MonoAOTCompilerTasksAssemblyPath)' == '' and '$(AotAssemblies)' == 'true' ">
	  <Import Project="Sdk.props" Sdk="Microsoft.NET.Runtime.MonoAOTCompiler.Task" />
	  <Import Project="Sdk.props" Sdk="Microsoft.NETCore.App.Runtime.AOT.Cross.android-x86" />
	  <Import Project="Sdk.props" Sdk="Microsoft.NETCore.App.Runtime.AOT.Cross.android-x64" />
	  <Import Project="Sdk.props" Sdk="Microsoft.NETCore.App.Runtime.AOT.Cross.android-arm" />
	  <Import Project="Sdk.props" Sdk="Microsoft.NETCore.App.Runtime.AOT.Cross.android-arm64" />
	</ImportGroup>

as the [default Mono workload does not support `$(AotAssemblies)`][1].
I think this is reasonable for now.


~~ Limitations ~~

Profiled AOT is not implemented yet:

  * #6053

`$(EnableLLVM)` fails when locating `opt`:

  * dotnet/runtime#56386

`$(AndroidClientHandler)` usage causes runtime crash:

  * dotnet/runtime#56315

Use of folder names like `Build AndÜmläüts` fails:

  * dotnet/runtime#56163


~~ Results ~~

All tests:

 1. Were running on a [Google Pixel 5][2], and
 2. Enabled two architectures, arm64 and x86, and
 3. **JIT time** was average of 10 runs with `-c Release`, with the
    `Activity: Displayed` time, and
 4. **AOT time** was average of 10 runs with
    `-c Release -p:RunAOTCompilation=true` with the
    `Activity: Displayed` time.
 5. Δ values are (AOT / JIT)*100.

| Test                |      JIT time |      AOT time |  Δ time |  JIT apk size |  AOT apk size | Δ size |
| ------------------- | ------------: | ------------: | ------: | ------------: | ------------: | -----: |
| [HelloAndroid][3]   |  00:00:00.308 |  00:00:00.209 |     68% |     8,367,969 |    12,082,123 | 144.4% |
| [HelloMaui][4]      |  00:00:01.117 |  00:00:00.568 |     51% |    16,272,964 |    42,869,016 | 263.4% |

[0]: https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in-net-6-preview-4/#blazor-webassembly-ahead-of-time-aot-compilation
[1]: https://github.com/dotnet/runtime/blob/69711860262e44458bbe276393ea3eb9f7a2192a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Manifest/WorkloadManifest.targets.in#L20-L25
[2]: https://store.google.com/us/product/pixel_5_specs?hl=en-US
[3]: https://github.com/dotnet/maui-samples/tree/714460431541f40570e91225e8ba4bc1fe08025f/HelloAndroid
[4]: https://github.com/dotnet/maui-samples/tree/714460431541f40570e91225e8ba4bc1fe08025f/HelloMaui
@jonathanpeppers
Copy link
Member Author

To move forward on this, I could try:

  1. Build libmono-profiler-aot.so from dotnet/runtime myself.
  2. Use aprofutil from mono/mono.
  3. Use profile-only,profile=foo.aprof in %(AotArguments)

Filed issue here: dotnet/runtime#56989

jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Aug 6, 2021
Fixes: dotnet#6053

This is still WIP. Still a few pieces missing on the dotnet/runtime to
enable this:

dotnet/runtime#56989

We will need a `libmono-profiler-aot.so` from dotnet/runtime to be
able to record AOT profiles.

For now, I could:

1. Use the `startup.aotprofile` we're already shipping in "legacy"
   Xamarin.Android.
2. Pass this in when `$(AndroidEnableProfiledAot)` is `true`.

~~ Results ~~

All tests:

 1. Were running on a [Google Pixel 5][0], and
 2. Enabled two architectures, arm64 and x86, and
 3. **AOT time** was average of 10 runs with `-c Release
    -p:RunAOTCompilation=true`, with the`Activity: Displayed` time
 4. **Profiled AOT time** was average of 10 runs with `-c Release
    -p:RunAOTCompilation=true -p:AndroidEnableProfiledAot=true` with
    the `Activity: Displayed` time.

| Test                |      AOT time | Profiled AOT time |  AOT apk size | Profiled AOT apk size |
| ------------------- | ------------: | ----------------: | ------------: | --------------------: |
| [HelloAndroid][1]   |  00:00:00.246 |      00:00:00.288 |    12,151,755 |             9,161,675 |
| [HelloMaui][2]      |  00:00:00.619 |      00:00:01.131 |    43,442,233 |            19,992,633 |

From these results, we see that Profiled AOT is AOT'ing *some* of the
assemblies.

We are not getting the best startup time yet, because some methods are
still using the JIT:

    08-06 14:12:34.985 30817 30817 D Mono    : AOT: FOUND method Android.Runtime.JNIEnv:NewGlobalRef (intptr) [0x7ae3c8c620 - 0x7ae3c8c6a0 0x7ae3c9849c]
    08-06 14:12:34.985 30817 30817 D Mono    : AOT: NOT FOUND: intptr:op_Explicit (intptr).
    08-06 14:12:34.985 30817 30817 D Mono    : AOT: NOT FOUND: intptr:op_Explicit (int).
    08-06 14:12:34.986 30817 30817 D Mono    : AOT: FOUND method System.WeakReference`1:.ctor (T,bool) [0x7ae3d8c580 - 0x7ae3d8c5d0 0x7ae3ddaec1]
    08-06 14:12:34.986 30817 30817 D Mono    : AOT: FOUND method System.WeakReference`1:Create (T,bool) [0x7ae3d8c4c0 - 0x7ae3d8c580 0x7ae3ddaebd]
    08-06 14:12:34.986 30817 30817 D Mono    : AOT: NOT FOUND: System.Runtime.InteropServices.GCHandle:Alloc (object,System.Runtime.InteropServices.GCHandleType).
    08-06 14:12:34.986 30817 30817 D Mono    : AOT: NOT FOUND: System.Runtime.InteropServices.GCHandle:Alloc (object,System.Runtime.InteropServices.GCHandleType).
    08-06 14:12:34.986 30817 30817 D Mono    : AOT: NOT FOUND: System.Runtime.InteropServices.GCHandle:.ctor (object,System.Runtime.InteropServices.GCHandleType).

Overall, seems promising, though.

[0]: store.google.com/us/product/pixel_5_specs?hl=en-US
[1]: dotnet/maui-samples@7144604/HelloAndroid
[2]: dotnet/maui-samples@7144604/HelloMaui
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Aug 12, 2021
Fixes: dotnet#6053

This is still WIP. Still a few pieces missing on the dotnet/runtime to
enable this:

dotnet/runtime#56989

We will need a `libmono-profiler-aot.so` from dotnet/runtime to be
able to record AOT profiles.

For now, I could:

1. Use the `startup.aotprofile` we're already shipping in "legacy"
   Xamarin.Android.
2. Pass this in when `$(AndroidEnableProfiledAot)` is `true`.

~~ Results ~~

All tests:

 1. Were running on a [Google Pixel 5][0], and
 2. Enabled two architectures, arm64 and x86, and
 3. **AOT time** was average of 10 runs with `-c Release
    -p:RunAOTCompilation=true`, with the`Activity: Displayed` time
 4. **Profiled AOT time** was average of 10 runs with `-c Release
    -p:RunAOTCompilation=true -p:AndroidEnableProfiledAot=true` with
    the `Activity: Displayed` time.

| Test                |      AOT time | Profiled AOT time |  AOT apk size | Profiled AOT apk size |
| ------------------- | ------------: | ----------------: | ------------: | --------------------: |
| [HelloAndroid][1]   |  00:00:00.246 |      00:00:00.288 |    12,151,755 |             9,161,675 |
| [HelloMaui][2]      |  00:00:00.619 |      00:00:01.131 |    43,442,233 |            19,992,633 |

From these results, we see that Profiled AOT is AOT'ing *some* of the
assemblies.

We are not getting the best startup time yet, because some methods are
still using the JIT:

    08-06 14:12:34.985 30817 30817 D Mono    : AOT: FOUND method Android.Runtime.JNIEnv:NewGlobalRef (intptr) [0x7ae3c8c620 - 0x7ae3c8c6a0 0x7ae3c9849c]
    08-06 14:12:34.985 30817 30817 D Mono    : AOT: NOT FOUND: intptr:op_Explicit (intptr).
    08-06 14:12:34.985 30817 30817 D Mono    : AOT: NOT FOUND: intptr:op_Explicit (int).
    08-06 14:12:34.986 30817 30817 D Mono    : AOT: FOUND method System.WeakReference`1:.ctor (T,bool) [0x7ae3d8c580 - 0x7ae3d8c5d0 0x7ae3ddaec1]
    08-06 14:12:34.986 30817 30817 D Mono    : AOT: FOUND method System.WeakReference`1:Create (T,bool) [0x7ae3d8c4c0 - 0x7ae3d8c580 0x7ae3ddaebd]
    08-06 14:12:34.986 30817 30817 D Mono    : AOT: NOT FOUND: System.Runtime.InteropServices.GCHandle:Alloc (object,System.Runtime.InteropServices.GCHandleType).
    08-06 14:12:34.986 30817 30817 D Mono    : AOT: NOT FOUND: System.Runtime.InteropServices.GCHandle:Alloc (object,System.Runtime.InteropServices.GCHandleType).
    08-06 14:12:34.986 30817 30817 D Mono    : AOT: NOT FOUND: System.Runtime.InteropServices.GCHandle:.ctor (object,System.Runtime.InteropServices.GCHandleType).

Overall, seems promising, though.

[0]: store.google.com/us/product/pixel_5_specs?hl=en-US
[1]: dotnet/maui-samples@7144604/HelloAndroid
[2]: dotnet/maui-samples@7144604/HelloMaui
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Aug 13, 2021
Fixes: dotnet#6053

This is still WIP. Still a few pieces missing on the dotnet/runtime to
enable this:

dotnet/runtime#56989

We will need a `libmono-profiler-aot.so` from dotnet/runtime to be
able to record AOT profiles.

For now, I could:

1. Use the `startup.aotprofile` we're already shipping in "legacy"
   Xamarin.Android.
2. Pass this in when `$(AndroidEnableProfiledAot)` is `true`.

~~ Results ~~

All tests:

 1. Were running on a [Google Pixel 5][0], and
 2. Enabled two architectures, arm64 and x86, and
 3. **AOT time** was average of 10 runs with `-c Release
    -p:RunAOTCompilation=true`, with the`Activity: Displayed` time
 4. **Profiled AOT time** was average of 10 runs with `-c Release
    -p:RunAOTCompilation=true -p:AndroidEnableProfiledAot=true` with
    the `Activity: Displayed` time.

| Test                |      AOT time | Profiled AOT time |  AOT apk size | Profiled AOT apk size |
| ------------------- | ------------: | ----------------: | ------------: | --------------------: |
| [HelloAndroid][1]   |  00:00:00.246 |      00:00:00.288 |    12,151,755 |             9,161,675 |
| [HelloMaui][2]      |  00:00:00.619 |      00:00:01.131 |    43,442,233 |            19,992,633 |

From these results, we see that Profiled AOT is AOT'ing *some* of the
assemblies.

We are not getting the best startup time yet, because some methods are
still using the JIT:

    08-06 14:12:34.985 30817 30817 D Mono    : AOT: FOUND method Android.Runtime.JNIEnv:NewGlobalRef (intptr) [0x7ae3c8c620 - 0x7ae3c8c6a0 0x7ae3c9849c]
    08-06 14:12:34.985 30817 30817 D Mono    : AOT: NOT FOUND: intptr:op_Explicit (intptr).
    08-06 14:12:34.985 30817 30817 D Mono    : AOT: NOT FOUND: intptr:op_Explicit (int).
    08-06 14:12:34.986 30817 30817 D Mono    : AOT: FOUND method System.WeakReference`1:.ctor (T,bool) [0x7ae3d8c580 - 0x7ae3d8c5d0 0x7ae3ddaec1]
    08-06 14:12:34.986 30817 30817 D Mono    : AOT: FOUND method System.WeakReference`1:Create (T,bool) [0x7ae3d8c4c0 - 0x7ae3d8c580 0x7ae3ddaebd]
    08-06 14:12:34.986 30817 30817 D Mono    : AOT: NOT FOUND: System.Runtime.InteropServices.GCHandle:Alloc (object,System.Runtime.InteropServices.GCHandleType).
    08-06 14:12:34.986 30817 30817 D Mono    : AOT: NOT FOUND: System.Runtime.InteropServices.GCHandle:Alloc (object,System.Runtime.InteropServices.GCHandleType).
    08-06 14:12:34.986 30817 30817 D Mono    : AOT: NOT FOUND: System.Runtime.InteropServices.GCHandle:.ctor (object,System.Runtime.InteropServices.GCHandleType).

Overall, seems promising, though.

[0]: store.google.com/us/product/pixel_5_specs?hl=en-US
[1]: dotnet/maui-samples@7144604/HelloAndroid
[2]: dotnet/maui-samples@7144604/HelloMaui
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Aug 16, 2021
Fixes: dotnet#6053

This is still WIP. Still a few pieces missing on the dotnet/runtime to
enable this:

dotnet/runtime#56989

We will need a `libmono-profiler-aot.so` from dotnet/runtime to be
able to record AOT profiles.

For now, I could:

1. Use the `startup.aotprofile` we're already shipping in "legacy"
   Xamarin.Android.
2. Pass this in when `$(AndroidEnableProfiledAot)` is `true`.

~~ Results ~~

All tests:

 1. Were running on a [Google Pixel 5][0], and
 2. Enabled two architectures, arm64 and x86, and
 3. **AOT time** was average of 10 runs with `-c Release
    -p:RunAOTCompilation=true`, with the`Activity: Displayed` time
 4. **Profiled AOT time** was average of 10 runs with `-c Release
    -p:RunAOTCompilation=true -p:AndroidEnableProfiledAot=true` with
    the `Activity: Displayed` time.

| Test                |      AOT time | Profiled AOT time |  AOT apk size | Profiled AOT apk size |
| ------------------- | ------------: | ----------------: | ------------: | --------------------: |
| [HelloAndroid][1]   |  00:00:00.246 |      00:00:00.288 |    12,151,755 |             9,161,675 |
| [HelloMaui][2]      |  00:00:00.619 |      00:00:01.131 |    43,442,233 |            19,992,633 |

From these results, we see that Profiled AOT is AOT'ing *some* of the
assemblies.

We are not getting the best startup time yet, because some methods are
still using the JIT:

    08-06 14:12:34.985 30817 30817 D Mono    : AOT: FOUND method Android.Runtime.JNIEnv:NewGlobalRef (intptr) [0x7ae3c8c620 - 0x7ae3c8c6a0 0x7ae3c9849c]
    08-06 14:12:34.985 30817 30817 D Mono    : AOT: NOT FOUND: intptr:op_Explicit (intptr).
    08-06 14:12:34.985 30817 30817 D Mono    : AOT: NOT FOUND: intptr:op_Explicit (int).
    08-06 14:12:34.986 30817 30817 D Mono    : AOT: FOUND method System.WeakReference`1:.ctor (T,bool) [0x7ae3d8c580 - 0x7ae3d8c5d0 0x7ae3ddaec1]
    08-06 14:12:34.986 30817 30817 D Mono    : AOT: FOUND method System.WeakReference`1:Create (T,bool) [0x7ae3d8c4c0 - 0x7ae3d8c580 0x7ae3ddaebd]
    08-06 14:12:34.986 30817 30817 D Mono    : AOT: NOT FOUND: System.Runtime.InteropServices.GCHandle:Alloc (object,System.Runtime.InteropServices.GCHandleType).
    08-06 14:12:34.986 30817 30817 D Mono    : AOT: NOT FOUND: System.Runtime.InteropServices.GCHandle:Alloc (object,System.Runtime.InteropServices.GCHandleType).
    08-06 14:12:34.986 30817 30817 D Mono    : AOT: NOT FOUND: System.Runtime.InteropServices.GCHandle:.ctor (object,System.Runtime.InteropServices.GCHandleType).

Overall, seems promising, though.

[0]: store.google.com/us/product/pixel_5_specs?hl=en-US
[1]: dotnet/maui-samples@7144604/HelloAndroid
[2]: dotnet/maui-samples@7144604/HelloMaui
@jonpryor jonpryor changed the title [One .NET] Profiled AOT [One .NET] Record new AOT Profiles Sep 1, 2021
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Sep 1, 2021
Fixes: dotnet#6053

This is still WIP. Still a few pieces missing on the dotnet/runtime to
enable this:

dotnet/runtime#56989

We will need a `libmono-profiler-aot.so` from dotnet/runtime to be
able to record AOT profiles.

For now, I could:

1. Use the `startup.aotprofile` we're already shipping in "legacy"
   Xamarin.Android.
2. Pass this in when `$(AndroidEnableProfiledAot)` is `true`.

~~ Results ~~

All tests:

 1. Were running on a [Google Pixel 5][0], and
 2. Enabled two architectures, arm64 and x86, and
 3. **AOT time** was average of 10 runs with `-c Release
    -p:RunAOTCompilation=true`, with the`Activity: Displayed` time
 4. **Profiled AOT time** was average of 10 runs with `-c Release
    -p:RunAOTCompilation=true -p:AndroidEnableProfiledAot=true` with
    the `Activity: Displayed` time.

| Test                |      AOT time | Profiled AOT time |  AOT apk size | Profiled AOT apk size |
| ------------------- | ------------: | ----------------: | ------------: | --------------------: |
| [HelloAndroid][1]   |  00:00:00.246 |      00:00:00.288 |    12,151,755 |             9,161,675 |
| [HelloMaui][2]      |  00:00:00.619 |      00:00:01.131 |    43,442,233 |            19,992,633 |

From these results, we see that Profiled AOT is AOT'ing *some* of the
assemblies.

We are not getting the best startup time yet, because some methods are
still using the JIT:

    08-06 14:12:34.985 30817 30817 D Mono    : AOT: FOUND method Android.Runtime.JNIEnv:NewGlobalRef (intptr) [0x7ae3c8c620 - 0x7ae3c8c6a0 0x7ae3c9849c]
    08-06 14:12:34.985 30817 30817 D Mono    : AOT: NOT FOUND: intptr:op_Explicit (intptr).
    08-06 14:12:34.985 30817 30817 D Mono    : AOT: NOT FOUND: intptr:op_Explicit (int).
    08-06 14:12:34.986 30817 30817 D Mono    : AOT: FOUND method System.WeakReference`1:.ctor (T,bool) [0x7ae3d8c580 - 0x7ae3d8c5d0 0x7ae3ddaec1]
    08-06 14:12:34.986 30817 30817 D Mono    : AOT: FOUND method System.WeakReference`1:Create (T,bool) [0x7ae3d8c4c0 - 0x7ae3d8c580 0x7ae3ddaebd]
    08-06 14:12:34.986 30817 30817 D Mono    : AOT: NOT FOUND: System.Runtime.InteropServices.GCHandle:Alloc (object,System.Runtime.InteropServices.GCHandleType).
    08-06 14:12:34.986 30817 30817 D Mono    : AOT: NOT FOUND: System.Runtime.InteropServices.GCHandle:Alloc (object,System.Runtime.InteropServices.GCHandleType).
    08-06 14:12:34.986 30817 30817 D Mono    : AOT: NOT FOUND: System.Runtime.InteropServices.GCHandle:.ctor (object,System.Runtime.InteropServices.GCHandleType).

Overall, seems promising, though.

[0]: store.google.com/us/product/pixel_5_specs?hl=en-US
[1]: dotnet/maui-samples@7144604/HelloAndroid
[2]: dotnet/maui-samples@7144604/HelloMaui
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Sep 1, 2021
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
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Sep 1, 2021
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
jonpryor pushed a commit that referenced this issue Sep 2, 2021
Fixes: #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>
@ghost ghost locked as resolved and limited conversation to collaborators Jun 2, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Area: App+Library Build Issues when building Library projects or Application projects.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant