4 ms·
No thanks. Watching you "manual memory all the way" dudes struggle with simple concurrency as much as you do, I'd hate to throw away a GC just for that extra t
by PopsiclePete 12y ago
No thanks.
Watching you "manual memory all the way" dudes struggle with simple concurrency as much as you do, I'd hate to throw away a GC just for that extra teeny bit of performance.
- comex 12y agoWell, the 10ms cited as desired GC latency is hardly an extra teeny bit of performance for a game server which would like to tick at at least 60fps (~16ms frame time), which is common for FPS; other types of games are different of course. I suppose it could be tuned to further decrease latency at the cost of throughput...
- crawshaw 12y agoThe 10ms number is an upper bound. You will only see pauses that long if you generating large amounts of garbage, which is relatively easy to avoid.
- oofabz 12y agoThe duration of a pause has more to do with the size of your heap than with how much garbage you generate. If you generate a lot of garbage, the pauses don't get longer, they get more frequent.
- slimsag 12y agocrawshaw isn't wrong -- and he's also the guy working on Android support. Go's GC scans pointers in the heap. - A 10GB heap with one single heap-allocated []byte will have short <1ms pauses. - A 512MB heap with 500k heap-allocated []byte will have long pauses.
- steveklabnik 12y agoWhile I agree in the general case, I'm really excited to show off what Rust can do here. We've made some changes lately that make concurrent stuff safe that I'm not sure other languages can do. My favorite latest example: extern crate threadpool; use threadpool::ScopedPool; fn main() { let mut numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; { let pool = ScopedPool::new(4); for x in &mut numbers[..] { pool.execute(move || { *x += 1; }); } } println!("{:?}", numbers); } This allocates a mutable array on the stack, and then creates a threadpool which adds one to each element of the array, four threads at a time. We need the inner {}s so that we know that the pool is done working before we try to print the result. Yes, mutable pointers into the parent stack frame. But, the compiler can verify that this is absolutely safe. Say, for example, that we left off the inner scope, so that the pool might not be destroyed and therefore join before we try to print out the array. That'd be racy in most languages. In Rust, it's a compile-time error: error: cannot borrow `numbers` as immutable because it is also borrowed as mutable println!("{:?}", numbers); ^~~~~~~ note: previous borrow of `numbers` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `numbers` until the borrow ends for x in &mut numbers[..] { ^~~~~~~ note: previous borrow ends here fn main() { } ^ Rust knows that you're still holding a mutable reference to the array, and so taking a new immutable one could case a race. As you can see from the `extern crate`, this pool isn't a compiler built-in: it's a library. There's actually a secondary implementation of a threadpool that makes some different choices internally. But this kind of safety can be gained in whatever concurrent code you're writing, and you can write new concurrent abstractions and ensure that they don't have data races.
- BinaryIdiot 12y ago> Watching you "manual memory all the way" dudes struggle with simple concurrency as much as you do, I'd hate to throw away a GC just for that extra teeny bit of performance. reply I think you may have missed the part where I mentioned RAII. It's a lovely scheme in C++ and a handful of other languages. You can get away from manually managing memory entirely in C++14.