dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.43k stars 4.76k forks source link

AOT optimization #99580

Closed DotNetNext closed 8 months ago

DotNetNext commented 8 months ago

AOT optimization 1.I referenced a dll, but the dll depends on another dll, so I installed only one dll, and the aot release failed(I only use the functionality of a DLL 。 Do not use dependent DLL functionality) 2.AOT requires perfect EMIT support, not through ReadyToRun, you can provide a DLL reference to publish, instead of checked ReadyToRun

MichalStrehovsky commented 8 months ago

Can you describe in more detail what this is about? "referenced a dll" -> what kind of DLL (native? managed?). "the aot release failed" -> how? is there an exception with a stack?

"AOT requires perfect EMIT support, not through ReadyToRun, you can provide a DLL reference to publish, instead of checked ReadyToRun" -> is this related to first point? what do you mean?

DotNetNext commented 8 months ago

Can you describe in more detail what this is about? "referenced a dll" -> what kind of DLL (native? managed?). "the aot release failed" -> how? is there an exception with a stack?

"AOT requires perfect EMIT support, not through ReadyToRun, you can provide a DLL reference to publish, instead of checked ReadyToRun" -> is this related to first point? what do you mean?


These two points are not related, they are two optimization directions

Let me write a DEMO for the first question

DotNetNext commented 8 months ago

AOT DEMO.zip

There are two folders in it.

The error folder can run but cannot be published ,

OK folder can be published, NUGET packages all the references

MichalStrehovsky commented 8 months ago

Can you reupload the ZIP? It cannot be downloaded and leads to a 404.

DotNetNext commented 8 months ago

Can you reupload the ZIP? It cannot be downloaded and leads to a 404.

Can download AOT DEMO.zip

DotNetNext commented 8 months ago

image

NCLnclNCL commented 8 months ago

ok

MichalStrehovsky commented 8 months ago

This is caused by your rd.xml. If you remove the rd.xml file the compilation succeeds. RD.XML files are unsupported.

The problem is that the nuget package you reference has incomplete dependencies (it's basically broken). By rooting it you cause it to hit codepaths within the compiler that are hard to recover from. The compiler generally tries to be resilient to junk input like this, but it's not 100% and rd.xml definitely makes things worse.

DotNetNext commented 8 months ago

This is caused by your rd.xml. If you remove the rd.xml file the compilation succeeds. RD.XML files are unsupported.

The problem is that the nuget package you reference has incomplete dependencies (it's basically broken). By rooting it you cause it to hit codepaths within the compiler that are hard to recover from. The compiler generally tries to be resilient to junk input like this, but it's not 100% and rd.xml definitely makes things worse.

rd.xml delete my program can not run, need rd.xml to support aot my program

jkotas commented 8 months ago

You should address the AOT warnings in your application and the references libraries instead: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/fixing-warnings . It is the only supported way to make your AOT compiled program work with confidence.

DotNetNext commented 8 months ago

You should address the AOT warnings in your application and the references libraries instead: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/fixing-warnings . It is the only supported way to make your AOT compiled program work with confidence.

I hope to support better in the future, AOT is not working very well at present

DotNetNext commented 8 months ago

The main ones are: publishing speed, EMIT, dependent publishing errors

jkotas commented 8 months ago

EMIT

If you application has a strong dependency on generating dynamic code at runtime via Reflection.Emit, native AOT is not the right technology to use for it. We have no plans to fixing that. Use regular CoreCLR w/ JIT instead.

DotNetNext commented 8 months ago

EMIT

If you application has a strong dependency on generating dynamic code at runtime via Reflection.Emit, native AOT is not the right technology to use for it. We have no plans to fixing that. Use regular CoreCLR w/ JIT instead.

My solution is to provide a DLL that simply references this DLL to solve the problem, which is nothing more than an intermediate conversion problem

DotNetNext commented 8 months ago

emit was a feature, and you just dropped it

huoyaoyuan commented 8 months ago

Emit is fundamentally disagreed with NativeAOT. NativeAOT is designed for environments that Emit or equivalents are forbidden, namely UWP and iOS.

There are alternatives like source generators, to implement features in more AOT-friendly way.

If you prefer, you can get in touch with me privately and I can explain more in Chinese.

DotNetNext commented 8 months ago

Emit is fundamentally disagreed with NativeAOT. NativeAOT is designed for environments that Emit or equivalents are forbidden, namely UWP and iOS.

There are alternatives like source generators, to implement features in more AOT-friendly way.

If you prefer, you can get in touch with me privately and I can explain more in Chinese.

These solutions are not as good as EMIT, Epression can replace a little, but there is no way to dynamically build classes, EMIT is the best,source generators should not be run time

其他方案不行,不能运行时创建类,目前EMIT能做到表达式树也做不到 ,重点是运行时创建

DotNetNext commented 8 months ago

If something is useful, it should be supported as much as possible, and give up the existing scheme, which will give many developers a headache, and there is no alternative

huoyaoyuan commented 8 months ago

dynamically build classes

This is strictly not possible for AOT environment. Ordinal CLR is a must. The NativeAOT type system doesn't support this. AOT environments don't allow this either.

DotNetNext commented 8 months ago

dynamically build classes

This is strictly not possible for AOT environment. Ordinal CLR is a must. The NativeAOT type system doesn't support this. AOT environments don't allow this either.

I know it's hard, but I think it's possible 。We are to solve problems, not to say impossible, there is no impossible。

jkotas commented 8 months ago

I know it's hard, but I think it's possible

If we were to add dynamic code generation (emit) to native AOT, we would end up with something that looks very much like regular CoreCLR w/ JIT.

Where do you see the difference between regular CoreCLR w/ JIT and the hypothetical native AOT w/ dynamic code generation?

MichalPetryka commented 8 months ago

If we were to add dynamic code generation (emit) to native AOT, we would end up with something that looks very much like regular CoreCLR w/ JIT.

Worth noting that there was an experiment with Mono Interpreter for it.

am11 commented 8 months ago

It was mentioned previously in https://github.com/dotnet/runtime/issues/95841#issuecomment-1849068553, but OP is adamant to have it first-class, which seems likely to happen in the future (based on cost/benefit/# of people asking etc.) but clearly not the priority of the project at this very second. :)

DotNetNext commented 8 months ago

I know it's hard, but I think it's possible

If we were to add dynamic code generation (emit) to native AOT, we would end up with something that looks very much like regular CoreCLR w/ JIT.

Where do you see the difference between regular CoreCLR w/ JIT and the hypothetical native AOT w/ dynamic code generation?

For example, add a tool to monitor the EMIT conversion part required by the current program, generate the EMIT replacement DLL required for the current program.Users download this DLL, reference it and publish it as AOT

DotNetNext commented 8 months ago

Users will not use much of the EMIT part, only a little conversion is required

DotNetNext commented 8 months ago

There are so many packages using EMIT on the market that it would be perfect to support it

jkotas commented 8 months ago

For example, add a tool to monitor the EMIT conversion part required by the current program, generate the EMIT replacement DLL required for the current program.Users download this DLL, reference it and publish it as AOT

This approach would violate our design principles for runtime form factors - look for "Deliver predictable experience".

We do not mind if somebody out there builds a solution like the one you are suggesting. It is not going to be included it in the .NET product itself. We believe that the predictable experience is more important.

jkotas commented 8 months ago

There are so many packages using EMIT on the market that it would be perfect to support it

These packages are supported by regular CoreCLR w/ JIT. If you depend on these packages, do not use native AOT. It is as simple as that.

huoyaoyuan commented 8 months ago

generate the EMIT replacement DLL required for the current program

EMIT can do much more than that. It can generate code based on user input, which is often considered as security risk. The coverage of EMIT paths may not be exhaustive either.

If the generated code can be determined by the application code only, it should be theoretically possible to replace with source generator. That our current suggestion.

DotNetNext commented 8 months ago

There are so many packages using EMIT on the market that it would be perfect to support it

These packages are supported by regular CoreCLR w/ JIT. If you depend on these packages, do not use native AOT. It is as simple as that.

I want to do high-end features, there is no way to use AOT, recently engaged in a dynamic API creation project, directly JS to create C# WEB API. I think this type of project is definitely a big trend in the future, and it's a regret not to support AOT

DotNetNext commented 8 months ago

There are so many packages using EMIT on the market that it would be perfect to support it

These packages are supported by regular CoreCLR w/ JIT. If you depend on these packages, do not use native AOT. It is as simple as that.

Just like AI, if AI can't evolve on its own, then it's just a machine. Language is the same, want to achieve this self-evolution of the function, must be supported at the bottom

DotNetNext commented 8 months ago

source generator

source generator

The source generator is weak and useless. Is to help me write him less a system.io.file.create, nothing useful

MichalStrehovsky commented 8 months ago

There are so many packages using EMIT on the market that it would be perfect to support it

These packages are supported by regular CoreCLR w/ JIT. If you depend on these packages, do not use native AOT. It is as simple as that.

Just like AI, if AI can't evolve on its own, then it's just a machine. Language is the same, want to achieve this self-evolution of the function, must be supported at the bottom

AOT is not an "evolution" of the JIT form factor. We have no plans to replace JIT with AOT for .NET.

AOT is specifically for the use cases and scenarios listed in the form factors document linked above. In the past, people who had such requirements often had to rewrite their app in a non-.NET language. Now it's possible to achieve their goals without a rewrite in a different language. But some things might need to still be rewritten using source generators, new high-performance reflection APIs, etc. If you want AOT, you can't get Emit functionality even if you go outside the .NET ecosystem (no emit in Go/Rust/Swift/C++/...). It's just fundamentally incompatible.

If your use case falls into the category that native AOT targets and you actually need AOT form factor, you'll need to make changes. We don't have plans to be drop-in compatible. Native AOT makes choices and tradeoffs to achieve startup/size/working set goals that are not compatible with dynamic code generation.

DotNetNext commented 8 months ago

There are so many packages using EMIT on the market that it would be perfect to support it

These packages are supported by regular CoreCLR w/ JIT. If you depend on these packages, do not use native AOT. It is as simple as that.

Just like AI, if AI can't evolve on its own, then it's just a machine. Language is the same, want to achieve this self-evolution of the function, must be supported at the bottom

AOT is not an "evolution" of the JIT form factor. We have no plans to replace JIT with AOT for .NET.

AOT is specifically for the use cases and scenarios listed in the form factors document linked above. In the past, people who had such requirements often had to rewrite their app in a non-.NET language. Now it's possible to achieve their goals without a rewrite in a different language. But some things might need to still be rewritten using source generators, new high-performance reflection APIs, etc. If you want AOT, you can't get Emit functionality even if you go outside the .NET ecosystem (no emit in Go/Rust/Swift/C++/...). It's just fundamentally incompatible.

If your use case falls into the category that native AOT targets and you actually need AOT form factor, you'll need to make changes. We don't have plans to be drop-in compatible. Native AOT makes choices and tradeoffs to achieve startup/size/working set goals that are not compatible with dynamic code generation.

EMIT you can not support, the release error, your compatibility is better? This can always be achieved, rd.xml after the release of missing DLL is not good release

DotNetNext commented 8 months ago

There are so many packages using EMIT on the market that it would be perfect to support it

These packages are supported by regular CoreCLR w/ JIT. If you depend on these packages, do not use native AOT. It is as simple as that.

Just like AI, if AI can't evolve on its own, then it's just a machine. Language is the same, want to achieve this self-evolution of the function, must be supported at the bottom

AOT is not an "evolution" of the JIT form factor. We have no plans to replace JIT with AOT for .NET.

AOT is specifically for the use cases and scenarios listed in the form factors document linked above. In the past, people who had such requirements often had to rewrite their app in a non-.NET language. Now it's possible to achieve their goals without a rewrite in a different language. But some things might need to still be rewritten using source generators, new high-performance reflection APIs, etc. If you want AOT, you can't get Emit functionality even if you go outside the .NET ecosystem (no emit in Go/Rust/Swift/C++/...). It's just fundamentally incompatible.

If your use case falls into the category that native AOT targets and you actually need AOT form factor, you'll need to make changes. We don't have plans to be drop-in compatible. Native AOT makes choices and tradeoffs to achieve startup/size/working set goals that are not compatible with dynamic code generation.

Now I have to package all DLLS with NUGET to publish AOT, even if I don't use DLLS

huoyaoyuan commented 8 months ago

EMIT you can not support, the release error, your compatibility is better? This can always be achieved, rd.xml after the release of missing DLL is not good release

Those environments are purposefully banning dynamic code emitting. Workarounds like scripting languages are invalid indeed.

Compatibility is counted in two directions: for application code and for platform. CLR was made compatible for Unix platforms by splitting Windows-only features to be optional. There's just no way to use Windows-only features on Unix platforms without heavy emulation. So does dynamic features on AOT-only platforms.

The source generator is weak and useless. Is to help me write him less a system.io.file.create, nothing useful

The famous users of Emit like System.Text.Json are adopting source generators, to replace reflection and dynamic methods.

Now I have to package all DLLS with NUGET to publish AOT, even if I don't use DLLS

I do not know what this mean. AOT has no relationship with NuGet. They are totally different layers of things.


I think it's better to ask some more questions:

DotNetNext commented 8 months ago

EMIT you can not support, the release error, your compatibility is better? This can always be achieved, rd.xml after the release of missing DLL is not good release

Those environments are purposefully banning dynamic code emitting. Workarounds like scripting languages are invalid indeed.

Compatibility is counted in two directions: for application code and for platform. CLR was made compatible for Unix platforms by splitting Windows-only features to be optional. There's just no way to use Windows-only features on Unix platforms without heavy emulation. So does dynamic features on AOT-only platforms.

The source generator is weak and useless. Is to help me write him less a system.io.file.create, nothing useful

The famous users of Emit like System.Text.Json are adopting source generators, to replace reflection and dynamic methods.

Now I have to package all DLLS with NUGET to publish AOT, even if I don't use DLLS

I do not know what this mean. AOT has no relationship with NuGet. They are totally different layers of things.

I think it's better to ask some more questions:

  • Why do you need NativeAOT in the first place? Do you need to run on iOS-like platforms or something? Does your code need to be loadable native library from native code?
  • What type of library that uses dynamic feature are you using? Are you actually using such code path?

The second problem looks at the above record, mainly after rd.xml, all the DLLS that rely on this DLL must be referenced before they can be published, even if they are not needed

DotNetNext commented 8 months ago
  • Why do you need NativeAOT in the first place? Do you need to run on iOS-like platforms or something? Does your code need to be loadable native library from native code?
  • What type of library that uses dynamic feature are you using? Are you actually using such code path?

I'm open source, I make things for others to use, so others want to use AOT that can only give up some features You tell me not to support, then I can only other users say not to support.

huoyaoyuan commented 8 months ago

so others want to use AOT that can only give up some features You tell me not to support

Not all features are orthogonal. They just have no (direct) way to work together. For example you can't use a WPF component on non-Windows platform. It's just the same that you can't use dynamic code on non-JIT platform.

The second problem looks at the above record, mainly after rd.xml, all the DLLS that rely on this DLL must be referenced before they can be published, even if they are not needed

rd.xml is outdated. The recommended approach today is using dynamic dependency annotation. Then the AOT compiler can correctly figure out what part of a library will be used.

DotNetNext commented 8 months ago

so others want to use AOT that can only give up some features You tell me not to support

Not all features are orthogonal. They just have no (direct) way to work together. For example you can't use a WPF component on non-Windows platform. It's just the same that you can't use dynamic code on non-JIT platform.

The second problem looks at the above record, mainly after rd.xml, all the DLLS that rely on this DLL must be referenced before they can be published, even if they are not needed

rd.xml is outdated. The recommended approach today is using dynamic dependency annotation. Then the AOT compiler can correctly figure out what part of a library will be used.

Is there a tutorial on not using XML?

jkotas commented 8 months ago

You tell me not to support, then I can only other users say not to support.

It is a fine answer to give if your package is fundamentally incompatible with native AOT. For example, Newtonsoft.Json that is the most popular nuget package have done that: https://github.com/JamesNK/Newtonsoft.Json/issues/2732

Is there a tutorial on not using XML?

This blog post is a good introduction: https://devblogs.microsoft.com/dotnet/creating-aot-compatible-libraries/

DotNetNext commented 8 months ago

You tell me not to support, then I can only other users say not to support.

It is a fine answer to give if your package is fundamentally incompatible with native AOT. For example, Newtonsoft.Json that is the most popular nuget package have done that: JamesNK/Newtonsoft.Json#2732

Is there a tutorial on not using XML?

This blog post is a good introduction: https://devblogs.microsoft.com/dotnet/creating-aot-compatible-libraries/

error : System.ArgumentNullException: Value cannot be null. (Parameter 'type') The program can't run away without publishing rd.xml

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net8.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
        <PublishAot>true</PublishAot>
<IsAotCompatible Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0'))">true</IsAotCompatible>
    </PropertyGroup>

    <ItemGroup>
      <PackageReference Include="SqlSugarCore" Version="5.1.4.135" />
    </ItemGroup>

</Project>
DotNetNext commented 8 months ago
//this is OK
<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net8.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
        <PublishAot>true</PublishAot>
    </PropertyGroup>

    <ItemGroup>
      <None Remove="rd.xml" />
    </ItemGroup>

    <ItemGroup>
      <Content Include="rd.xml">
        <CopyToOutputDirectory>Always</CopyToOutputDirectory>
      </Content>
    </ItemGroup>

    <ItemGroup>
      <PackageReference Include="SqlSugarCore" Version="5.1.4.135" />
    </ItemGroup>

    <ItemGroup>
        <RdXmlFile Include="rd.xml" />
    </ItemGroup>

</Project>
//rd.xml
<Directives>
    <Application>
        <Assembly Name="orm_sqlsugar"  Dynamic="Required All">
        </Assembly>
        <Assembly Name="SqlSugar"  Dynamic="Required All">
        </Assembly>
    </Application>
</Directives>