Remix.run Logo
nananana9 2 days ago

> the thread sleeps until ready and the kernel abstracts it away.

Sure, but once you involve the kernel and OS scheduler things get 3 to 4 orders of magnitude slower than what they should be.

The last time I was working on our coroutine/scheduling code creating and joining a thread that exited instantly was ~200us, and creating one of our green threads, scheduling it and waiting for it was ~400ns.

You don't need to wait 10 years for someone else to design yet another absurdly complex async framework, you can roll your own green threads/stackful coroutines in any systems language with 20 lines of ASM.

groundzeros2015 2 days ago | parent | next [-]

1. Why can’t we have better green threads implementations with better scheduling models?

2. Unchecked array operations are a lot faster. Manual memory management is a lot faster. Shared memory is a lot faster.

Usually when you see someone reach for sharp and less expressive tools it’s justified by a hot code path. But here we jump immediately to the perf hack?

3. How many simultaneous async operations does your program have?

vlovich123 2 days ago | parent [-]

Well, if you offload heavy compute into an async task, then usually it depends strictly on how many concurrent inputs you are given. But even something as “simple” as a performance editor benefits from this if done well - that’s why JS text editors have reasonably acceptable performance whereas Java IDEs always struggled (historically anyway since even Java has adopted green threads).

ptx 2 days ago | parent | next [-]

Are you sure Java's UI issues are caused by threading and not just Swing being a glitchy pile of junk?

For example, if you don't explicitly call the java.awt.Toolkit.sync() method after updating the UI state (which according to the docs "is useful for animation"), Swing will in my experience introduce seemingly random delays and UI lag because it just doesn't bother sending the UI updates to the window system.

vlovich123 2 days ago | parent [-]

only netbeans is written in swing . Eclipse and Jetbrains use their own thing and still generally struggled.

ptx 2 days ago | parent [-]

No, JetBrains use Swing in IntelliJ IDEA. You can tell from how it (for example) fails to layout dialogs correctly the first time they're displayed, just like every other Swing application. And how windows have no minimum size because Swing doesn't expose that functionality. And the various baffling bugs involving window focus that are inherent to Swing applications.

Eclipse uses SWT instead, which wraps the platform's native widgets.

mike_hearn a day ago | parent [-]

When did you last use IntelliJ, 30 years ago? I've never seen it fail to lay out dialogs correctly, windows do have minimum sizes, and I haven't seen any focus bugs.

groundzeros2015 2 days ago | parent | prev | next [-]

You think IDEs are written in JS because of the performance benefits of the threading model?

I thought it was because they could copy chromium.

vlovich123 2 days ago | parent [-]

Why do you think they don’t struggle with input latency? Because the non blocking nature built into the browser model is so powerful and you cannot get that with threads.

groundzeros2015 2 days ago | parent | next [-]

I disagree with the premise. I cannot imagine a better latency experience than blocking loop IDEs like VS6.

Which inputs are getting latency? The keyboard? The files?

> the non blocking nature

https://youtu.be/bzkRVzciAZg?si=BuBXxHTgN0OqsAhI

vlovich123 2 days ago | parent [-]

Hate to break it to you but windows gui programming, emblemified by VS6, is about as far away from a blocking threaded model as you get. You literally have a UI event loop and any compute intensive work is meant to be offloaded to other threads via messages/COM. This is why when they failed to do that correctly the entire UI would lock up - because they didn’t have good hygiene around how to offload compute intensive operations that also interacted with the GUI.

You’ve literally argued against yourself without realizing.

groundzeros2015 2 days ago | parent [-]

Wait which programming model are you arguing is the low latency one? I thought you said it was JS because non-blocking.

vlovich123 18 hours ago | parent [-]

Event loops are also non blocking. That’s literally why JS is non blocking. But event loops and callbacks are extremely hard to scale and maintain and keep non blocking. That’s why async/await is a more powerful abstraction - you don’t pretend I/O is this blocking thing, you interleave other work while it’s being done, and you don’t get impossible to follow callback hell. VS6 suffered from non responsive hangs all the time because some developer forgot to offload something that turned out to be compute heavy under certain conditions.

vlovich123 14 hours ago | parent [-]

Also, the parts they couldn’t make non-blocking (eg file reads) were precisely where VS6 would shit the bed and hang the entire UI trying to open a large file.

usrnm 2 days ago | parent | prev [-]

Are you sure that latency-sensitive parts are written in async JS instead of having a separate UI thread (pool)? I have no idea myself, but without knowing the details it's hard to argue. Note, that browsers themselves, are usually written in languages like C++ or Rust. They run JS, but aren't written in it

pjmlp 2 days ago | parent | next [-]

Yes they are, the UI layer is mostly JS, outside the rendering and layout engines.

spwa4 2 days ago | parent | prev [-]

If you implement threads and code that reacts to an input queue (e.g. PostMessage, queue_push, mq_send, ...), you've implemented (probably a bad version of) async threads. And yes, that's exactly what Windows 1.0 did and what made it great.

But God help you if you have to change the code. Async threads are a way to organize it and make it workable for humans.

PunchyHamster 2 days ago | parent | prev | next [-]

Maybe you remember performance of IDEs from 15 years ago because that definitely isn't my experience.

jcelerier 2 days ago | parent | prev [-]

> that’s why JS text editors have reasonably acceptable performance

Absolutely not

fulafel 2 days ago | parent | prev [-]

You involve the kernel also when you are doing async io.

In this context the interesting thing to measure would be doing IO in your green threads vs OS threads.

A stronger theoretical performance argument for async io is that you can do batching, ala io_uring, and do fewer protection domain crossings per IO that way.

a day ago | parent | next [-]
[deleted]
audunw a day ago | parent | prev [-]

Well yeah of course, using APIs io_uring and grand central dispatch is basically the whole point of all this async stuff in a systems programming language. It’s absurd it hasn’t been mentioned more here.

OS Threads are for compute parallelism, async with stackless coroutines (ideally) or green threads is for IO parallelism. It’s pretty straight forward.

And IMO, Zig has show how to do async IO right (the foundational stuff. Other languages could add better syntax for ergonomics.

nananana9 a day ago | parent [-]

It's not the whole point, there's lots of other (albeit smaller) gains to be had once you have a strong async apparatus.

The core of your async implementation doesn't have to care about I/O - as long as it has a way to block/schedule fibers, it's easy to implement io_uring/IOCP based I/O on top of that - it's a matter of sticking a single IO poll in your main loop, and when you get a result, schedule the fiber that's waiting for it.

Another thing you get almost for free is an accurate Sleep(0.3) - your Sleep pushes the current fiber in a global vector with the time to be resumed, and you loop over that vector in your main loop.

We're writing a game engine so WaitForNextFrame() is another useful one - the implementation is literally pushing the current fiber to a vector and resuming it the next tick.