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

Add support for future-less asynchronous calls on void methods #8

Closed
TobiasWrigstad opened this issue Jul 18, 2014 · 17 comments
Closed
Assignees

Comments

@TobiasWrigstad
Copy link
Contributor

We currently implement async sends to void methods using standard futures which are fulfilled by (). This makes some sense -- it is possible to wait for the method to finish. On the other hand, it is highly suboptimal. Profiling the prime sieve program for example showed that ~30% of the entire program was spent creating and fulfilling Fut void.

We need a way to call void methods asynchronously without futures. For now, I think a good solution (given it is simple to implement) is to check whether the caller saves the result of the call or not. So, give the method foo() : void, the call

target.foo()

should generate a call without future overhead, whereas the call

x = target.foo()

should generate the same code as we currently do for both those cases.

(Someone might argue this is premature optimisation but currently that's not the case. Anything that makes our current key example run faster is important.)

@EliasC — I am assigning you to this task. If you can have this done before August 1st, we are good.

@TobiasWrigstad TobiasWrigstad changed the title Support for future-less asynchronous calls on void methods Add support for future-less asynchronous calls on void methods Jul 18, 2014
@supercooldave
Copy link

Doug Lea calls these one way message sends.

@EliasC
Copy link
Contributor

EliasC commented Jul 19, 2014

It's a bit wonky to implement it that way since it would require adding machinery, either to the type checker or to the code generation, to know if the current thing being translated is being "captured" or not. It wouldn't be hard, but I would prefer to avoid adding that kind of complexity for just one thing.

What would actually be easier to implement is another operator for one way message sends. For example, x!foo() could mean call foo and ignore the results (making y = x!foo() illegal). On the C-level, this could tranlate to a normal message send with a future that is NULL.

@TobiasWrigstad
Copy link
Contributor Author

For a first implementation of this feature, I am all for it.

@supercooldave
Copy link

Just one point on this issue. It applies to all kinds of methods, not just those returning void.

Sent from my iPhone

On 19/07/2014, at 10:09, EliasC [email protected] wrote:

It's a bit wonky to implement that way since it would require adding machinery, either to the type checker or to the code generation, to know if the current thing being translated is being "captured" or not. It wouldn't be hard, but I would prefer to avoid adding that kind of complexity for just one thing.

What would actually be easier to implement is another operator for one way message sends. For example, x!foo() could mean call foo and ignore the results (making y = x!foo() illegal). On the C-level, this could tranlate to a normal message send with a future that is NULL.


Reply to this email directly or view it on GitHub.

Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm

@supercooldave
Copy link

I guess the difference between the two approaches boils down to whether one way sends are a language feature or an optimisation.

@TobiasWrigstad
Copy link
Contributor Author

This is a good point. I like both actually. What I originally suggested is not visible to the user, which is nice — and in line with the project. But it is also good to be able to explicate what one wants. So I'd like both I guess. But I'd favour the first kind just to lower the number of concepts in the language.

@EliasC
Copy link
Contributor

EliasC commented Jul 19, 2014

Just a reminder that nothing we do in mylittlepony needs to "leak" to the final language. It is fully possible to implicitly avoid creating futures, but when trying the language out like this I think there is a point in favoring low implementation complexity over user complexity.

@TobiasWrigstad
Copy link
Contributor Author

Given the level of documentation of the current implementation, I agree with you 100% ;)

@albertnetymk
Copy link
Contributor

I would guess the C optimizer is smart enough to remove the unused result.

Even if we capture the return value of one function call, 'x =
actor.function()', it's still possible that variable is not accessed
afterwards, and it's the job of optimizer to avoid the unnecessary code
generation. C should be able to optimize it away with '-O2'. Is the
profiling running with optimizing flag on?
On Jul 19, 2014 10:42 AM, "TobiasWrigstad" [email protected] wrote:

Given the level of documentation of the current implementation, I agree
with you 100% ;)


Reply to this email directly or view it on GitHub
#8 (comment).

@TobiasWrigstad
Copy link
Contributor Author

The C compiler is really not that smart. Partially because we are generating code that looks very much like use, and because there are multiple use-sites and the creation-site is always different from at leaf one use-site.

I ran with -O1, -O2 and -O3 and saw roughly the same 30% time spent generating futures never used.

@EliasC
Copy link
Contributor

EliasC commented Jul 22, 2014

This has been implemented and seems to work (i.e. it doesn't break anything obvious). Feel free to reopen this if new problems arise.

@EliasC EliasC closed this as completed Jul 22, 2014
@TobiasWrigstad
Copy link
Contributor Author

Can you just briefly write down how this works here for our perusal and inclusion in Stephan’s language spec?

@EliasC
Copy link
Contributor

EliasC commented Jul 23, 2014

The expression x!foo(y) will call the method foo on x and immediately return unit. No futures will be generated, so this should be more efficient when calling methods of void-type (or when you don't care about the result).

@supercooldave
Copy link

Don't confuse methods of void return type with those whose result you don't care about. We may care to know when a void method returns.

Sent from my iPhone

On 23/07/2014, at 10:30, EliasC [email protected] wrote:

The expression x!foo(y) will call the method foo on x and immediately return unit. No futures will be generated, so this should be more efficient when calling methods of void-type (or when you don't care about the result).


Reply to this email directly or view it on GitHub.

Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm

@EliasC
Copy link
Contributor

EliasC commented Jul 23, 2014

@supercooldave Sure, and in that case we can still use x.foo(y) and get on that result. Mentally remove the "or" from the final parenthesis in my previous post (or parenthesise it one additional level).

@kaeluka
Copy link
Contributor

kaeluka commented Jul 23, 2014

I'll put it in the manual later today

@TobiasWrigstad
Copy link
Contributor Author

Super!

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

5 participants