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

NativeAOT compilation support #19520

Open
kant2002 opened this issue Jul 15, 2021 · 4 comments
Open

NativeAOT compilation support #19520

kant2002 opened this issue Jul 15, 2021 · 4 comments

Comments

@kant2002
Copy link

Motivation

My motivation is to set experiment for evaluation limits of NativeAOT compilation for .NET. I have hopes and expectations that performance overall should improve a bit. I can only speculate about effects. Even if experiment fails to reach meaningful improvements, codebase should be in a state which would be more friendly for R2R and better suited for ILTrimming in case if somebody needed.

Proposed solution

I would like to test interest of core team in this experiment. Eventually this is for them to decide if this helpful or not. Would be extremely good to have one core team member to sponsor this work (i.e. look over my shoulders and help understanding codebase, also allocate some cycles for that).

If received positively, I can start contributing. I hope minor changes lands main repo, and if some substantial changes arise, they can live on branch. That's up to further discussion.

Side effects

Some changes I expect to be cosmetic, like Enum.GetValues(typeof(T)) => Enum.GetValues<T>(), other may be slightly more involved. I expect if localization done using ResourceManager then maybe some issues can appear when targeting smaller size. My goal is to produce executable of smaller size, so I expect eventually disable reflection, and as such modding API would not work. That require provide alternative way how load mods into executable which is friendly for static compilation. Again, if this appear too radical of a change it would be better left that on a branch and discuss until agreement would be reached (or not).

Alternatives

Technically I do not consider alternatives to NativeAOT, since that's the point. Other options I'm flexible, since I want that experiment to succeed.

@anvilvapre
Copy link
Contributor

I believe mono allows you to compile a mono application into a shared library/compiled code. Dotnet may also support this. Is this what you mean? Why would it require rewriting parts of the code?

This solution could be marginally faster when loading. But once dotnet or mono have just in time compiled IL to native instructions I don't expect a huge performance improvement. This because the compiled and JIT code will mostly look the same.

No using reflection and not using generics will require a full rewrite of the game engine. You might as well re implement it in c++ or rust then. Will be a big project.

@kant2002
Copy link
Author

I believe mono allows you to compile a mono application into a shared library/compiled code. Dotnet may also support this. Is this what you mean? Why would it require rewriting parts of the code?

  • Honestly I want use NativeAOT just because that would be good example that NativeAOT works.
  • I do not expect rewriting code. I want that part to be close to zero. If applying NativeAOT require large re-engeneering I would consider experiment fails and NativeAOT not suited.

This solution could be marginally faster when loading. But once dotnet or mono have just in time compiled IL to native instructions I don't expect a huge performance improvement. This because the compiled and JIT code will mostly look the same.

I agree. I may speculate that startup time important for standalone servers, but again that has to be measured. I prefer that members of this project set measurement goals and what to measure. That way I would not measure something not important.

No using reflection and not using generics will require a full rewrite of the game engine. You might as well re implement it in c++ or rust then. Will be a big project.

I probably go too deep in technicalities when attempt to explain scope. Ignore what I wrote later, if its too distracting. My modus operandi would be have least amount changes to this project. Now to technicalities.

  • Reflection-free mode is mode which is technical demo, and core NativeAOT actively discourage me from using it, because it is too limiting. This is very aggressive mode where reflection is severely crippling. I personally think that single mod can be run in this mode too,
  • Generics 99% working, even in aggressive mode, until you start having recursion in generics. It may cause a problem. Until that's the case I do not expect any problem with that.

Some things like Assembly.Load not working in NativeAOT, and never will, so it require to have separate projects which package single mod and platform into the single exe file. I do not see a workaround for that. That's extremely fortunate.

Again, I expect changes to be trivial in nature, and any re-engineering mean experiment is busted.

@abcdefg30
Copy link
Member

Hi. Unfortunately I don't think removing all reflection and assembly loading is compatible with the way OpenRA is meant to be used for mods, so I doubt we can take such changes directly into the main branch. I don't see anything in the way of a forked demo project though. As measure it might be enough to simply measure the start-up time used to get into the shellmap (menu background).

P.S. If you want to have a chat you can join our Discord server (https://discord.openra.net) where most of the core devs are available.

@kant2002
Copy link
Author

This is initial concept. https://github.com/kant2002/OpenRA/tree/nativeaot
This is basic compilation without too much thoughts put into scripting and other areas. I try to limit amount of changes without too much refactoring.

I add 2 sample applications

  1. OpenRA.Server.D2k This is server for Dune 2000
  2. OpenRA.Launcher.D2k This is launcher for Dune 2000

Both applications do not allow changing mods during runtime. That's expected and nothing I can do about that. Assembly.Load does not supported.

Publishing steps

For publishing OpenRA.Server.D2k

cd OpenRA.Server.D2k
dotnet publish -c Release -r win-x64

then run using

bin\win-x64\publish\OpenRA.Server.D2k.exe Engine.EngineDir="..\..\..\" Game.Mod=d2k

For publishing OpenRA.Launcher.D2k

cd OpenRA.Launcher.D2k
dotnet publish -c Release -r win-x64

then run using

bin\win-x64\publish\OpenRA.exe Engine.EngineDir="..\..\..\" Game.Mod=d2k

I did not test performance, just make it compile. Subjectively startup time for server become noticeable faster, but I need instrument things to measure properly. Maybe that's related to my computer.

Application seems to be not that much affected.

Sizes of application become slightly bigger then I expected- 96Mb both. That's indirectly indicate on tight coupling of code, but I will try take a look to understand what consuming space.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants