Hacker Newsnew | past | comments | ask | show | jobs | submit | steveklabnik's commentslogin

Rust the language knows nothing about allocations. It’s purely a library concern.

For the time being, I consider alloc and std to be part of the language, and the compiler also has provisions for them if they are used. If the alternative is supposed to be only using core, then the language does not provide for control over allocations the way Zig does. Imposing allocations with no control and not providing allocations at all are both failure modes. With enough effort, anyone could do anything, but programming languages exist to control and enhance certain things under their purview. Rust does not have a comparable facility to control allocations like it controls ownership and borrowing. Just as C-with-tooling being safe isn't the same as C being safe, Rust-with-libraries providing control over allocations isn't the same as Rust providing control over allocations.

Things like the index become a workflow pattern, rather than a feature, if that makes any sense.

What were you trying to “revert back”? You should have been able to just stop using jj, there’s nothing to revert back to. It’s also possible that I’m misunderstanding what you mean.

It wasn’t implemented for the same reason. Rust uses C++20 ordering.

right, so I would expect that the equivalent of READ_ONCE is converted to an acquire in rust, even if slightly pessimal.

But the article says that the suggestion is to convert them to relaxed loads. Is the expectation to YOLO it and hope that the compiler doesn't break control and data dependencies?


There is a yolo way that actually works, which would be to change it to a relaxed load followed by an acquire signal fence.

Is that any better than just using an acquire load?

It is cheaper on ARM and POWER. But I'm not sure it is always safe. The standard has very complex rules for consume to make sure that the compiler didn't break the dependencies.

edit: and those rules where so complex that compilers decided where not implementable or not worth it.


The rules were there to explain what optimizations remained possible. Here no optimization is possible at the compiler level, and only the processor retains freedom because we know it won't use it.

It is nasty, but it's very similar to how Linux does it (volatile read + __asm__("") compiler barrier).


This is still unsound (in both C and Rust), because the compiler can break data dependencies by e.g. replacing a value with a different value known to be equal to it. A compiler barrier doesn't prevent this. (Neither would a hardware barrier, but with a hardware barrier it doesn't matter if data dependencies are broken.) The difficulty of ensuring the compiler will never break data dependencies is why compilers never properly implemented consume. Yet at the same time, this kind of optimization is actually very rare in non-pathological code, which is why Linux has been able to get away with assuming it won't happen.

In principle a compiler could convert the data dependency into to a control dependency (for example, after PGO after checking against the most likely value), and those are fairly fragile.

I guess in practice mainstream compilers do not do it and relaxed+signal fence works for now, but the fact that compilers have been reluctant to use it to implement consume means that they are reluctant to commit to it.

In any case I think you work on GCC, so you probably know the details better than me.

edit: it seems that ARM specifically does not respect control dependencies. But I might misreading the MM.


shouldn't it be preceded?

No, you want to sequence any subsequent loads to after the acquire/consume load.

C++20 actually [changed the semantics of consume](https://devblogs.microsoft.com/oldnewthing/20230427-00/?p=10...), but Rust doesn't include it. And last I remember compilers still treat it as acquire, so it's not worth the bytes it's stored in.

In the current drafts of C++ (I don't know which version it landed in), memory_order::consume is fully dead and listed as deprecated in the standard.

I use chrome btw.

It gets brought up because the conversation is not “is Firefox better than Chrome,” the conversation is about Rust’s multithreading guarantees. It’s just an entirely different conversation.

For example, your own beefs with Mozilla have nothing to do with the technical choices made by the code.


What abstraction do you refer to?

Rust is actually few steps above from the bare metal, to enforce its security invariants. Boundary checks (which breaks auto-vectorization of loops), stack probe, fat pointer (wastes register), fixed index type (uint), etc.

There are other hidden costs coming from usage of std. Even `Result` is a bit of inefficiency.

I'm not saying any of these are bad. I'm just saying Rust would be slower than C if *naively* used.


Okay, cool, I can see where you're going with this. I wouldn't exactly agree, because all of these things are stuff you can easily opt out of, but I thought you were maybe suggesting something like "the borrow checker has overhead" which I would take more direct issue with.

(and yeah, the opt out question gets right to what you're saying about "naively used", I saw "unavoidable" but you're not actually saying it's unavoidable.)


Specialization isn’t stable in Rust, but is possible with C++ templates. It’s used in the standard library for performance reasons. But it’s not clear if it’ll ever land for users.

You can use unsafe in Rust to write the exact same thing.

https://en.wikipedia.org/wiki/Safety-critical_system

A lot of people in the space just drop the “systems” when talking about it.


It’s not deliberate activism. It’s two things:

Monomorphizarion makes the GPL weird.

Rust is dual licensed under Apache/MIT, and so most people choose the same as a default if they don’t feel strongly about licensing.


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

Search: