Some important things I think people should note before blindly commenting: * The example code is obviously contrived. The real gist is that massive deallocations in the UI thread cause lag, which the example code proves. That very thing can easily happen in the real world. * I didn't see any difference on my machine between a debug build and a release build. * The example is preforming 1 _million_ deallocations. Tha…
>As an aside, compilers have used the trick of not free-ing data structures before, because it provides a significant performance boost. Instead of calling free on all those billions of tiny data structures a compiler would generate during its lifetime, they just let them leak. Since a compiler is short lived its not a problem, they get a free lunch (pun unintended), and the OS takes care of cleaning up after all is…
Rust: Dropping heavy things in another thread can make your code 10000x faster
241–250 of 285 posts
Re: Rust: Dropping heavy things in another thread can make your code 10000x faster
#242Earlier quoted context omitted.
Destructors in C++ aren't just for making sure you leak memory. They are used for many lifetime controlled things such as: 1. general resource cleanup (file handle, database connection, etc.) using RAII (Resource Aquisition Is Initialization); 2. tracing function entry/exit.
Apparently, that doesn't work in Rust: https://news.ycombinator.com/item?id=23363647
Re: Rust: Dropping heavy things in another thread can make your code 10000x faster
#243Just be careful, because moving heavy things to be dropped to another thread can change the semantics of the program. For instance, consider what happens if within that heavy thing you had a BufWriter: unless its buffer is empty, dropping it writes the buffer, so now your file is being written and closed in a random moment in the future, instead of being guaranteed to have been sent to the kernel and closed when the…
A while ago I stumbled over a proposal to move a shared pointer (this was C++ code) to a thread in order to trigger the freeing of a legacy data structure there (the multi-thousand delete calls caused the watchdog of the main thread to fail). However, keeping the shared pointer reference in the main thread for too long resulted in the possibility that the "clean-up" thread ran while the main thread still had a hold o…
Re: Rust: Dropping heavy things in another thread can make your code 10000x faster
#244The title is slightly wrong: it's not going to make your code faster , it's going to reduce latency on the given thread. It maybe a net win if this is the UI thread of a desktop app, but overall, it will come at a performance cost: because modern allocators have thread-local memory pools, and now you're moving away from it. And if you're running you code on a NUMA system (most server nowadays), when moving from one t…
I think if you wanted to do deferred destruction right, ideally you’d mod an allocator to have functions like (alloc_local, alloc_global, free_now, free_deferred) to avoid exhausting memory. Traits could make this ergonomic.
Also I admit I don’t understand why “you won’t have any backpressure on your allocations,” shouldn’t deferred destruction give you more backpressure if anything? I am probably confused.
Re: Rust: Dropping heavy things in another thread can make your code 10000x faster
#245Earlier quoted context omitted.
> the ownership system lets you transfer freeing responsibility off-thread safely and cheaply in order to not have it block the critical path This can also trivially be done in other languages. Atomically append your pointer to a queue of "large things that need to be freed" and move on as though you had actually called free. Within a particularly time sensitive loop you can even opt to place pointers into a prealloc…
A lot of C++ code depends on deallocation order for correctness. Like a destructor may want to say bye-bye to a pointed-to-object, and if you reverse order of deallocation, that pointer may be dangling. Consider this code { Window a; ClickHandler* b = new ClickHandler(&a); delete b; } Let's say b tries to deregister itself when it's deleted. This code will work as written. But if you defer the deletion of b, then sta…
Re: Rust: Dropping heavy things in another thread can make your code 10000x faster
#246Earlier quoted context omitted.
Correctness means adherence to the spec, not some contrived absolute truth.
But the spec usually has some implicit assumptions. Usually it's "app doesn't leak memory" in the same way nobody explicitly specifies "result of an addition of natural numbers should match ...". We don't go around saying "oh, you didn't want modulo 5 arithmetic? You should've put that in the spec, not rely on some contrived absolute truth".
Yes they do. In most programming languages, by default integer arithmetic is modulo 2^64 (at best). If you want arbitrary precision arithmetic, you have to explicitly specify that.
Re: Rust: Dropping heavy things in another thread can make your code 10000x faster
#247Earlier quoted context omitted.
In a world where processes can fork-and-exec, nothing about "as a service" changes that. The compiler would just be reinvoked as needed. Converting it into a persistent process breaks a lot more than just allocation optimizations.
But you want to share state and only update state incrementally on edit to get any reasonable level of performance for stuff like language server code analysis.
Re: Rust: Dropping heavy things in another thread can make your code 10000x faster
#248This is the standard problem with tracing data structures to free them. You frequently run into it with systems based on malloc/free or reference counting. The underlying problem is that freeing the structure takes time proportional to the number of pointers in the structure it has to chase. Generational/compacting GC has the opposite problem. Garbage collection takes time proportional to the live set, and the amount…
"Generational/compacting GC has the opposite problem. Garbage collection takes time proportional to the live set, and the amount of memory collected is unimportant." Takes time proportional the live set times the number of GC runs that happen while the objects are alive . In other words, the longer the objects live, the more GC runs have to scan that object (assuming there is enough activity to trigger the GC), and t…
Re: Rust: Dropping heavy things in another thread can make your code 10000x faster
#249Earlier quoted context omitted.
Isn’t a Rust “move” implemented as a bit wise copy (e.g. memcpy call)? I see people claiming move has no cost but I’m not sure that is true.
What is bit-wise copied is the pointer to the memory. I.e. a `HashMap` struct, or `Vec` struct don't directly contain the data. For example the `Vec` is defined internally as something similar to: `struct Vec { data: *mut [T], capacity: usize, len: usize, marker: PhantomData }` (Slightly simplified, not actual Vec type). So a move of a Vec copies at most 3 usize (24 bytes on 64bit systems), similar thinks apply for a…
Re: Rust: Dropping heavy things in another thread can make your code 10000x faster
#250Earlier quoted context omitted.
"Generational/compacting GC has the opposite problem. Garbage collection takes time proportional to the live set, and the amount of memory collected is unimportant." Takes time proportional the live set times the number of GC runs that happen while the objects are alive . In other words, the longer the objects live, the more GC runs have to scan that object (assuming there is enough activity to trigger the GC), and t…
This is most decidedly not true for generational GCs, and for concurrent GCs, the tracing work happens asynchronously and in parallel, on other cores, not taking time on the main thread.
But generational GCs do improve massively on this problem.