Live data from Hacker News

When static makes your C code 10 times faster

mazzo.li

81–90 of 113 posts

Re: When static makes your C code 10 times faster

#81
post #36
post #12

If I could travel back in time I'd tell Dennis to make "static" the implicit default, and have a special keyword like "public" or "export" for items that are meant to be accessible from outside the compilation unit. I'd also ask him to make "switch" break by default. Then I'd go kill Hitler or something.

No, even if you could kill Hitler, then WW2 doesn't happen, computers aren't invented yet, so time travel isn't invented yet so you can't head back to kill him. Read your briefing notes. Also https://tvtropes.org/pmwiki/pmwiki.php/Main/HitlersTimeTrave...

"Locating a lone, disillusioned war veteran wandering around post-WWI Europe is perhaps the ultimate needle-in-a-haystack search"

A time traveler shouldn't have a limit on time to search, so this doesn't make sense as an objection to me.

Re: When static makes your C code 10 times faster

#82
post #22

Division is slow, which is something most programmers don't know. If you can binary AND instead of MOD this can be a huge win. Multiplication is also very fast, usually one or two cycles on larger chips.

>Division is slow

I wondered if that's really still true, since I haven't done much assembly language programming since PowerPC was new.

Here, it says the M1 has 7-9 cycles latency for division instructions, but throughput of 2 cycles per.

https://dougallj.github.io/applecpu/firestorm-int.html

"The M1 is 10x faster than the Xeon at 64 bit divides. It’s…just wow."

So, given all of the other things that can slow you up, I wonder if it really makes sense to avoid division any more?

(I guess the energy efficient "Icestorm" cores have throughput equal to latency, so it's only the "Firestorm" ones where it's super fast)

Re: When static makes your C code 10 times faster

#83
More programmers really should have a look at what sort of assembly the compiler generates for their code. Compilers aren't magic, and seeing what sort of code it generates does give authors more insight into how concise their code truly is.

Re: When static makes your C code 10 times faster

#84
post #71

Earlier quoted context omitted.

This is one of those sayings that I don't think is helpful. What it should be is: limit variable scope to the smallest thing it can be. Nobody is being fooled about global state when you have a singleton database connection, event bus router, or network stack. I don't think your program is better when you pass in i/o functionality to every single class context in the constructor. Similarly a mega-class that encapsula…

I respectfully disagree on both points. > I don't think your program is better when you pass in i/o functionality to every single class context in the constructor. Abstracting over I/O transport is an excellent thing to do. This allows you to do things like easily record and replay a network stream. Which is useful for both debugging and automated tests. I/O comes in a kazillion flavors. Networked, interprocess, seri…

I agree with everything you said. Global variables also make it much harder to use multithreading. The mega-class is only bad if many parts of the code require references to it. In a well-structured program most subsystems will only need references to a few of the mega-class's (transitive) members.

Re: When static makes your C code 10 times faster

#85
post #39

Earlier quoted context omitted.

I quite like C syntax, and I sometimes long for a language that would change a few elements (default to const and static, different/safer standard api for strings). Some might call it Go but a simple slightly updated C would be nice.

Have you seen zig? It's a modern language that tries to keep the simplicity and explicitness of C (it does change the syntax a bit though).

I really wish Zig had followed Rust’s lead and made variables const by default :/

Re: When static makes your C code 10 times faster

#86

Earlier quoted context omitted.

You'd think the compiler would let you know you have a constant that is not labelled as such, like the way `tslint` complains about this incessantly. (I think `splint` for c/c++ may also do this, but I've only briefly used it.)

The compiler only operates on one unit (file) at a time so it has literally no way of telling this in C. There are legitimate uses for having a non-const global which is never modified by local source: library config options, hooks for external programs, and what not. As you say, this would be a job for the linter.

You can get pretty far with a compiler warning like "warn if a global isn't preceded by an 'extern' declaration". Also, LTO does have enough information to warn about these things, especially with default hidden visibility.

Re: When static makes your C code 10 times faster

#87

Link time optimization would enable a similar change even without a code edit. Using static is good, but it’s a good idea to figure out how to just let other people’s code run fast too.

Only if the value isn't visible outside the final image. This will still happen if it has "default"/dllexport visibility or its address is taken.

Re: When static makes your C code 10 times faster

#88
post #22

Division is slow, which is something most programmers don't know. If you can binary AND instead of MOD this can be a huge win. Multiplication is also very fast, usually one or two cycles on larger chips.

>Division is slow I wondered if that's really still true, since I haven't done much assembly language programming since PowerPC was new. Here, it says the M1 has 7-9 cycles latency for division instructions, but throughput of 2 cycles per . https://dougallj.github.io/applecpu/firestorm-int.html "The M1 is 10x faster than the Xeon at 64 bit divides. It’s…just wow." So, given all of the other things that can slow you u…

You shouldn't assume you're running on the performance cores. Not everyone is writing an app, and even if you are, most of your code will be better off on the efficiency cores.

Re: When static makes your C code 10 times faster

#89
post #71

Earlier quoted context omitted.

This is one of those sayings that I don't think is helpful. What it should be is: limit variable scope to the smallest thing it can be. Nobody is being fooled about global state when you have a singleton database connection, event bus router, or network stack. I don't think your program is better when you pass in i/o functionality to every single class context in the constructor. Similarly a mega-class that encapsula…

I respectfully disagree on both points. > I don't think your program is better when you pass in i/o functionality to every single class context in the constructor. Abstracting over I/O transport is an excellent thing to do. This allows you to do things like easily record and replay a network stream. Which is useful for both debugging and automated tests. I/O comes in a kazillion flavors. Networked, interprocess, seri…

There is one common situation where not using mutable globals is a recipe for complexity and a serious code smell. That case is when your internal structures directly control the physical resources of the machine. There is no amount of window dressing that can make these anything but global structures because that is what they literally are. That gets hidden a bit if you delegate resource management to the OS but you can’t do that if you care about performance.

And if you are creating and scheduling all of your concurrency in user space, which is common for some types of server software, then passing what are effectively global objects down the call stack becomes a real mess and introduces a number of suboptimal behaviors in the code gen.

I’ve seen people try to design database engines, the high-performance kind that directly manage all the resources they use, that don’t use globals in a misguided attempt to adhere to this heuristic. The end result was a convoluted mess of indirection that just obscured the reality that all of those objects were mutable globals. If you care about performance then I/O isn’t very abstract; the code knows exactly what kind of device it is dealing with.

I don’t like mutable globals as a general rule, but for some types of software they are unambiguously the correct engineering choice and not using them would be a design defect.

Re: When static makes your C code 10 times faster

#90

Earlier quoted context omitted.

Have you seen zig? It's a modern language that tries to keep the simplicity and explicitness of C (it does change the syntax a bit though).

I really wish Zig had followed Rust’s lead and made variables const by default :/

Variables are immutable by default in Rust, but they're not const by default. The difference is that a variable can become mutable while a const is always immutable.
Post reply on HN