Live data from Hacker News

C Is Not a Low-Level Language

queue.acm.org

251–260 of 326 posts

Re: C Is Not a Low-Level Language

#251
post #83

Earlier quoted context omitted.

When a lie gets repeated enough times, eventually it becomes a fact.

It's just practical. Otherwise how do you call java ? Or python ? And what would be the benefit of changing those particular sementics ? In french we define such article as "fucking a fly".

Java and Python are much closer to C than C is to assembly.

Managing memory and raw pointers are nothing. Try implementing a recursive function call in x86 assembler to get a real idea of low level.

Re: C Is Not a Low-Level Language

#252
I hate the idea of "low-level". There is not really such a thing. You should be using a language suitable for the domain your working in.

Sadly, too many programming languages try to be the end all be all. C is language that is great for working at the system domain.

Ideally, we would have small minimalist languages for various problem domains. In reality maintaining and building high quality compilers is a lot work. Moreover, a lot of development will just pile together whatever works.

That aside, you could build a computer transistor by transistor, but it's probably more helpful to think at the logic gate level or even larger units. Heck even a transistor is just a of piece of silicon/germanium that behaves in a certain way.

So there are levels abstraction, but is an abstraction low-level? I think term probably came about to refer lower layers of abstraction that build what ever system your using. So unless your using something that nothing can be added upon. Everything, even what people would call high level can be low-level.

Heck, people call JS a high level language, but there are compilers that compile to JS. This makes a JS a lower level system that something else is built upon. This just again shows why I would say that low-level is often thrown around with connotation that is not exactly true.

Re: C Is Not a Low-Level Language

#253
post #123

Earlier quoted context omitted.

What's the word that comes after 'JIT'?

What the word is not really important. JITting is also called "dynamic translation", which is what a CPU does with microcode. Whether that's a full compiler or not is beyond pedantic -- and irrelevant to the parent's point.

The parent is telling me how the JVM doesn't have a compiler, which was my claim. It has a couple full-blown compilers.

which is what a CPU does with microcode.

Either you know something about current x86 CPUs that I don't or words and technical terms are, indeed, not important and have no meaning.

Re: C Is Not a Low-Level Language

#254

Earlier quoted context omitted.

There's not that much overlap between the kind of optimizations that JITs do and the optimizations that modern CPUs do. The promise of JITs outperforming AoT compiled code has never really materialized. The performance advantages of OoO execution, speculative execution, etc. are very real and all modern high performance CPUs do them. Attempts to shift some of that work onto the compiler like Itanium and Cell have lar…

arguably the "sufficiently advanced compiler" (cue joke) has arrived (sadly, post Itanium, Cell) in the form of a popularized LLVM[0], so it's improper to claim failure based on two, aged datapoints. The flaws of OOO and SpecEx are evident with the overhead required to secure a system (spectre, meltdown) in a nondeterministic computational environment, and there is certainly a power cost to effectively JITting your c…

OoO and speculative execution are largely improving performance based on dynamic context that in most real world cases is not available at compile time. They are able to do so much more efficiently than software JITting can due to being implemented in hardware. There is still no sufficiently advanced compiler to make getting rid of them a good strategy for many workloads.

Most of what OoO and speculative execution are doing for performance on modern CPUs is hiding L2 and L3 cache latency. On a modern system running common workloads it's pretty unpredictable when you're going to miss L1 as it's dependent on complex dynamic factors. Cell tried replacing automatically managed caches with explicitly managed on chip memory and that proved very difficult to work with for many problems. There's been little investment in technologies to better use software managed caches since then because no other significant CPU design has tried it. It's not a problem LLVM attempts to address to my knowledge.

Other perf problems are fundamental to the way we structure code. C++ performance advantages come in part from very aggressive inlining but OoO is important when inlining is not practical which is still a lot of the time.

Re: C Is Not a Low-Level Language

#255
The meta point from the article is that this is as much a hardware problem as it is a language or developer one. An arms race was waged to create CPUs that are very effective in running sequential programs; to the point that what they present to the program is a very much a facade and they hide an increasing great deal of internal implementation detail. By David's postulation, even the native assembly language for the CPU is not low level.

To drive this juxtaposition home, I'd point to PALcode on Alpha processors in which C (and others) can very much be a low level language. Very few commercial processors let you code at the microcode level.

The overarching premise is then brought home by GPU programming, which shows that you don't necessarily need to be writing at the ucode level if the ecosystem was built around how the modern hardware functioned.

Re: C Is Not a Low-Level Language

#256

This article makes some valid points but is overall rather misleading I think. Almost all of the reasons given why C is "not a low-level language" also apply to x86/x64 assembly. Register renaming, cache hierarchies, out of order and speculative execution etc are not visible at the assembly / machine code level either on Intel or other mainstream CPU architectures like ARM or Power PC. If C is not a low level languag…

By David's postulation, even the native assembly language for the CPU is not low level. See my other comment on the parent topic for justification.

Re: C Is Not a Low-Level Language

#257

Earlier quoted context omitted.

What's wrong with their memory model? Honest question.

the jvm lacks structs and more specifically arrays of structs as a way to allocate memory. this causes extreme bloat due to object overhead as well as a ton of indirections when using large collections. the indirections destroy any semblance of locality you may have thought you had which is the absolute worst thing you can do from a performance perspective on modern processors. what people end up doing instead is mak…

There's a proposal to fix this by adding value types to the JVM. It's part of something called “Project Valhalla”.

http://jesperdj.com/2015/10/04/project-valhalla-value-types/

Re: C Is Not a Low-Level Language

#258
post #51

Earlier quoted context omitted.

It also hides the fact C is just a couple notches above the absolute minimum most people would even consider - writing assembly code by hand - and is, effectively, the lowest most programmers will ever venture.

True, but one of the points the article makes is that in practice, there's a vast gulf of distance (person-years of C compiler development) between the C code one writes and the resulting assembly code output (and this is ignoring the fact that x86 assembly is, itself a co-evolved abstraction with C-like languages that is basically emulated on modern massively-parallel CPU architectures). In that regard, a case can b…

> In that regard, a case can be made that when you're writing in C, you're writing exactly as close to the bare metal as if you're writing in, say, Go or Haskell.

No, you really can't. This is childish black and white thinking. The computational model of C is built on an interface exposed by the hardware. Go and Haskell build many additional abstractions on top of that same model.

This article could have had a fruitful discussion about what the author is trying to say, but by choosing such a clickbait title, he managed to turn it into a discussion on semantics that wants to deny useful distinctions, because in some context (not the context in which it's actually used), it doesn't fit.

This kind of linguistic wankery really pisses me off, because it's useless and rests on a misunderstanding of how people actually use language (which is to say, in context and often in relative terms).

Re: C Is Not a Low-Level Language

#259
post #167

Earlier quoted context omitted.

Right, and the point I'm trying to make is this is a pretty lousy analogy. For one thing, an x86 CPU is not nearly as VM-y as you make it out - renamed registers are very much real registers, big piles of the most common instructions execute in 1 or 2 uOps. For another, the VM you've picked as an example is singularly uncpu-like. C also exposes an abstract machine, would you use that as an analogy? Probably not. 'An…

I don't know I think you're getting caught up too much on the specifics of what they're doing. CPU's are adopting JIT like tendencies in order to increase performance. Instruction reorder, register renaming, branch prediction, etc. > if you squint but offers somewhere between zero and negative insight. The insight I bring from this is that we should look moving those features out of the hardware and into the software…

"x86 is an architecture hobbled by its legacy ISA, the CPUs are immensely complex VM-like dynamic beasts that hide the real CPU to get performance out of it" is one of those tropes that's inaccurate enough to have a small cottage industry of online pieces explaining the wrong bits. You can probably find highly rated SO answers or HN comments about it.

The long and the short of it is, an x86 cpu is not really VM-like and a JVM is decidedly unCPU like. The analogy only works if you generalize it so much it becomes a uselessly mushy tautology or you ignore basic aspects of how each of these things work.

Re: C Is Not a Low-Level Language

#260
post #6

Earlier quoted context omitted.

It is very important to emphasize that GPU's only "achieve high performance" in workloads tailored very specifically to their extremely limited architecture. CPU's, on the other hand, are designed to be much more generic with decent performance for any task.

I think it's more accurate to say that CPUs are high-performance for different tasks than GPUs. Simple code, very wide data workloads are atrociously slow on CPUs, and single-threaded heavily branching workloads are atrociously slow on GPUs. That doesn't mean that one is more limited than the other.

The whole point of the article is that this is largely a myth imposed by the memory model of C and C-like languages. Single-threaded heavily branching workloads would be atrociously slow on modern CPUs, if not for branch prediction (which caused Spectre). On modern processors, you have 180 instructions running in one thread.

The processor is doing an ok job filling these instructions, but a language and compiler can do a much better job. C doesn't collect any information about data dependencies, and instead just pretends all instructions are sequential. Even code which contains tight loops of sequential commands can be optimized, because you have an entire program and operating system running around that sequential code.

Post reply on HN