-
-
Notifications
You must be signed in to change notification settings - Fork 143
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
Recompile Emscripten binaries, implement WASM with fallback, and add instructions and scripts #740
Recompile Emscripten binaries, implement WASM with fallback, and add instructions and scripts #740
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm on the bash script
I've commited my script. |
Great! I'll try to reproduce mine in Windows sandbox, as the only other machine I have is very ancient and would get clogged up if I try to install docker desktop on it. |
I'll do some testing of these versions, and in particular try to get some results for #652 (comparing the wasm and the asm versions). I needed to recompile due to the memory issue with the Promise polyfill branch (as I wanted to test with that version which is faster). On a quick test with the old wasm from last year (in one browser), just judging by how it "feels" as a user browsing a ZIM, the wasm version is still not any faster than asm, but this might have changed with the newer Emscripten. However, note that if we don't merge the Polyfill PR, then we probably don't need to compile these with the higher memory value I've included in this PR, as we only need more Emscripten memory for stability with that PR. So long as the wasm version isn't slower, I could push my code that selects wasm if the browser supports it, or asm if it doesn't. It's not complicated, a couple of lines. Would it be best to push that to this PR (and change title) or to separate one? I think that one would depend on this one (and they both to some extent depend on the Promise Polyfill PR). Final step would be to clone these scripts to recompile xzdec and maybe include a wasm version of that too. |
I opened emscripten-core/emscripten#14700. However, that GitHub is swamped with issues and PRs, so it wouldn't surprise me if this is overlooked. In the meantime, we can easily polyfill the |
I confirm that the only polyfill needed to allow this asm to run on IE11 is:
I'll add it to this PR in |
Kripken did reply on that issue, suggesting I make a PR for the polyfill... I don't know whether I can do that (I've actually suggested a simpler alternative), but in any case it looks like I should add the very short polyfill -- maybe to zimfile.js -- with a note to remove it if it's not needed in a future Emscripten release. |
60993c2
to
f9d594e
Compare
I've added in the newly compiled wasm and asm modules (zstandard only, not xzdec yet), and I've made them conditionally loadable, so that IE11 still works and uses ASM, and browsers capable of running WebAssembly use the WASM. The WASM version is not any slower than ASM (in any one browser) on my quick subjective tests, and may be a little faster. What's sure is that it is a much smaller module to load and should run on a dedicated low-level system (though ASM apparently runs on its own precompiled thread too). Just bear in mind that this branch doesn't have the Promise polyfill yet (that's a separate PR), so it's still using Q, and doesn't benefit from the speedup we see in that branch. Now, should we try to do the same for xzdec? The compile string will need to be changed, because we last compiled on an older version of EMSDK, and some of the options have changed names. |
@mossroy Just to let you know, we need to modularize xzdec, which also means refactoring xzdec_wrapper, to get it to work in the same way as zstddec. I need to push a change to the EMCC compile command to do that. |
@Jaifroid : OK sorry I leave the keyboard for now, then. |
No problem, your changes won't conflict with what I'm doing, but we will need to recompile xzdec again when I've pushed the relevant changes (but that's easy now). |
Congrats for finding and reporting a bug in emscripten! If you don't manage to do the PR they suggest, I might help |
Feel free! I won't be working on that (handling what needs to be done with our code is plenty enough for me!!). On that issue, there is an Emscripten dev who seems to have taken an interest, but it's not clear if they are proposing to do the work or not... |
Hmm. Latest commits are failing on one browser (Chrome 58, Window 7) in compiling the new xzdec WASM -- see below. This is probably one of the first browsers to provide WASM support and it may well have been an incomplete implementation in that version. How should we handle this? Some kind of fallback to ASM if WASM fails to compile? Might be hard to code for that...
|
I thought I'd be clever and get round the Chrome 58 WASM compile error by detecting it and reloading the app in ASM mode. It worked, but Sauce Labs doesn't like it and complains (see screenshot)... So now I'm stumped. I downloaded a version of Chrome 58 and it indeed cannot compile the WASM. The problem is with that early version of Chrome, not with our modern WASM. My solution works for the user: they just get a momentary reload during the load sequence, which is hardly noticeable. But it doesn't work for testing. Any ideas as to how I can abort and change the RequireJS definition "on the fly", in a generic way, without doing Last resort might be to change the Chrome version we're testing against? I don't suppose we should introduce some specific test for a specific build of this browser in the code (if that's possible), just to get around testing? |
OK, I ditched the reload idea, and fixed it instead with a fallback |
Your latest approach (use requireJS to load ASM if loading WASM fails) looks the best one to me. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would be in favor of adding the same fallback to ASM if loading the WASM file fails
I agree. It has drawbacks, so better to test each time. |
I did not have the time to work on emscripten-core/emscripten#14700 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could not test, just added a few comments in the code
I've had a look in
However, oddly, it says that streaming instantiation is disabled by default. The only thing I can think is that we have not set the option for the MINIMAL_RUNTIME (above those two options). It could be worth experimenting with? I don't know if it's necessary just to eliminate a fallback warning in browser consoles, and of course our code might not work with the minimal runtime as I think we possibly need XHR to load the WASM binary. |
This branch works fine on my Firefox OS device. It chooses the ASM versions (as WASM is unsupported) and does not complain. I did not see any obvious performance difference. It might be worth testing the "minimal runtime" option you suggest. Another improvement could be to display in the Settings section :
|
Yes, populating the API panel could provide good diagnostic info to savvy users. |
I've added code to populate the API Status Panel. It was trickier than I thought to get right given the async nature of the errors happening. I've included in zstddec-wrapper and xzdec-wrapper some Some images below of what would be seen in a) an error situation, and b) normal operation. Please note that the actual decoder being used ('ZSTD' or 'XZ') in square brackets after the machine type ('WASM' or 'ASM') will only be displayed once a ZIM file has been loaded. It will always report the last decompression type used. Though extremely unlikely in practice, a ZIM could hypothetically use ZSTD for some clusters and XZ for some others. The only way to know the decompression type is at the moment a Decompressor is requested. Code to deal with any particular decompression type is set up in its wrapper, so the code should be extensible to future codecs. EDIT: Once an error has been detected, it will always be shown in the API panel during that session, even if the user is using the other decoder and that loaded normally. The error occurs for any particular decoder only if all attempts to fall back to asm have failed, as well as wasm. IMHO it's better to show that there's a problem, than to hide it just because the needed decompressor is working. Otherwise the user won't know why the app hangs when opening some ZIMs and not others. In practice it would be rare for one decoder to load and the other not to, but we did come across a situation above that was similar in an old Chrome. |
I've run out of time to deal with the console warning, i.e. to experiment with different values when compiling xzdec and zstddec. We've made it fairly easy to do that (it's the testing that would be time-consuming). So I think it's best to set that as a new issue. @mossroy Please let me know if the implementation of the Status Panel code is satisfactory for merging (in due course). I have tested it on IE11, Firefox latest, Edge Chromium. I have yet to test on Edge Legacy or UWP. |
Just noticed a silly minor error... Will push a very small change. |
@mossroy Apart from the minor changes I've indicated in comments above, are you happy for me to squash-merge? |
It seems to work well on my FirefoxOS device :-) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not have a very deep look, but it looks good to me
It's working fine on Firefox OS (orange) and latest Firefox/Chromium (green). |
OK, will do. |
This PR is for implementing #739.
I've done the Windows implementation and documentation, with a short PowerShell script that runs everything. It works like a dream -- so much easier than what I had to do before!
@mossroy Would you be able to do the equivalent linux script (no rush)? It's probably just a one-liner and very easy for you to test on your linux machines. Take a look at the script
Compile-Zstddec.ps1
in this PR.I'm not sure whether we should add equivalent xzdec compilation to this PR to make it generic. For the moment it's just zstddec.