Skip to content

Commit

Permalink
[One .NET] built-in Profiled AOT support
Browse files Browse the repository at this point in the history
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][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
  • Loading branch information
jonathanpeppers committed Sep 1, 2021
1 parent e9a4c9f commit b9faaf6
Show file tree
Hide file tree
Showing 6 changed files with 13 additions and 19 deletions.
1 change: 1 addition & 0 deletions build-tools/create-packs/Microsoft.Android.Sdk.proj
Expand Up @@ -76,6 +76,7 @@ core workload SDK packs imported by WorkloadManifest.targets.
<_PackageFiles Include="$(XamarinAndroidSourcePath)src\Xamarin.Android.Build.Tasks\Microsoft.Android.Sdk\Sdk\**" PackagePath="Sdk" />
<_PackageFiles Include="$(XamarinAndroidSourcePath)src\Microsoft.Android.Sdk.ILLink\PreserveLists\**" PackagePath="PreserveLists" />
<_PackageFiles Include="$(XamarinAndroidSourcePath)src\Xamarin.Android.Build.Tasks\Microsoft.Android.Sdk\targets\**" PackagePath="targets" />
<_PackageFiles Include="$(XamarinAndroidSourcePath)src\Xamarin.Android.Build.Tasks\dotnet.aotprofile" PackagePath="targets" />
<_PackageFiles Include="$(IntermediateOutputPath)UnixFilePermissions.xml" PackagePath="data" Condition=" '$(HostOS)' != 'Windows' " />
<None Include="$(MSBuildThisFileDirectory)SignList.xml" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
Expand Down
Expand Up @@ -69,11 +69,13 @@ They run in a context of an inner build with a single $(RuntimeIdentifier).
TempDirectory="$([MSBuild]::EnsureTrailingSlash($(_AotOutputDirectory)))%(FileName)"
AotArguments="$(_AotArguments),temp-path=$([System.IO.Path]::GetFullPath(%(_MonoAOTAssemblies.TempDirectory)))"
/>
<AndroidAotProfile Include="$(MSBuildThisFileDirectory)dotnet.aotprofile" Condition=" '$(AndroidEnableProfiledAot)' == 'true' and '$(AndroidUseDefaultAotProfile)' != 'false' " />
</ItemGroup>
<MakeDir Directories="$(IntermediateOutputPath)aot\;@(_MonoAOTAssemblies->'%(TempDirectory)')" />
<MonoAOTCompiler
Assemblies="@(_MonoAOTAssemblies)"
CompilerBinaryPath="$(_MonoAOTCompilerPath)"
AotProfilePath="@(AndroidAotProfile->'%(FullPath)')"
DisableParallelAot="$(_DisableParallelAot)"
LibraryFormat="So"
Mode="$(AndroidAotMode)"
Expand Down
Expand Up @@ -48,8 +48,8 @@ Copyright (C) 2019 Microsoft Corporation. All rights reserved.
DependsOnTargets="$(_BeginAotProfilingDependsOnTargets)">
</Target>
<Target Name="FinishAotProfiling"
DependsOnTargets="_ResolveSdks">
DependsOnTargets="_ResolveSdks;_ResolveMonoAndroidSdks">
<Exec Command="&quot;$(AdbToolPath)adb&quot; $(AdbTarget) forward tcp:$(AndroidAotProfilerPort) tcp:$(AndroidAotProfilerPort)" />
<Exec Command="&quot;$(MonoAndroidBinDirectory)aprofutil&quot; $(AProfUtilExtraOptions) -s -v -p $(AndroidAotProfilerPort) -o &quot;$(AndroidAotCustomProfilePath)&quot;" />
<Exec Command="&quot;$(AProfUtilToolPath)aprofutil&quot; $(AProfUtilExtraOptions) -s -v -p $(AndroidAotProfilerPort) -o &quot;$(AndroidAotCustomProfilePath)&quot;" />
</Target>
</Project>
Expand Up @@ -680,6 +680,12 @@ because xbuild doesn't support framework reference assemblies.
/>
</CreateProperty>

<CreateProperty Value="$(MonoAndroidBinDirectory)">
<Output TaskParameter="Value" PropertyName="AProfUtilToolPath"
Condition="'$(AProfUtilToolPath)' == ''"
/>
</CreateProperty>

<CreateProperty Value="--dex --no-strict">
<Output TaskParameter="Value" PropertyName="DxExtraArguments"
Condition="'$(DxExtraArguments)' == ''"
Expand Down
Binary file added src/Xamarin.Android.Build.Tasks/dotnet.aotprofile
Binary file not shown.
19 changes: 2 additions & 17 deletions src/monodroid/jni/monodroid-glue.cc
Expand Up @@ -1567,7 +1567,6 @@ MonodroidRuntime::set_trace_options (void)
mono_jit_set_trace_options (value.get ());
}

#if defined (NET6)
inline void
MonodroidRuntime::set_profile_options ()
{
Expand All @@ -1582,23 +1581,10 @@ MonodroidRuntime::set_profile_options ()
value.assign (prop_value);
}

#if defined (NET6)
// setenv(3) makes copies of its arguments
setenv ("DOTNET_DiagnosticPorts", value.get (), 1);
}
#else // def NET6
inline void
MonodroidRuntime::set_profile_options ()
{
// We want to avoid dynamic allocation, thus let’s create a buffer that can take both the property value and a
// path without allocation
dynamic_local_string<SENSIBLE_PATH_MAX + PROPERTY_VALUE_BUFFER_LEN> value;
{
dynamic_local_string<PROPERTY_VALUE_BUFFER_LEN> prop_value;
if (androidSystem.monodroid_get_system_property (Debug::DEBUG_MONO_PROFILE_PROPERTY, prop_value) == 0)
return;

value.assign (prop_value.get (), prop_value.length ());
}
#endif // def NET6

constexpr char OUTPUT_ARG[] = "output=";
constexpr size_t OUTPUT_ARG_LEN = sizeof(OUTPUT_ARG) - 1;
Expand Down Expand Up @@ -1673,7 +1659,6 @@ MonodroidRuntime::set_profile_options ()
log_warn (LOG_DEFAULT, "Initializing profiler with options: %s", value.get ());
debug.monodroid_profiler_load (androidSystem.get_runtime_libdir (), value.get (), output_path.get ());
}
#endif // ndef NET6

/*
Disable LLVM signal handlers.
Expand Down

0 comments on commit b9faaf6

Please sign in to comment.