This issue tracks work items required for the AOT effort for WebAssembly
Once I have a few backports done, I'm going to pick up Get the AOT compiler compiling + linking sample app. Should I make an issue for it or discuss it here?
@alexanderkyte That one I have a fix on my local branch: https://github.com/kumpera/mono/commit/9295d95b8b1c3ae2a13daed21aadc1e691e8bf80
Tomorrow I'll extract the ready bits from that branch into a PR.
PR #10266 gets us to the point were we crash when executing managed code due to conflicting function pointer types.
Zoltan has a branch in (https://github.com/vargaz/mono/commits/wasm-changes) with a bunch of changes, I plan to pick and merge them once the previous PR goes in.
That branch raised one interesting issue. Do we want to have a single runtime for interp/aot or not?
My concern is that emscripten documents C++ exceptions as experience in size&perf. We should validate that claim with our workload and before going either way.
latest branch: https://github.com/kumpera/mono/tree/wasm-llvm
Current status:
Kyte on the code_start/end issue
Me trying to get test_0_return working.
Found the following issues so far:
Curious: I haven't seen many news on mono-wasm AOT lately. From all I read many communities are eagerly awaiting progress (as myself) on the AOT compilation.
Is this still a project actively pursued? If so, are there any milestones or is there any release schedule?
Thanks in advance
Yes, work is being done on AOT support, it is somewhat usable in mono master.
There are 2 main problems currently:
I'd say much more important is size than compilation speed.
@vargaz thanks for your feedback and for updating the task list above.
Since you mentioned 2 main problems: which tasks on the list would reflect those 2 main problems?
If that helps, I'm having a out-of-mono running PoC here: https://github.com/nventive/Uno.Wasm.Bootstrap/tree/master/src/Uno.Wasm.AotTests, with a running app here: https://unobootstrap-staging.azurewebsites.net.
It shows the progress in performance, as well as the binary size for a small payload, as well as the generation speed (see the linux builds here: https://uno-platform.visualstudio.com/Uno%20Platform/_build?definitionId=34&_a=summary)
@jeromelaban thanks. We looked into but found this would require a Linux subsystem which would derail our efforts at this time. Hence, we'll leave that subject for now and still are eagerly waiting on mono-wasm AOT support on Windows.
How do the file sizes compare to the whole mono runtime precompiled to wasm?
Compile times probably aren't super important since I assume AOT would be a "release mode" thing. Webpack can take a really long time too.
@legistek The sample above is about 7MB uncompressed without the emscripten fixes. With the future fixes, the file goes down to about 3MB.
With larger codebases (e.g. https://playground.platform.uno), it's very easy to get to 90MB of wasm. What the emscripten fixes will provide for those remains to be seen.
Thanks @jeromelaban. Do you have any guesses on why adding non-trivial code blows up the file sizes?
I mean, I would understand if there would be some 'fixed overhead' independent of 'lines of code'. However, I'm surprised that adding code increased the build size that drastically.
System.Xml is a large contributor to this, though I'm not sure of the details of what makes the resulting wasm file this large (aside from the indexes wasm section being extremely large). Referencing Json.NET makes the issue even bigger, as it references large parts of System.Data.
The related PR in emscripten is this one: https://github.com/kripken/emscripten-fastcomp/pull/243
I know it's not entirely apples-to-apples, but I don't understand why pre-compiling would result in assembly sizes over 10 times larger than the entire mono runtime compiled to WASM. There must be a ton of unnecessary stuff there.
Most definitely, @vargaz may have more insights on that.
Couple of reasons for the size issues:
AOT support is still under development, so hopefully file sizes will go down in the future. We are also experimenting with mixed aot+interpreter mode.
Thanks @vargaz
We are also experimenting with mixed aot+interpreter mode.
Does this mean that the performance of the 'interpreter mode' would be improved as well? Possibly to a point where it would become 'comparable' to the expected performance if the AOT mode (close to .NET 'native')?
FYI As of our latest tests (Q2 2018) the interpreter mode was >= 100 slower than .NET 'native'.
@DierkDroth currently the performance difference for the raytracer above is about 50x on chrome, 30x on Firefox. The type of CPU is very important as well for the interpreter (i3 vs i7, specifically)
Thanks @jeromelaban
You mean when comparing wasm interpreter to wasm AOT or wasm interpreter to .NET 'native'?
Right, I missed that distinction, comparing wasm AOT and wasm interpreter.
Thanks for clarification. Curious have you compared to .NET 'native' as well by chance?
Any idea when a mono build will be released with AOT enabled ? For end user Alpha/Beta testing ?
Or if the current source tree is worth building for very early testing ?
I've grab the latest WASM build from:
https://github.com/mono/mono/blob/master/sdks/wasm/docs/getting-started/obtain-wasm-sdk.md#latest-successful-build
Created a simple file called sample.cs like the following (ignore extra using's left in from more code):
using System;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using WebAssembly;
using WebAssembly.Net.Http.HttpClient;
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World..");
}
}
Set environment var to WASM (ie. WASM_SDK=c:\mono-wasm-a92701bd18b\ )
mcs -r:%WASM_SDK%/wasm-bcl/wasm/System.Net.Http.dll -r:%WASM_SDK%/framework/WebAssembly.Bindings.dll -r:%WASM_SDK%/framework/WebAssembly.Net.Http.dll sample.cs -out:sample.exe
mono %WASM_SDK%/packager.exe --copy=always --out=./publish --asset=./sample.html --asset=server.py sample.exe
All good so far. No errors..
Change into publish..
Then python server.py
All good again.. Browse to. http://localhost:8000/sample.html and console gives:
Loaded: sample.exe
mono.js:formatted:7588 Loaded: WebAssembly.Bindings.dll
mono.js:formatted:7588 Loaded: mscorlib.dll
mono.js:formatted:7593 initializing mono runtime
mono.js:formatted:7513 >>mono_wasm_runtime_ready
runtime.js:11 Uncaught (in promise) ReferenceError: App is not defined
at runtime.js:11
at mono.js:formatted:7609
Line 11 in runtime.js is:
App.init ();
@CastleSoft can you try the sample? https://github.com/mono/mono/tree/master/sdks/wasm/docs/getting-started
I have followed https://github.com/mono/mono/tree/master/sdks/wasm/docs/getting-started and got mono working in interpreted mode.
How can I try mono AOT? any docs?
@DierkDroth @jeromelaban According to performance, we should moderate the expectation on mono perf directly since wasm seems to be slower than native code yet.
https://arxiv.org/abs/1901.09056?utm_medium=email&utm_source=topic+optin&utm_campaign=awareness&utm_content=20190209+programming+nl&mkt_tok=eyJpIjoiTVRSaVltUmtOV0kwWWpZeCIsInQiOiIwMEVQMEVEYmNOeE5VQ1wvVTRoWTg5MlpCenpDelVEb3BmMlNjYkszNFJ6T1UyOEQwdzBxdGVXM2NrRmR4aFRtc3BOYytJQVE0WUFObFc3ZE5HdFhkd1BmQXpVTE5YMVdadDVsWG5UU201UkloQVwvTmlMd25SYUs0ek9DQVl4d25iIn0%3D
@DierkDroth @jeromelaban According to performance, we should moderate the expectation on mono perf directly since wasm seems to be slower than native code yet.
@karoldeland That would still be multiple times faster than the current interpreter implementation.
https://github.com/stefan-schweiger/bakkBenchmark
But you should always expect a certain performance overhead with WebAssembly, and I'm sure mono will also add a bit to that. Even under ideal circumstances I wouldn't expect to get anything better than a 3-5x slowdown with AOT for most code when compared to native code (although I haven't run any performance tests myself with AOT as of now).
@stefan-schweiger you're right. Still lot of space for improvement.
I'm sure you're all sick of being asked this, so sorry. :) But what's the ETA on when we might be able to try AOT compiled C# -> Webassembly using a Windows-friendly toolchain?
Here is a demo of Steve at NDC London 2019. He is showing off the AOT, https://youtu.be/Qe8UW5543-s?t=3167
He's showing off AOT generally but I don't think he's showing off .NET compiled AOT - let alone compiled through a Windows toolchain. I hope we're not going to be expected to use mingw just to develop Blazor apps.
So I see that Milestone 1 is completed. Any way to test AoT on Blazor/windows?
@emilm here's some steps I described there, It's not completely Windows based, but it's running under WSL. It allows to experiment with plain mono AOT.
Windows toolchain isn't even in the roadmap above. Isn't Microsoft sponsoring this? Makes no sense.
@jeromelaban Thanks!
@legistek Maybe it's implied, since MS is sponsoring Mono. It would be nuts not to have Windows toolchain for this. MS should put full force behind AoT compilation and get it out there, because it will be a major success I think.
I have to confess, that the technical details as per the milestone lists are above my head, but it definitely is required to have a tool chain option which is 100% MS Windows (and is not dependent on WSL or the like) asap.
it definitely is required to have a tool chain option which is 100% MS Windows (and is not dependent on WSL or the like) asap.
ASAP and Blazor don’t really mix at this point.
ASAP and Blazor don’t really mix at this point.
Indeed, and one of the things that's holding it back is the lack of a viable AOT option. No one really knows how far Blazor can go as a client side tech until we know the performance with AOT. (As a server side tech, it's doing great).
I wouldn't be concerned with AOT speed. It should work fast, why not. More problematic is the binaries size IMO.
Yes both speed and size are important. And no one's going to put serious investment into Blazor until we can actually see how it's going to perform in both regards. And the lack of an AOT option is holding that back right now.
Also, back to Windows toolchain, I'm noting the deafening silence on this point from anyone officially involved with this project.
I guess it's because most people don't care whether the toolchain is working on Windows or not. I myself would be glad for any AOT compilation toolchain to start working with.
I guess it's because most people don't care whether the toolchain is working on Windows or not.
How about most people who are interested in Blazor? Blazor will be a failure if it can't be developed in Windows. You may not care about that, but plenty of people do - and more importantly Microsoft should.
@m5x people do care, but for now it seems that it's more important to make AOT and mixed modes work (it's getting a lot more stable at runtime lately thanks to @vargaz).
FWIW, there are already Windows binaries produced by the CI, but if anyone wants to document how it works (haven't made research on this yet, as my focus was on getting AOT working to evaluate perf and linux is still the only easy option to do so), it'll make this Windows support move forward faster 😉
Yes, that's what I was trying to say. It's more important to make it work (on any platform) at this point. Adding platforms is the next step. People who can work with Windows only are here too early.
Too early? You've got to be kidding me. WASM was standardized over two years ago and Blazor was announced over one year ago. Blazor development has gone very fast, but the pace of this AOT part been glacial. If MS is as serious about Blazor as it says it should put real resources behind this and get moving on this so that people can actually start making real applications. Otherwise we are going to start to think it's vaporware and move on.
@legistek you've noticed that a lot of work is done lately on the interpreter (and mixed mode by extension), which is the segway to make wasm FullAOT viable (because of its size characteristics). AOT's integration in Blazor may be slow, but AOT work in mono definitely is not. It's also advanced enough to be able to find issues like this one.
Well, again, my biggest concern is not even the pace but the fact that a Windows-based WASM AOT option is not even in the roadmap. That means that building Blazor apps with WASM AOT is a very long way away, if ever.
A windows AOT toolchain is definitely on the roadmap we've simply been focused on AOT and AOT+Interpreter functionality up to now. This issue should not be considered a complete or up to date planning document.
Thanks @lewing that is reassuring.
So both llvm and Emscripten can be run on Windows. What's actually blocking this from working in windows right now?
Sorry I'm a little behind on these particular techs. Proud Microsoft devotee here and always will be.
Sorry if I'm off-topic. I downloaded WASM SDK from https://jenkins.mono-project.com/job/test-mono-mainline-wasm/label=ubuntu-1804-amd64/lastSuccessfulBuild/Azure/.
The tool packer.exe from the package as option --aot. That made me feeling happy that AOT is already out. However I don't see any difference between the packages generated with --aot and without.
So what's that good for, is it just a placeholder for future support, or would it maybe work if I'd use the Linux/WSL version?
Did you check the AOT section at https://github.com/mono/mono/blob/master/sdks/wasm/docs/packager.md? It seems to explain how to use it with Emscripten.
Hello @chucker, I actually found that page only after I posted here. However even when I set --emscripten-sdkdir and --mono-sdkdir I don't see any difference in the resulting packages.
For me it was not enough to follow the description in the packager.md file to build with the --aot option. For example it doesn't mention to run ninja. I've found the missing steps in the Makefile and packager.cs source files.
I've created a description how I've managed to do it. Hope it helps somebody.
https://balintpogatsa.github.io/2019/05/05/webassembly-mono-aot-example.html
After applying @BalintPogatsa's guide and making the compilation under WSL and making it possible to run from Visual Studio, I'm running to following problems:
1>EXEC : error : asm2wasm seeing an invalid argument type at index 1 (this will not validate) in call from $_file_write to $_lseek (this is likely due to undefined behavior in C, like defining a function one way and calling it in another, which is important to fix)
1>EXEC : error : asm2wasm seeing an invalid argument type at index 1 (this will not validate) in call from $_file_setendoffile to $_lseek (this is likely due to undefined behavior in C, like defining a function one way and calling it in another, which is important to fix)
1>EXEC : error : asm2wasm seeing an invalid argument type at index 1 (this will not validate) in call from $_file_setendoffile to $_ftruncate (this is likely due to undefined behavior in C, like defining a function one way and calling it in another, which is important to fix)
1>EXEC : error : asm2wasm seeing an invalid argument type at index 1 (this will not validate) in call from $_binary_protocol_open_file to $_ftruncate (this is likely due to undefined behavior in C, like defining a function one way and calling it in another, which is important to fix)
1>EXEC : error : asm2wasm seeing an invalid argument type at index 1 (this will not validate) in call from $_mono_file_map_fileio to $_lseek (this is likely due to undefined behavior in C, like defining a function one way and calling it in another, which is important to fix)
1>EXEC : error : asm2wasm seeing an invalid argument type at index 1 (this will not validate) in call from $_mono_file_map_fileio to $_lseek (this is likely due to undefined behavior in C, like defining a function one way and calling it in another, which is important to fix)
1>EXEC : error : asm2wasm seeing an invalid argument type at index 1 (this will not validate) in call from $_mono_file_map_fileio to $_lseek (this is likely due to undefined behavior in C, like defining a function one way and calling it in another, which is important to fix)
1>EXEC : error : asm2wasm seeing an invalid argument type at index 5 (this will not validate) in call from $_mono_valloc to $___mmap (this is likely due to undefined behavior in C, like defining a function one way and calling it in another, which is important to fix)
1>EXEC : error : asm2wasm seeing an invalid argument type at index 5 (this will not validate) in call from $_mono_valloc to $___mmap (this is likely due to undefined behavior in C, like defining a function one way and calling it in another, which is important to fix)
1>EXEC : error : asm2wasm seeing an invalid argument type at index 1 (this will not validate) in call from $_mono_w32file_create to $_posix_fadvise (this is likely due to undefined behavior in C, like defining a function one way and calling it in another, which is important to fix)
1>EXEC : error : asm2wasm seeing an invalid argument type at index 2 (this will not validate) in call from $_mono_w32file_create to $_posix_fadvise (this is likely due to undefined behavior in C, like defining a function one way and calling it in another, which is important to fix)
1>EXEC : error : asm2wasm seeing an invalid argument type at index 1 (this will not validate) in call from $_mono_w32file_create to $_posix_fadvise (this is likely due to undefined behavior in C, like defining a function one way and calling it in another, which is important to fix)
1>EXEC : error : asm2wasm seeing an invalid argument type at index 2 (this will not validate) in call from $_mono_w32file_create to $_posix_fadvise (this is likely due to undefined behavior in C, like defining a function one way and calling it in another, which is important to fix)
1>EXEC : error : asm2wasm seeing an invalid argument type at index 1 (this will not validate) in call from $_file_seek to $_lseek (this is likely due to undefined behavior in C, like defining a function one way and calling it in another, which is important to fix)
1>EXEC : error : asm2wasm seeing an invalid argument type at index 5 (this will not validate) in call from $_mono_file_map to $___mmap (this is likely due to undefined behavior in C, like defining a function one way and calling it in another, which is important to fix)
1>EXEC : error : asm2wasm seeing an invalid argument type at index 5 (this will not validate) in call from $_mono_file_map to $___mmap (this is likely due to undefined behavior in C, like defining a function one way and calling it in another, which is important to fix)
and
1>shared : error : '/mnt/c/Users/Honza/emsdk/clang/e1.38.31_64bit/binaryen/bin/asm2wasm /mnt/d/Users/Honza/Documents/Programy/WASM.net/WASM.net/bin/Release/wasm/mono.temp.asm.js --total-memory=134217728 --trap-mode=clamp -Oz --mem-init=/mnt/d/Users/Honza/Documents/Programy/WASM.net/WASM.net/bin/Release/wasm/mono.js.mem --mem-base=1024 --table-max=-1 --wasm-only -g -o /mnt/d/Users/Honza/Documents/Programy/WASM.net/WASM.net/bin/Release/wasm/mono.wast -S --mvp-features' failed (-6)
It's also worth noting that I had to replace cscwith mcsin build.ninjagenerated by packer.exe.
Attached project
WASM.net.zip
I am seeing the same issue with 1.38.31 "asm2wasm seeing an invalid argument"
@DzonnyDZ @roozbehid I was having the same issue in an entirely different project right after updating from Emscripten 1.38.30 to 1.38.31.
I suspect that the signature of some POSIX functions (see the logs: lseek, ftruncate, mmap, etc.) has changed in the latest update. If so, that would explain why libraries compiled with older Emscripten versions fail to link with the latest one.
So, as a first step, try to clone the repository again and double-check that it's not linking on your machines against anything outside the repository that might have been compiled with an older emcc. Then build, and see if that fixes your problems. :-)
PS: I'm completely unrelated to mono/mono. While searching for solutions I just found your comments.
Yes, the upgrade doesn’t trigger a rebuild of everything it needs to. You’ll need to clean your repository.
Well in my case I had a pipeline in appveyor so everything should've been clean.
I reverted to 1.38.28 which is still successful, but I was also using a 2 month older version of mono.
With so much development going on with WebAssembly, I just don't know when is a good time to upgrade my mono :D
For me it was not enough to follow the description in the packager.md file to build with the
--aotoption. For example it doesn't mention to run ninja. I've found the missing steps in theMakefileandpackager.cssource files.I've created a description how I've managed to do it. Hope it helps somebody.
https://balintpogatsa.github.io/2019/05/05/webassembly-mono-aot-example.html
@BalintPogatsa These directions were very helpful but I couldn't get the example to compile:
I looked at the current jenkins build script and noticed that I had to apply this patch:
cd /mnt/jenkins/workspace/test-mono-mainline-wasm/label/ubuntu-1804-amd64/sdks/builds/toolchains/emsdk/upstream/emscripten && (patch -N -p1 < /mnt/jenkins/workspace/test-mono-mainline-wasm/label/ubuntu-1804-amd64/sdks/builds/emscripten-pr-8457.diff; exit 0)
patching file emcc.py
The patch can be found here:
https://github.com/mono/mono/blob/master/sdks/builds/emscripten-pr-8457.diff
The example then compiled for me.
Has there been any movement on this? Are we any closer to AOT Blazor (or any other C# app) than we were since the last update?
My guess is the development pace will be able to pick up again once .NET Core 3.0 is out later this month.
Also, does anyone know whether reflection will be a problem the way it is with CoreRT and .NET Native? I would hope not since reflection (other than Emit) works fine when Mono compiles to iOS, but I would like to confirm.
Reflection in general is supported on wasm, some things like Type.GetType () might have problems due to the lack of stack walks.
It was announced that Blazor WASM will be released in May 2020. Can we assume that it will have AOT compilation? What is the correct answer?
For all Blazor fans two things are very important:
Note that this bug is about AOT support in mono wasm, not Blazor. AOT now works in mono wasm, there are too many problems:
@Andrzej-W I have been asking the same question at the ASP.NET Core project and the team seems to be tight lipped. It's not even clear to me that the two teams are coordinating or what the game plan is - if any - for getting AOT to Blazor. Which is concerning.
the executable size is too big
This one is important, yes. What are some of the latest stats?
build speed is too slow
This one is much less important IMO. AOT compilation should be reserved for final releases. Webpack release compilation can be horrible too.
You can inspect this site: https://unobootstrap-staging.azurewebsites.net which is built with AOT using mono-wasm from a few days ago. It's a simple raytracer, so it'll give you an idea of how low it can go (for now, until profile guided AOT is enabled).
My understanding:
Can we assume that it will have AOT compilation? What is the correct answer?
(•) No, and we don't have any roadmap just yet.
There is plenty to do on Blazor (or Mono-WASM, for that matter) _besides_ AOT, such as a better debugging story.
@jeromelaban that site looks like it's using interpreted WASM. It's downloading mono.wasm (1.3MB) for example.
@chucker not sure if you've used Blazor extensively but complicated UIs do not run at an acceptable speed with interpreted mono. Server-side Blazor is very good but there are significant scalability concerns.
@jeromelaban that site looks like it's using interpreted WASM. It's downloading mono.wasm (1.3MB) for example.
@legistek this site is AOTed. You're seeing the brotli compressed file (pre-compressed for speed). The interpreted version runs the same raytracer in about 30s.
@jeromelaban ok thanks. I was trying to get an idea of download size. So the 1.3MB mono.wasm file is basically the compiled application?
1.3MB isn't horrible but it's only a few hundred lines of C# code so I'd wonder how that scales in a realistic application.
@jeromelaban ok thanks. I was trying to get an idea of download size. So the 1.3MB mono.wasm file is basically the compiled application?
1.3MB isn't horrible but it's only a few hundred lines of C# code so I'd wonder how that scales in a realistic application.
@legistek it's the whole compiled application, with assemblies IL stripped. As for the few hundred lines, that's incorrect. There's the whole BCL+runtime that's coming along (albeit linked, without PGAoT).
I'm assuming you're trying to compare with existing JS frameworks, while excluding the weight of the browser itself (which provides the GC, runtime and everything else).
It's like saying electron based apps are fat when compared with native apps. Yes they are, but they come with their own environment.
Wasm in its current form is (in my opinion, and aside from using plain C or C++) is best suited for web apps, not web sites, where apps don't have the same expectations for payload size.
If you want to see a realistic production application, see this https://calculator.platform.uno, which is running mixed mode (AOT+Interpreter).
Ok so the calculator is 6.3MB.
I'm not really trying to compare it to JS or anything else. I just want to know roughly (within an order of magnitude even would be helpful) how large of a payload to expect for a complex app. For example, Microsoft Word online. Both where things stand now, and where things are expected to go.
And just as an aside, I remember well from my C++ days (and back when static linking was the norm) that you could have very complex applications with lots of dependencies and the resulting self-contianed EXE would be quite small because the linker would strip out anything not needed. I assume that's the ultimate goal here as well, yes?
And just as an aside, I remember well from my C++ days (and back when static linking was the norm) that you could have very complex applications with lots of dependencies and the resulting self-contianed EXE would be quite small because the linker would strip out anything not needed. I assume that's the ultimate goal here as well, yes?
That's what both IL and LLVM linkers do indeed.
It's not efficient enough for IL though, for multiple reasons (e.g. libraries not built having linkers in mind, like json.net that pulls the universe along with it, as it unconditionally references lots of code), but with profile guided AOT, the unused (or not used enough) code will not be compiled down to AOT. It will stay as IL (way smaller than its Wasm equivalent) while still being executable through the interpreter.
@jeromelaban understood, and thanks for the explanation. Makes sense. Unfortunately it still doesn't answer the question of how big we can expect full blown apps to be? I think we could all live with 10 MB, 20, and maybe even 50 MB (esp. if the browser will cache). Much more than that and it's going to feel to people like they're downloading an app, which defeats a lot of the purpose of WASM.
Please realize there's no judgment here. We just need to have our expectations properly informed.
@legistek the calculator is a full blown app :) It's the actual windows calculator. There's some kind of threshold where adding more app code does not increase the size of the binary much, as many of the framework dependencies are already pulled in.
That being said, my expectations are that the size will go down significantly with PGAoT, and you can get a taste of that by looking at what Xamarin.Android does as it's using the same optimization technique.
Haha. Yes, well, I doubt many CTOs and CEOs,, when we are trying to convince them we should adopt Blazor or Uno or anything else, will consider Calculator as representative of what we would be trying to sell.
So it sounds like the answer is, y'all just don't know. Which is fine, but that is a big risk factor.
Perhaps static linking is not the best idea after all, reflection just makes it much worse. Browser could happily cache libraries, even if they are big and after they have been loaded once, no more loading. Granted, initial download might be big but all others would incur no penalties.
@jeromelaban you have written
It will stay as IL (way smaller than its Wasm equivalent)
Does that mean that instruction set available in Wasm is much smaller (or more primitive) than in IL?
I have never analysed Wasm instruction set but I would like to believe that it is comparable to IL and when we compile some C# code to one or the other we will have a binary file with similar size. And I'm no talking here about linking libraries but about code generation - translation from C# to Wasm or IL.
I understand that C# to IL compiler is mature and Wasm is relatively new but hopefully it will be possible to achieve similar binary size in the near future. What do you think?
WebAssembly and .NET IL are not comparable.
WebAssembly is lower level. It is designed for C++.
It has no object model. No struct, no classes, no fields, no statics, no virtual calls, no derivations of types, no metadata, no interfaces, no arrays. Just ints, floats, and addresses. It has something special for function pointers, is all, so that the call and callee must match on signature.
WebAssembly is more like a CPU.
Thank you @jaykrell for explanation. I'm old enough that I wrote programs in assembly language for Motorola 68000 and Intel 8086 processors. Now I understand the most fundamental difference between IL and Wasm. It is of course much more complicated to generate for example virtual method call when it is not supported by Wasm, but the question remains: will it be possible to have comparable binary size?
Let's assume some code compiled to IL has 2MB. The same code compiled to Wasm will have for example 2.5MB. It is much bigger, but we don't need an IL interpreter at all and as a result we have to download much less bytes (I'm writing this in context of Blazor).
I don’t think interpreter is particularly large. It is?
WebAssembly also kinda does not have a “runtime” or “library”. You need to get System.String, System.Object, etc. from somewhere. And then maybe static linking.
The runtime itself is around 1.2MB (just the C part like the GC, interpreter, etc.. no BCL).
For 12 MB of IL, the result of mixed AOT is about 35 MB (where Newtonsoft.Json and System.Data are interpreted, because of their linker-unfriendliness). 35 MB includes the 1.2 MB of the runtime.
@jeromelaban If I understand correctly you have some set of C# sources (Microsoft/Mono libraries) which are then compiled to IL and to Wasm and the size of Wasm binaries is almost 3 times bigger. I have to say that it is terrible. The last hope is 5G network in every place around the globe.
Thank you guys for all your help and time.
@Andrzej-W this is the current state of the AOT compiler. The smart mono folks are working on many improvements, and wasm itself is going to improve.
Also, that 35 MB compresses down to 6MB on the wire using brotli. (still the calculator I mentioned earlier).
I just want to make a quick comment. Compilers and compilation are among the most complex and esoteric topics in all of computer science. I was programming C64 assembly as a child and C in high school and I DROPPED my compilers class in college because I thought it would be too difficult and tedious. It's crazy CRAZY hard. The people who work on compiler technologies are usually the best of the best.
Relatedly, our experience and intuition as application level programmers don't really apply when it comes to compilation. So you may ask, how is it possible that compiled code could wind up orders of magnitude larger than the interpreted code? Well it's possible and REALLY hard to understand exactly why.
My point is, I have faith that the experts from Mono and Microsoft are on top of this and will figure it out. I just urge as much transparency as possible for the sake of managing our expectations. Likewise I urge my fellow observers to not read too much into any one data point and trust that the experts here will find the best outcome possible.
I'd like to echo @jeromelaban 's point:
Wasm in its current form is (in my opinion, and aside from using plain C or C++) is best suited for web apps, not web sites, where apps don't have the same expectations for payload size.
I assume by web apps he meant Rich Internet Applications (RIAs), not those like ASP.Net Web applications (MVC, Web Forms, etc). The long startup time is caused by more than the download size which is not much different from many static pages with a bunch of images especially GIFs. People who know exactly what tasks they want to perform with an RIA most likely do not mind waiting for quite a few seconds before it starts for the first time. Subsequent startup time is significantly reduced. (80% reduction for one of my WASM apps which I am unable to explain fully by browser cache).
Casual visitors of a web page would likely flee if contents do not show up in a few seconds.
@miha,
I agree, perhaps some combination of static linking and CDN-hosted
libraries would be the best.
Dne st 2. 10. 2019 16:07 uživatel Hong notifications@github.com napsal:
I'd like to echo @jeromelaban https://github.com/jeromelaban 's point:
Wasm in its current form is (in my opinion, and aside from using plain C
or C++) is best suited for web apps, not web sites, where apps don't have
the same expectations for payload size.I assume by web apps he meant Rich Internet Applications (RIAs), not those
like ASP.Net Web applications (MVC, Web Forms, etc). The long startup time
is caused by more than the download size which is not much different from many
static pages with a bunch of images especially GIFs
https://www.keycdn.com/support/the-growth-of-web-page-size. People who
know exactly what tasks they want to perform with an RIA most likely do not
mind waiting for quite a few seconds before it starts for the first time.
Subsequent startup time is significantly reduced. (80% reduction for one of
my WASM apps which I am unable to explain fully by browser cache).
Casual visitors of a web page would likely flee
https://www.section.io/blog/page-load-time-bounce-rate/ if contents do
not show up in a few seconds.—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/mono/mono/issues/10222?email_source=notifications&email_token=AAQ6JS2SR7XDYXUGBYOHBMDQMSTI5A5CNFSM4FQZ6SZKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEAE3V2A#issuecomment-537508584,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAQ6JS3N3AKEIPDJN4VDRIDQMSTI5ANCNFSM4FQZ6SZA
.
@jeromelaban for that calculator app, is there a step by step guide anywhere that you know of explaining how to build in the mixed mode that was used for that app? (My understanding is that the production version of Uno is still using the mono interpreter, so I'm assuming someone went through a custom build process to make the calculator app, right?) Thanks!
Edit - If I'm understanding correctly, it looks like the only portion of the Uno calculator app that's native AOT WASM is the original C++ from MS. All the C# code appears to still be interpreted IL. Is that correct?
@legistek it depends on the apps, but most of the apps we publish are either Full AOT or Mixed Mode. We tend to keep interpreter only builds for iOS, which does not support large wasm modules.
For the Calculator, it's running Full AOT and there's nothing custom around AOT that sets it aside from the other Uno apps, but there's specific code to support interop with a native wasm module (the C++ calculation engine) that got merged into mono master.
The Uno Bootstrapper itself is custom from mono's standpoint, but that's pretty much it. For the Wasm Mixed Mode itself, there's no specific tech documentation that I know of, other than this one, maybe @vargaz can help there.
Some doc for building with AOT is here, and more specific bits for the calculator.
Ok, wow, I think I actually got it working. (At least I got "Hello World" to display in the console, lol!)
One thing - the line sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF doesn't work in WSL. I had to use curl -sL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF" | sudo apt-key add. Don't ask me why or what it means!
Thanks @jeromelaban I think I can at least start to compare performance.
Edit -
If anyone's interested, I did some real quick and dirty benchmarking of operations I knew would be inefficient like reflection (basically data binding) and string manipulation, not just arithmetic. Here's what I got:
Mono Interpreted IL: 2.49s
Full AOT (Chrome): 0.702s
Full AOT (Firefox): 0.5s
Native: 0.067s
So WASM AOT was basically 10x slower than native, and interpreted was basically 4-5x slower than AOT.
Good, but not phenomenal.
@legistek Note that https://github.com/mono/mono/issues/13653 has a very significant impact on performance, every time there's a using, foreach, lock, any Linq operator, etc...
I remember @kg was talking about some possible optimizations there, but until the Exceptions specification is implemented, there's going to be some impact, it seems.
Very interesting and good to know!
Anyway very impressive work. I compiled a pretty large project and the compressed mono.wasm was about 5MB and that was not even mixed mode. A similar scale Angular project of ours is almost that size even after webpacking so this is well within tolerable limits and presumably will only get better.
Now if only we can get a Windows toolchain the world will be perfect. :)
Now if only we can get a Windows toolchain the world will be perfect. :)
Concur if the toolchain would work RELIABLY well. Now, building an AoT package is a simple click of a .bat file, and it is very reliable. In light of the .Net Native toolchain nightmare, I would rather stay with this Unix based .bat file than an unreliable Windows toolchain. I never need to restart VS or Windows, clean projects or solutions, delete output folders, delete the mega NuGet package folder, etc. to make the AoT building work with this one-click approach.
I'm trying to understand where we're at regarding WASM support for Blazor and would have thought that this very feature would be important for Blazor on WASM. Given that Blazor is supposed to have WASM support by May 2020 I find it concerning that there hasn't been much progress recently on this particular issue.
Could anyone please shed some light? What am I missing?
It really seems like the only serious WASM .NET work being done right now is by @jeromelaban and Uno. There's nothing stopping the Blazor team from building out a bootstrapper for AOT WASM the way Uno did, even if it requires a Linux toolchain. Yet I've directly asked the Blazor team about this repeatedly and they don't reply. They just seem to have other priorities.
Any update on this?
Still in progress.
Will it be "Done" in time for .NET 5 in November?
@kg the Blazor team just removed AOT from the .NET 5 roadmap:
https://github.com/dotnet/aspnetcore/issues/21514
We're just wondering if something changed and what.
@kg the Blazor team just removed AOT from the .NET 5 roadmap:
dotnet/aspnetcore#21514We're just wondering if something changed and what.
@legistek Dan posted in explaining the current status of AoT in .Net 5.
Looks like much more work is required in order for it to be accomplished so I don't think they were able to include it in the launch.
https://github.com/dotnet/aspnetcore/issues/5466#issuecomment-639806998_
Is there any documentation or guide on how to compile to a single wasm through mono AOT without UNO? I'm having a hard time finding any sort of documentation. My understanding was that this functionality which was POC'd through mono-wasm was already ported to mono.
I found and followed this guide (https://balintpogatsa.github.io/2019/05/05/webassembly-mono-aot-example.html) but the result was not what I expected. It sounded like this was suppose to be way to compile AOT without the need for UNO. I thought the end result would be the mono webassembly runtime, my code, and the standard libs that I depend on would all get compiled into a single wasm file. Instead after compilation I ended up with a slightly larger wasm file but all the dlls still seem to be there and attempting to load the wasm module by itself didn't seem to work.
Most helpful comment
Yes, work is being done on AOT support, it is somewhat usable in mono master.
There are 2 main problems currently: