BLU Discuss list archive


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Discuss] Port Scanning



> On 8/6/24 14:53, markw at mohawksoft.com wrote:
>> I call BS on that whole paragraph. Rust is OK, but ANYTHING you can
>> write
>> in Rust can be written to be faster in C/C++.
>
> Both are compiled languages, frequently using related compilers. Both
> are going to approach as-fast-as-possible. Theoretically.

There are many "compiled" languages, but compilation is not necessarily
optimization.

>
> The practical is going to be different.
>
>
> Practical case 1: Rust's advantage.
>
> There are various reports of programmers with years old, very familiar,
> finely optimized C/C++ programs, deciding to rewrite in Rust, sometimes
> as a first Rust project, and having the na??ve Rust program be
> significantly faster than the mature C/C++. In digging a little these
> all seem to be due to Rust "std" library having some very well written
> data structures that are both very fast and, because of the way Rust
> does generics, very easy to use with the data that are sitting around
> the old C program.

I've been programming in "C" since 1984 and C++ very soon after
Stroustrup's book. To be honest, I've never been at a company that used
standard libraries. They are always written to be too generic. In the old
Windows days, the memory management was difficult with segmentation (x86)
or selector (x286). In big projects, you generally don't use standard
libraries, the vagaries and different implementation are sometimes a risk.


>
> There is no reason these fast std data structures could not be written
> in C/C++, and be as fast, but Rust has a practical advantage here, at
> least some of the time.

Like I said, big projects tend to write their own or use more
optimized/specialized libraries.

>
> A freaky thing about Rust libraries is it is common for the exact same
> "crate" (as Rust calls libraries) to be maybe used in a tiny embedded
> machine with no OS, inside an OS kernel, in some big container in the
> cloud, inside a "smartphone", in browsers via WASM, or running on the
> zillion CPUs of some some gigantic cluster that we call a
> "supercomputer" these days.

How is that "freaky?"
>
> Not just core stuff, as C/C++ programmers do with something like
> strncpy() in glibc, but maybe an obscure open source crate created by
> some programmer in Nebraska, it doesn't have to be in std. (In fact the
> tiny embedded is likely "no_std".)

The over all performance of a "program" has very little to do with the
higher level language used. Languages like python, perl, and what ever
glue together libraries written in C/C++ or even assembly.

The high level language makes no difference (A code profiler proves this.)
The routines that are called most often or do the core work tend to take
99% of the processing time.

>
>
> Practical case 2: Rust's Advantage.
>
> Moore's Law has been sputtering and clawing and *barely* wheezing along
> for years now. Computers have gotten faster by doing more and more
> cacheing, and by having more CPUs. For multiple CPUs, with view to
> shared RAM (clever cacheing), multi-threaded programs can be screaming
> fast.

There are a number of assumptions that are more complicated than
presented. My main argument is that hardly anyone really understands
"multi-threading."  It is harder than inexperienced engineers think. I'm
not talking about "bugs" I'm talking about how to actually prarallelize an
algorithm. It doesn't matter what language you use, if you don't
understand this, nothing will help.

A few quick examples:

False prarallelism is the biggest problem. If you lock a resource for
longer than you need to, you are not going to see much improvement no
matter how many threads you use.

On a large system you may have two or more CPU chips, these systems
usually have a NUMA architecture where CPU1 has access to local RAM, CPU2
has access to its local RAM. If CPU1 needs to access memory local to CPU2
there is a series of bus synchronization operations where the memory is
copied or accessed by the adjacent CPU. A well tuned algorithm could
perform poorly if you don't use processor affinity with your threads.

Virtual memory thrashing. Organizing the memory layout of your program
with an eye to keeping memory in as few virtual memory pages as possible.
This allows fewer page faults.

When to use a mutex or when it is better to use an atomic variable. While
a mutex is an explicit lock, and "atomic" variable relies on the processor
for synchronization. In older versions of the x86 (80386 and higher)
issuing the "lock" prefix before an operation would assert a memory
bus/cache lock. Newer intel type processors, in the last 10 or so years,
have a much better cache invalidation system, but I'm not sure about ARM.



>
> It is handy that writing a multi-threaded program in C/C++ is easy. The
> catch is that maintaining a multi-threaded program in C/C++ is???kinda
> impossible. Too much of a multi-threaded "program" is in the comments,
> explaining key relationships to the next programmer (or same programmer,
> if the programmer and project both survive long enough).

I'm sorry you've seen code like that. Generally a "thread" in a C program
should be represented by structure that is passed to all functions that
need the thread's context. In C++, you'd use an instance of a class.

Very rarely have I seen multithreaded where it is a complicated affair.

>
> So multi-threaded programming needs to be approached carefully, and with
> discipline to not do dangerous things that might start out okay but will
> inevitably turn into?? bugs??????nasty, subtle bugs. At least for C/C++.

Well, if you think there exists a multithreaded environment where you
NEVER need to worry about threads, you are simply incorrect. Even the most
thread aware language will need to understand access to various resources.

>
> Rust is different. For beginners Rust is can be annoying, as the
> compiler insists on lots of extra detail that isn't needed in a C/C++
> program. But all that extra detail *is* also in the C/C++ program, but
> it is just in the comments. For the programmer to maintain and obey.

Why is the parser so stupid? Why does one need to use "fn" before a
function. That was kind of eliminated in the 70s. What about "let" are we
using BASIC now? Even python doesn't need "let." Its just stupid.

>
> Because Rust insists the programmer tell the compiler these things, the
> compiler will help out and prevent a range of bugs. They simply won't be
> there. This doesn't make Rust faster, per se, but it can allow Rust
> programmers to be much more aggressive about how they use multi-tasking,
> to do things that would be reckless in C/C++. And in that can be
> significant speed.

This is totally untrue and ridiculous. There is a very detailed and
documented set of rules around types and type conversion. There is no
ambiguity to the compiler.

Multithreading has its own set of bugs that are outside the realm of
normal idiocy.

>
>
> Practical case 3: C/C++'s advantage.
>
> C/C++ compilers are more mature, so there are better optimizers for
> C/C++ programmers. This is an advantage for C. Though, not always:
> sometimes the machine code will simply be as fast as it possible, and
> sometimes Rust will be that fast, making it a wash. But on average, at
> least for the moment, C/C++ has the advantage.

C has the unique advantage that the primitives correspond to typical CPU
operations and that just about anything written in C has a readable
analogy in processor assembly. When C optimizes stuff, it can get near
assembly efficiency. Furthermore, constructs list "switch," can be really
optimized to a jump table.

>
>
> Future Case
>
> I don't hear others talking about this, and I might be wrong (would
> anyone here expect me to ever be wrong??), but because the Rust compiler
> has more information about the program than does the C/C++ compiler, and
> because it compiles both the "program" and the libraries, I expect the
> Rust compiler should be able, in the future, to optimize on a larger
> scalem and get better results. But I might be wrong. (Me??????)

I can't tell you how many times I've heard this exact same argument for java.

>
>
> A Why: "Zero Cost Abstractions".
>
> Rust has lots of cool features that one would expect in, say, Python.
> And Python is a pig. Fat and slow. And though you might expect those
> features to make Rust slower, you would be wrong.

This goes back to my point that the high level language doesn't make a
difference.

>
> Rust is a strongly typed, compiled language. It has a compiler that is
> picky as hell (though also helpful in its complaints). They push this to
> the extreme. All of these features that seem like they would be slow are
> implemented at compile time. By the time the machine code is emitted,
> there is no speed penalty. Rust is obsessed about this.

You can't use "early binding" i.e. compile time optimization, to optimize
run-time operation.

>
> If you can get Rust to do the array index computation (iterators and the
> like), it trusts its own index math, there will be no runtime checks to
> slow down array access, yet the result is still safe array access, as if
> there were runtime checks.

There must be run-time checks on dynamically allocated arrays if you want
protection.
>
> Yes, there are ways to slow down a Rust program. If you have to do some
> chaotic array accessing there might not be a way to get Rust to do that
> for you, in which case you can choose to have those accesses have a
> runtime check, and that will take a little speed. Or, you could decide
> to do unchecked array access (the "unsafe {}" feature is useful). Or,
> maybe be a little more clean, figure out how to put your index
> computation in as clean a little package as possible, prove it up and
> down that it is correct, and kind of simulate Rust's trust of its own
> index calculations.
>
> Similarly, there is no speed penalty of doing runtime dispatch unless
> the programmer decides to do so. Maybe there are code size
> considerations, and runtime dispatch can be smaller, maybe some key
> stuff decides to fit in a small cache that way and the result is faster
> even with the extra indirection. Cool. But the programmer chooses.
> Aren't vtables part of C++? Okay, same idea, it costs a little, not a
> lot. Nice to be able to choose. That is the level Rust is at, they sweat
> runtime dispatch and avoid it by default.
>
> Rust is that way all along. Every feature is designed to be as fast as
> is theoretically possible, the price for those fancy features is paid at
> compile time, not runtime. Zero cost abstractions.


This sounds like a great debate. I'm not a fan of rust.