-
Notifications
You must be signed in to change notification settings - Fork 14
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
Simplify deferred destruction #9
Conversation
Thanks for the writeup. I'm not sure I share the sentiment. My impression is that it's not a net-gain as it'll make the most frequent use cases less ergonomic. The extra Ptr/Owned functions are probably useful on their own, to avoid dirty transmutes and all that. |
Do you at least agree about removing
If we leave |
text/2017-08-30-simplify-defer.md
Outdated
This makes `defer_free` unnecessary. | ||
This is the kind of problem `ManuallyDrop` was created to solve. | ||
|
||
### Do we need `defer_free`? |
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.
maybe defer_drop
?
text/2017-08-30-simplify-defer.md
Outdated
|
||
# Detailed design | ||
|
||
### `Deferred` |
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 think the title here doesn't match with the content.
text/2017-08-30-simplify-defer.md
Outdated
In most cases `defer` will be used to just deallocate memory or execute simple destruction | ||
routines. The passed `FnOnce()` closure will almost always fit into, say, 3 words. | ||
|
||
I have an [implementation](https://gist.github.com/stjepang/00d63b8febc07b297eae3480e80d0e91) |
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 wonder if it can be inlined here so that this RFC is self-contained.
text/2017-08-30-simplify-defer.md
Outdated
of `Deferred` ready, which is able to store a small closure within itself, falling back | ||
to heap allocation for big closures. | ||
|
||
**TL;DR:** `Deferred` is to `FnOnce() + Send + 'static` what `SmallVec` is to `Vec`. |
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.
Very helpful analogy :)
|
||
Strictly speaking, this code is possibly incorrect because an `Owned` and `Ptr` pointing to the | ||
same thing exist at the same time. This is okay because the `Owned` will not be used until the | ||
closure executes, but **@RalfJung**'s new unsafe code checker might reject the code as unsound. |
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 feel the proposed solution is hacky for the reason that the meaning of Owned
or Ptr<'static>
is unclear. I think it would be great if the meaning can be explained in RustBelt's lifetime logic.
Also, I doubt that the defer*
family of functions is safe. For example, the client should guarantee that the defer_drop()
ed object is no longer pointed to by a memory cell. This knowledge cannot be expressed in Rust's type system, so it should be unsafe
.
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.
Regarding conversion from Ptr<'scope>
to Ptr<'static>
, that is definitely hacky. But I think what we actually want here is conversion to Ptr<'unsafe>
. Unsafe lifetime was proposed in this RFC, but in the end it was postponed.
Regarding safety, defer_free
and defer_drop
are definitely unsafe and this RFC doesn't aim to change that. However, defer
is currently unsafe, but this RFC proposes to make it a safe function. I suppose you're okay with that?
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.
Ah, yes. I am okay with pub safe fn defer()
.
text/2017-08-30-simplify-defer.md
Outdated
We'll introduce two new functions (`Owned::from_ptr` and `Ptr::to_static`). But at the same time | ||
we'll also remove two functions (`Scope::defer_free` and `Scope::defer_drop`). | ||
|
||
There might be very small differences in performance when using `defer_free` and `defer_drop` versus |
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 think @schets may have an opinion on the performance. cf: crossbeam-rs/crossbeam-epoch#3 (comment)
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.
Good point.
Is it reasonable to assume that defer_drop is the most frequent use case? I can get behind removing defer_free. |
I reduced the scope of the RFC. Now it only proposes to remove |
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 gonna go ahead and approve it. I'll defer more specific implementation details to the implementation PR.
I tacked
Unfortunately, it seems that in threaded benchmarks this version is noticeably slower, presumably due to slower migration of garbage. I might've made some silly mistake and written a nonoptimal implementation, but if not, we have to investigate the causes of this. |
On
|
I changed my mind and removed a previous comment. With regards to the API, we have to notice that removing The As the RFC mentions, In general, I'm in favour of this RFC, but only if we resolve the performance problems I mentioned in the comment above. |
Thank you for writing these benchmarks! I can confirm the performance issues. It turns out that the size of
I've pushed the updated implementation of |
This is the kind of problem `ManuallyDrop` was created to solve. | ||
|
||
# Can we make `defer` safe and faster? | ||
|
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.
Maybe three sharps?
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.
After tweaking the layout of Deferred a bit to make it smaller, the issue is resolved
That's great! If it was this simple to improve performance, surely it will also be possible to tweak it to specific hardware. I think it's fine if we leave the inline implementation of Deferred
in this RFC as a working PoC and then modify it further in the actual crate code.
This is a good point and a real concern. I'll open a new issue to discuss how to deal with those lifetime constraints. |
Proposal:
Scope::defer_free
.Scope::defer
.Rendered