10 ms·
If you don't need to do bounds checking, and doing it anyway, then that's a step down from C.
by bayindirh 3y ago
If you don't need to do bounds checking, and doing it anyway, then that's a step down from C.
- mcfedr 3y agoBut isn't the point that the number of times a c programmer thought they didn't need bounds checks and reality are very different. Also off by one errors and such. Rust won't let you make these mistakes
- bayindirh 3y agoI personally don't think that a programming language should save me from myself unless I explicitly ask for it. For every case I first prove to myself that I can get away without bounds checking, otherwise if I'm in doubt, I put it in and profile. I think Rust is a nice language, but when it's presented as an "antidote" to "evils of C/C++", and is "indeed made to kill those" I lose my interest. Also, while I think learning Rust is worthwhile, I think promoting Rust's barriers as saviors are funny. We say that Apple's against general purpose computing with all its walled gardens. Then Rust is against "General purpose programming". I want to be able to write programs which crash and burn like meteors entering the atmosphere, because this allows me to understand the hardware under me. Promoting a walled programming language as "the one and only" is wrong. Why should I embrace a programming language as one and only if that doesn't allow me to do what I want with my computer? Edit: No, unsafe doesn't count, because it doesn't remove all checks.
- chatmasta 3y ago> Edit: No, unsafe doesn't count Why not? You can basically write C with FFI and unsafe. In fact that's how many "port to Rust" projects start. It seems directly analogous to the fact that you can disable SIP on macOS to escape their walled garden, into an "I know what I'm doing" mode.
- pjc50 3y agoMemory safety has become important enough to be a matter of national security: https://www.whitehouse.gov/oncd/briefing-room/2024/02/26/press-release-technical-report/ https://www.whitehouse.gov/oncd/briefing-room/2024/02/26/pre... > I want to be able to write programs which crash and burn like meteors entering the atmosphere Sure, fine, whatever, just as long as it's not used by anyone else. Production code needs to be held to standards.
- bayindirh 3y agoI'm a big proponent of choosing the right tool for the job at hand. On the other hand, I'm a big opponent of throwing stones because of emotions. C/C++ can be made memory safe. You need to use a couple of data structures and need to be a little bit more vigilant and make periodic tests. If the developers can't bother to learn them, that's fine. However, saying something is impossible and being adamant about that without research is harmful as it is. I sometimes say things about Rust, people correct me, and I learn. Some people see the evidence contrary to their beliefs and get triggered because they were wrong in the first place. This is what I'm bothered about. I don't use C or C++ only. I'm not against Rust either. I'm against positioning of Rust and C/C++ from Rust community's perspective. That's all. Lastly, I'm not a proponent of reckless coding either. Totally contrary. I take pride in writing robust code. However, I want to be able to write code which breaks on purpose to see what hardware does, to understand the failure modes or gotchas of the architecture I'm running on.
- Too 3y ago> C/C++ can be made memory safe. In theory, in small toy projects or with a massive NASA budget - Yes. In any other project, with normal (aka too short) time constraints and average skilled developers, it’s not. 35 years of trying, has proven us humans that, several times over.
- bayindirh 3y agoI think it's much simpler than that, because I did it myself, on a HPC scale high performance materials simulation code. Is it simple? Yes. It's easy? No, because you need to design for that and be mindful during implementation (const correctness, guarantees by design, valgrind tests, unit sealing, etc.). I think it can be made much simpler with smart pointers, etc. if speed is not that important. We push humans too much to develop things fast. C++ is not very conductive to that, yet it's the only tool which works in some cases. I won't retype my views about Rust because it's all over this thread. Just I'll tell that I'm against vilifying C/C++ as evil because they can be held wrong. I believe things can and shall be able to held wrong. Knowing failure modes and shortcomings is a plus. Because you can then hold dangerous things right, and appreciate things which promote holding things right.
- dmos62 3y agoWhich do you think is more efficient in terms of CPU resources, user-time, developer-time, money? Both development and the final program taken into account. On average.
- bayindirh 3y agoDepends on what you're building. If the code you're running is not resource intensive and relatively short-running, developer time is more expensive. However, if your program is long running and requires high performance (number crunching, simulations, HPC in general), %1 difference in tight loops affect your total runtime by hours, if not days. Then, user-time is much more expensive, hence you need more speed. Also, in this case you're maxing out ~100 servers in terms of power and TDP, so a shorter runtime has a bigger impact on your energy bill, and global warming. If I can run more users' code for the same power and time budget, and conclude more research, developer time to be damned. They can spend as much as time they like. Tech people tend to say developers are expensive and hardware is cheap. No it's not, if you're using it at its max capacity.
- shakow 3y ago> %1 difference in tight loops I'd love to see how you can reach this number. I hear a lot of people complaining about supposedly degraded performances due to bound checking; but IME, even on number crunching HPC code, I have never been able to get a signal greater than noise regarding bound checks, which can be explained by: (i) the prediction pipeline doing its job, (ii) iterators eliding bound-checks at compile time, (iii) bound checking being dwarfed by the actual computations within the tight loop. Remember to measure what you optimize for first before going on an intuition.
- bayindirh 3y agoDisclaimer: I'm an HPC admin and both develop code on these things and manage them. The code I have written was doing ~1.7M iterations per core, per second when I implemented it w/o bounds checking and locks. It was designed to be fast from the start, so I never tried bounds checking. I'm restarting the work on the code soon-ish, so I'll be writing a benchmark module for the thing. If you can provide me an e-mail address, I'll implement both, do the tests, and provide you the results, and we can discuss on it, too. Also, I'll see whether GCC-14 (or whatever comes next) is intelligent enough to eliminate bounds checks in these cases. The following part of the code [0], was running with much higher iteration numbers inside the "tight loop", but I never benchmarked it, because its iteration count is both inconsistent (due to adaptive nature), and was meaningless in the bigger picture (where 1.7M/sec/core number comes in). That code was never optimized before measurement, and the biggest bottleneck was memory controller at the end. I needed to reorder matrices to pass that hurdle, yet the Ph.D. was complete, and speed was adequate, so we didn't bother, TBH. [0]: https://journals.tubitak.gov.tr/elektrik/vol29/iss2/45/ https://journals.tubitak.gov.tr/elektrik/vol29/iss2/45/
- sunshowers 3y agoI do think, when it comes to professional-grade software, programming languages should save programmers from themselves -- even the ones who don't want to be saved.
- jeroenhd 3y agoVery little Rust code actually does all the safety checks that you would expect a debug build of that same program to do, especially in the kernel. You can write safe rust (check the Option<T> returned by vec.get(i)) but code like `p[0] = update_prob(d[0].into(), p[0].into()) as u8;` (https://gitlab.collabora.com/dwlsalmeida/for-upstream/-/commit/7681609641fb9c94a0b5d827dc2e7290401689c3#eef62635f4a18e96131ace643dc5dcb1dde2fbb5_0_1645 https://gitlab.collabora.com/dwlsalmeida/for-upstream/-/comm...) can panic at three different places. Such a panic would become a kernel oops, which wouldn't be the end of the world but it would probably kill whatever program was trying to decode video. With additional optimisation options, the bounds checking may even be omitted entirely. Rust does generate more accurate bounds checking warnings thanks to all the metadata it has, but that should not be solely relied upon. Rust will let you make those mistakes, but only sometimes, not usually like in old C or C++. I think it's important to know the difference, because feeling invulnerable to these bugs may lead you to write buggy code because you stopped thinking about common C bugs entirely. Also worthy of note is that because of a compiler bug, it's possible to leak memory and cause other weird memory bugs in perfectly safe Rust at the moment. It involves messing with lifetimes and semi-unsafe code so I doubt that bug would just sneak in, but the language doesn't make your code completely bullet proof.
- KerrAvon 3y ago> can panic at three different places Remember that some of the point here is that it _will_ reliably kill the program if that happens; in C, you might be silently reading or writing to the wrong address 3 times.
- Mateon1 3y agoThe `single_ref` field is a fixed-size array in both of the objects referenced in this line, so this line can't panic, and no bounds checks are involved (since the compiler sees the index < length at compile time and doesn't even need to emit one -- although I think it still does, and it's LLVM that gets rid of it actually) Causing memory leaks is possible in safe Rust even without any arcane invocations, you can construct a cycle of Rc<T> counted objects. There's even a perfectly safe Box::leak in the standard library that gives you a &'static reference to any object by leaking it. Preventing leaks is outside of the scope of Rust's safety system.
- estebank 3y agoIf you can assure that bounds checks are not necessary (either by construction, because it's a statically sized array, or by runtime check because you do a length check once at runtime), then doing those same things will tell rustc enough to know that bounds checks aren't needed[1][2]. If you think you don't need bounds checks, but can't communicate that in code, such as with an assertion (or if rustc had a bug that misses those checks, unlikely but could happen), then yes, you'll end up with bounds checks unless you use get_unchecked in an unsafe block. I'm failing to see how this is an onerous difference. 1: https://nnethercote.github.io/perf-book/bounds-checks.html https://nnethercote.github.io/perf-book/bounds-checks.html 2: https://github.com/Shnatsel/bounds-check-cookbook/ https://github.com/Shnatsel/bounds-check-cookbook/
- Aurornis 3y ago> If you don't need to do bounds checking, and doing it anyway, then that's a step down from C. The Rust compiler tries to optimize away unnecessary bounds checks. In practice, it works well. The real-world cost of Rust bounds checking isn't very significant in most benchmarks, aside from some synthetic micro-benchmarks designed to emphasize the issue. If you come across a hot loop in Rust where bounds checking is an actual overhead, you can manually optimize it out if you so desire. It's important to really check first, though, because it's often surprising that it makes such little difference or has been optimized out already.
- jcranmer 3y agoWho would you rather trust to do bounds checking, computers who are zealously good at doing what they are told to do to the point of absurdity or humans who are notoriously bad at following rigorous procedures? I mean, we've seen from several other fields that the only way to get the safety standards of human procedures up is to introduce checklists and get people to rigorously follow them [1]. If you want to elide bounds checks for performance reasons, which is easier: manually verifying for yourself that every single array access is guarded by a bounds check somewhere and ensuring that no subsequent code changes break this verification, or getting the compiler to prove for you that every bounds check can be safely elided? [1] And of course we still have several issues in fields like medicine where practitioners refuse to adopt this methodology because they find checklists to be an insult to their intelligence.
- bayindirh 3y ago> getting the compiler to prove for you that every bounds check can be safely elided? I'd prefer to delegate that where compiler if it can do that for that piece of code at hand. I've written about a case where it'd be very hard for a compiler to eliminate a bounds check because the guarantees are made elsewhere in the code. On the other hand, I'd rather add my bounds check voluntarily (it's very simple in C++ vectors for example. use ".at()" instead of "[]", that's all), because I generally design my code in a way which doesn't need bounds checks by failing hard and early at places where I build/fill the arrays/vectors and prone to malformation. So, you need to be well-formed to pass these checks, and these data structures are not modified ever down the pipe. If they are modified, they'll be bound checked of course. What I'm saying is, I'm not naive enough to believe that I'm perfect, but I'm not naive enough to believe that compiler is perfect, either. So, I do my part, and leave the parts I can't be sure to the compiler. I'm not an hard-liner. I just want finer control on my code, and take full responsibility if it crashes and burns in a way it shouldn't, so plan and implement accordingly.