Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> I feel that we are far from zero cost abstractions now, though.

Why?

> Is it because the stacks in green threads is smaller than what C would expect ?

Yes.

> An interesting approach taken by Go here is to avoid calling C as much as possible.

Right, so this is a cost that they can pay. Rust cannot.



About the cost of skipping the libc:

Do you mean a human/development cost ?

Other than that, what would rust lose for not using the libc for system calls ?


steveklabnik was not saying that it costs Rust to avoid libc, he was saying that "calling C has high overhead" (i.e. the main underlying reason for avoiding libc) is not something Rust can do, given its goals. This also means there's not nearly as much reason to put the effort into reimplementing the libc abstractions on every platform.


About the cost of calling an async function synchronously:

You had a call to read(). Now you have a thread, an event loop, a pooling mechanism, and a synchronization with the thread. That's much more system calls and cpu cycles, for an synchronous async read()


Well no, if you don't explicitly run it in a thread pool?


Well, here's the actual wait method:

https://github.com/alexcrichton/futures-rs/blob/master/src/f...

Of course depending on your executor, the IO can be async or sync.


I can see a LOT of overhead here. Am I wrong ?

Have you ever ran a benchmark of a wait(async_read()) compared to just sync_read() ?


Can you explain how you run an async function synchronously, and how it has no overhead compared to calling a synchronous implementation of the same function ?


As far as the kernel-side implementation goes, IO is always asynchronous. The CPU is not involved in the actual movement of data between memory and the network interface.

When you make a synchronous syscall, the kernel initiates the operation, saves the state of your thread, and starts another one. When the network interface is done, it signals the kernel, which then marks your thread as runnable and schedules it for execution.

When you make an asynchronous syscall, the kernel initiates the operation but does not block your thread. This is usually done in the context of an event loop, which makes a synchronous syscall (like epoll_wait) when it runs out of tasks to run.

Thus, converting a single async syscall to a sync one means two syscalls: initiate the operation, then wait for its result. The extra round trip between user and kernel mode is basically free in this case because you're blocking on IO, and any logic it implements has to happen in the synchronous case anyway.


You are side-stepping the question by explaining how scheduling works.

You can not say that there is NO overhead. Using async code in a synchronous fashion is not going to be as fast as using plain sync code.

Look at the wait() function: https://github.com/alexcrichton/futures-rs/blob/master/src/f...

All this code IS overhead that wouldn't exist if the code was synchronous in the first place.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: