Hacker News new | ask | show | jobs
by cbd1984 4125 days ago
C is simple to compile into nearly-optimal code, or at least it was back in the 1970s, when computers had single-opcode dispatch or trivial pipelines, no SIMD hardware, no other parallelism worth mentioning, and it wasn't worth worrying about cache too much. (Running in the registers was a neater trick.)

That meant it was relatively simple to 'see' the assembly language 'behind' a given C function or stretch of code; it didn't take much to get inside the head of a C compiler, so you could be reasonably sure that a simple piece of C would result in a similarly simple piece of assembly out the other end.

That, of course, was well and good when it was reasonably simple to predict actual performance from glancing at assembly code, which assumes opcode performance (as opposed to, say, cache performance) dominates how fast the code runs.

Now... how many of those things still hold true on desktop and server class hardware?

2 comments

But everything that came after C hasn't improved on this, at all. In fact, languages now dominate that aren't compiled.

So as it stands, C is still your best bet when you are looking for that optimal translation. Intel has recently made some effort to augment it in ways to fully utilize new CPUs various parallel pipelines and specific functionality:

https://ispc.github.io/

ISPC is cool, what it helps out with (writing the SIMD kernel) has never really been the bottleneck in my experience.

The data still has to be arranged optimally for the hardware in order for SIMD code to have any benefit (and at this point, writing SIMD code is straightforward). You also still need to be experienced with the capabilities of the hardware if you have any chance of writing good ISPC code (although this is true of C, as well as any shading language).

That said, using it to target SSE and AVX with the same code is attractive.

"C is simple to compile into nearly-optimal code, or at least it was back in the 1970s,"

And yet the best practice of the time was not to use C for time-critical applications. If your hypothesis were true, why would, say, all those NES programmers write all that assembly?

He means it was nearly-optimal on its original target, the PDP 11.

It was decidedly not nearly-optimal a few years later on microprocessors like 8080, z80, 6502, etc., which were highly register starved, 8-bit rather than 16-bit, non-orthogonal instructions and registers, etc.

As for "not to use C for time-critical applications", both then and now people sometimes write critical inner loops in assembly, it's just less common now because compilers are much more sophisticated.

But C was indeed used on "time-critical applications", aside perhaps from inner loops, back in the 70s, certainly on PDP 11s, and sometimes on less ideal microprocessors.

> why would, say, all those NES programmers write all that assembly?

Several reasons. First and foremost, things like that were highly RAM starved by the standards of the day. The PDP-11/70 had 64k of instructions and a separate 64k of data per process, with a total amount of RAM of up to something like a megabyte.

The NES had 2k RAM onboard -- although cartridges could extend that -- and the register starved 6502.

Another big reason is that, in every era, games are always pushing the limits of the hardware, and developers were typically quite willing to code in assembly if they believed it would give them a 20% edge in speed or decrease in space.

But also there was a mythos (that hasn't completely disappeared) that assembly would yield vastly more than 10%-20% speed increase over high level languages of the day, including C, so for most developers, they never even considered anything but assembler.

It also was not uncommon at the time for many of those game programmers to only know assembler, and not any other language except perhaps Basic.

The availability of C compilers for various platforms was not so universal then as it is now, especially on non-Unix systems, and the non-Unix C compilers, when available, were not necessarily at the same level of quality as the Unix C compilers.

Last but not least, C had not yet taken the world by storm, and a lot of those developers and companies had never even heard of C, and the ones that had heard of it were pretty dubious, more often than not.

> Last but not least, C had not yet taken the world by storm, and a lot of those developers and companies had never even heard of C, and the ones that had heard of it were pretty dubious, more often than not.

Specially since some of us were exposed to languages (Modula-2, Turbo Pascal) that were more feature rich than C while allowing similar performance levels on the same systems.

Certainly, although of course it depends on which range of years we're talking about, and which platforms we're talking about; you're talking about later years than PDP 11 C and more capable platforms than the "NES" mentioned above.

Prior to Turbo Pascal there was UCSD Pascal, which was extremely popular but not high performance.

But the whole idea that any high level language could be even close to competitive with assembly was a very radical idea considered laughable by the mainstream, for many years, which I think is the underlying idea here.

Another language worth mentioning is Bliss, a pioneering high level systems programming language roughly contemporary with early C, with high levels of efficiency and optimization, and was famous in some circles but not with the mainstream.

As I recall, that one eventually dropped by the wayside because it was too closely tied to DEC architectures. It may or may not have been ported to others, but it did not have (relatively) easy portability as a feature anyway, unlike the Johnson C compiler, which is often claimed to be the first such.

I wasn't a Turbo Pascal user, but wasn't it, too, tied to the one platform?

Wirth's languages after Pascal, I dunno; everyone heard of them but they were never that widely adopted. I guess I'm unclear on why.

> But the whole idea that any high level language could be even close to competitive with assembly was a very radical idea considered laughable by the mainstream, for many years, which I think is the underlying idea here.

From the papers I used to dig during my degree, I would assume Algol derivatives were already quite competitive, given that quite a few OS were implemented in them.

> I wasn't a Turbo Pascal user, but wasn't it, too, tied to the one platform?

Yes, to the PC. I eventually moved into C++ as time came to move along to more portable languages, as C was too primitive for my taste and I had just got hold of Turbo C++.

> Wirth's languages after Pascal, I dunno; everyone heard of them but they were never that widely adopted. I guess I'm unclear on why.

I was lucky to discover Oberon, and to use the Native PC version.

It opened my eyes that is it possible to have workstation OS done in GC enabled systems programming languages.

It also made me research Modula-3, Component Pascal, Oberon-2 and Active Oberon.

Coming back to the original point, back when coding for home computers, if performance was an issue, Assembly was the only option (Z80, 68000, x86).

For me, C was something I would see mentioned in some computer magazines about those new expensive UNIX workstations.

> I would assume Algol derivatives were already quite competitive, given that quite a few OS were implemented in them.

Yes, and PL/1 for systems programming in Multics and IBM systems, etc. (We won't count Burroughs since they literally designed the hardware to be programmed in Algol.)

That shows my comment was far too imprecise; it must have to do with different segments of the industry or something.

> back when coding for home computers, if performance was an issue, Assembly was the only option (Z80, 68000, x86).

Indeed.

> Another language worth mentioning is Bliss

I work with a former member of the DEC compiler team who brings up BLISS from time to time. One feature he liked was the control over register assignment, making it easy to keep frequently used variables in registers across function calls.

I'd be curious to know whether BLISS lives on at VMS Software, Inc. as they port to AMD64.