-
Notifications
You must be signed in to change notification settings - Fork 188
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
Effect handlers #1340
Effect handlers #1340
Conversation
@pmwhite is looking at running Jane Streets codebase under this patch |
In the past, large applications have demonstrated surprising performance charactaristics when compiled with JSOO, like this issue where testing a gameboy emulator showed some scenarios where inlining hurt runtime performance. I wonder if it might be worth it to build and benchmark that gameboy emulator with these changes in order to see how it performs on larger programs. |
This is ncessary to deal with the calling conventin mismatch introduced by the upcoming effect support (ocsigen/js_of_ocaml#1340)
This is ncessary to deal with the calling conventin mismatch introduced by the upcoming effect support (ocsigen/js_of_ocaml#1340)
This is necessary to deal with the calling convention mismatch introduced by the upcoming effect support (ocsigen/js_of_ocaml#1340)
That's a good idea, indeed. It is about 7 times slower in Chrome. I guess that should be expected for this kind of code. With support for effect handlers:
Without:
Interestingly, the generated code is only 30% larger (5% larger when compressed). So, it is possible that we can do way better for the Ocsigen Start demo I mentioned above (the lambda lifting phase currently generates a few functions with thousands of parameters, which might well have a large impact on code size...) |
What's the story for separate compilation and dynlink ? I wonder if we should have the jsoo linker check that all js files have been compiled with compatible options. (use-js-string and effects) |
Iv'e done a first pass of review without really looking at the commit implementing effects yet. |
Can you include the benchmark changes used to generate the graphs. |
… tests We are doing a lot of generated code comparison. I'm not sure it is worth it to change the tests.
This is a joint work with Olivier Nicole (@OlivierNicole) based on previous work from Armaël Guéneau (@Armael) and Patrick Ferris (@patricoferris), with some help from Hugo Heuzard (@hhugo)
With 'make graphseff'
…osition No longer do this while parsing the bytecode. This is more robust, since the optimization phases do not have to preserve this invariant. This is also more efficient, since do not have to deal with so many blocks during optimization phases.
And simplify Effect.cps_block
@hhugo I have cleaned up the history. Thanks a lot for your review and all the work you put into it. That was tremendously useful! |
Thanks everyone for the work!!! |
@vouillon, how is your effects-optim branch progressing. Do you think we should wait for it before the next release ? |
@hhugo It probably still needs several weeks of work. So I don't think we should wait for it. |
@vouillon, changing the baseline of lambda_lifting from 1 to 2 seem to reduce the amount of free variable quiet a bit. Using es6 lambda could reduce the size (uncompressed) a bit |
Well spotted! See #1360 for an alternative fix.
Yes, indeed. |
I did a quick experiment, |
To support effect handlers, we are changing the calling convention of OCaml functions. See ocsigen/js_of_ocaml#1340. Wrapping Ocaml functions is now mandatory to use them from JavaScript.
This pull request adds support for effect handlers. This is a joint work with Olivier Nicole (@OlivierNicole) based on previous work from Armaël Guéneau (@Armael) and Patrick Ferris (@patricoferris).
The implementation is based on a CPS transform of the whole code. This a thorough implementation. In particular, you can perform effects from within the OCaml toplevel in a browser.
The graph below shows the performance impact on some short programs from the Js_of_ocaml benchmark. Short recursive functions that did not perform any allocation, such as the Fibonacci function, become much slower (up to 9 time slower). For other benchmarks, we are more between 1.5 and 2 times slower. Interestingly, code that makes heavy use of exceptions can become faster (
boyer
).The code size is larger, within a factor 2.5. For a much larger example, the Ocsigen Start demo, the generated code is 80% larger. But only 26% larger when compressed with
bzip2
(we are adding a lot offunction
andreturn
that compress well).We hope to be able to reduce the performance gap by performing a partial CPS transform based on a static analysis to detect code that does not perform any effects.
The compatibility with existing code should be rather high. However, the calling convention mismatch between JavaScript and OCaml is now larger since OCaml functions take a continuation as additional parameter. So, it is no longer possible to call a JavaScript function as if it was an OCaml function (and conversely). When calling a JavaScript from OCaml, you have to use
Js.Unsafe.call
. For using an OCaml function from JavaScript, you have to properly wrap it usingJs.wrap_callback
or one of theJs.Unsafe.callback
variants.