Live data from Hacker News

Why is calling my asm function from Rust slower than calling it from C?

ohadravid.github.io

21–30 of 43 posts

Re: Why is calling my asm function from Rust slower than calling it from C?

#21
post #2

For example, before we had something like: top: *const FFISafe > We can change that to: top: WithOffset > rust, you were meant to replace c++, not join it...

> rust, you were meant to replace c++, not join it...

Turns out that not all of the C++ noise people make fun of is due to C++, sometimes the problems you want to solve with Rust or C++ is just hard to express simply to the compiler.

Re: Why is calling my asm function from Rust slower than calling it from C?

#22
post #2

For example, before we had something like: top: *const FFISafe > We can change that to: top: WithOffset > rust, you were meant to replace c++, not join it...

FYI to non-Rust devs wondering what's going on with this code: Those two abstractions (FFISafe and WithOffset) are not standard Rust abstractions. They're something the author is building within their own library: https://github.com/memorysafety/rav1d/blob/25e5574/src/ffi_s...

So for all of the complaining about Rust abstractions and syntax in this thread, keep in mind that these particular abstractions that caused this problem are not standard. If you just want to call an extern "C" function you can do so directly in an unsafe block. The article should be read as the author debugging their Rust wrapper types, not as a generic article about calling C functions from Rust.

Re: Why is calling my asm function from Rust slower than calling it from C?

#24
post #3

Not related to the topic, but seeing this tidbit in the article took me by surprise; > PSA: if you don’t see syntax highlighting, disable the 1Password extension. This linked to the following discussion that's been ongoing for over a week (with acknowledgement from 1password that they're looking into it but as far as can tell no ETA on the fix or explanation for why it's happening in the first place): https://www.1pa…

Yea i think this discussion was quite interesting as well. And i can also verify that this issue exists in Zen (firefox based) as well.

Re: Why is calling my asm function from Rust slower than calling it from C?

#25
post #19

Earlier quoted context omitted.

What's a language with zero complexity-cost abstractions?

Natural language. It's a language interpreted by LLMs. It is really high level.

Even that has lots and lots of abstractions which add complexity. For example, figures of speech such as "shooting fish in a barrel".

Re: Why is calling my asm function from Rust slower than calling it from C?

#26
post #15
post #12

Earlier quoted context omitted.

> But the point is that the exact same external library code has a _lower_ cost if called from the non-abstract horror of a language C, and the (partial) fix for that is really ugly looking low-level Rust crap that that took a _long_ time to figure out and is the exact opposite of an abstraction, and the full fix is not even known yet. No, it's not the exact same external library. There's an additional Rust library i…

> No, it's not the exact same external library. It uses the exact same assembly language. > There's an additional Rust library in between that they used, which provides the `FFISafe` type, and that has overhead. Look, I wrote " But the point is that the exact same external library code has a _lower_ cost if called [from C]" and that remains a true statement. It's pretty obvious that I was referring to the shared code…

> Look, I wrote " But the point is that the exact same external library code has a _lower_ cost if called [from C]" and that remains a true statement.

I don't think you've understood the article at all.

The overhead came from the author's own abstractions that were designed to accommodate both the assembly version or the Rust fallback. The assumption was that they take the same types and therefore the abstraction would be zero-cost, but in practice the Rust version had different types and therefore there was extra overhead in the way they were called.

If the author had simply done an extern "C" of the function and called it from Rust there wouldn't be overhead.

> To me, that looks like a high-cost non-abstraction.

The abstractions that caused this probably were not standard Rust library abstractions. The author wrote them as part of the library.

You don't need an abstraction at all to just call C functions from Rust. It's build right into the language.

If you think the problems in this article are a common Rust failure mode, you haven't understood the article at all. The unique method of calling C functions was something the author wrote, not a standard Rust practice.

Re: Why is calling my asm function from Rust slower than calling it from C?

#27
post #11
post #9

Earlier quoted context omitted.

It sounds like you're saying that you consider seeing this single instance of someone writing a library with a costly abstraction to be indicative of the entire language ecosystem not fitting the paradigm. This is kind of hard to take seriously; it's not like C++ doesn't have some costly abstractions as well way more embedded into the language itself (e.g. exceptions).

> someone writing a library with a costly abstraction That's not what happened here. > it's not like C++ doesn't have some costly abstractions This is simultaneously both completely orthogonal to my observation that the Rust FFI is borked, and a great example of a problem that wouldn't happen in C++, because in C++ you could completely ignore the costly abstractions if necessary.

> That's not what happened here.

Yes, it's what happened here. The article is about debugging the author's own abstraction types that had some incorrect assumptions.

You do not need these wrapper types to call C functions. If the author had removed the complex extractions and called the extern "C" function directly (as is standard in Rust) there would not be the additional overhead.

Re: Why is calling my asm function from Rust slower than calling it from C?

#28
post #5
post #4

Earlier quoted context omitted.

The point of Rust is ostensibly to provide a safer version of C++-like semantics, not necessarily to avoid the same level of complexity. Especially if you're directly using unsafe code (which is necessary in some cases, like FFI), it's not really clear to me that Rust was "meant" to be doing something wildly different here. The large majority of the code not needing to use unsafe will still be better off even if this…

This is all well and good, but "zero cost abstractions" implies, well, that you're crawling _up_ the abstraction pyramid, not lost in twisty little side passages.

"Zero cost abstractions" refers to some features of the language that provide functionalities with no runtime cost, e.g. (safe) iterators, not to a presumed simplicity of the whole language. Therefore, this is not mutually exclusive with the fact that certain concepts in Rust require more complexity than their counterpart in other languages (after all, the complexities of the borrow checker don't exist in C).

In general, and it applies to the referenced article, programming with a high level of control over the implementation is complex, and there's no way around it. This article explains the concept: https://matklad.github.io/2023/01/26/rusts-ugly-syntax.html.

Post reply on HN