Live data from Hacker News

C Is Not a Low-Level Language

queue.acm.org

171–180 of 326 posts

Re: C Is Not a Low-Level Language

#171

Ok, w/o dipping into machine code, show me a low level language. Any snippet of C-code is transparent in that you know roughly how it is going to be translated into machine code.

unsigned char r(unsigned char num) { return num % 10; } https://godbolt.org/g/26HfQk

Or compile this with clang and -msse4.2 -O2

    // https://codereview.stackexchange.com/questions/38182
    // https://codereview.stackexchange.com/a/38184
    // Definition: Count number of 1's and 0's from integer     with bitwise operation
    // 2^32 = 4,294,967,296
    // unsigned int 32 bit
    #include
    int CountOnesFromInteger(unsigned int);
    int main()
    {   unsigned int inputValue;
        short unsigned int onesOfValue;
        printf("Please Enter value (between 0 to 4,294,967,295) : ");
        scanf("%u",&inputValue);
        onesOfValue = CountOnesFromInteger(inputValue);
    
        printf("\nThe Number has \"%d\" 1's and \"%d\" 0's",onesOfValue,32-onesOfValue); }
    // Notice the popcnt
    int CountOnesFromInteger(unsigned int value) {
        int count;
        for (count = 0; value != 0; count++, value &= value-1);
        return count; }

Re: C Is Not a Low-Level Language

#172

TLDR: C was close-to-the-metal on the PDP-11 but since then hardware has become more complex while exposing the same abstraction to the C programmer. That means that hardware features such as speculative execution and L1/L2 caching are invisible to the programmer. This was the cause of Spectre and Meltdown and it forces a lot of complexity into the compiler. GPUs achieve high performance in part because their program…

I don’t understand. CPUs do not support C, they support a specific instruction set. What stops them from having instructions for cache management, pipelining, speculative execution hints, etc?

[deleted]

Re: C Is Not a Low-Level Language

#173
post #14

Earlier quoted context omitted.

I also had the initial impression that the article is misleading, but later on the author made the point that the C compiler is doing significant work to reorder / parallelize / optimize the code. I agree that x86/x64 is not a low-level language either, but even if it was, with the description the author provided, I'd agree with his point of C not being low-level. Regarding cutting off backwards compatibility to impr…

There was an article on Hacker News recently that covered some of the reasons for Itanium's failure to realize its theoretical benefits. I'm not finding it now, but IIRC, the argument made was that predicting likely-parallelizable code is actually a lot harder to do at compile time, and that, like so many ultra-optimized systems, the real world works much differently and a messier, more random approach ultimately yie…

> the argument made was that predicting likely-parallelizable code is actually a lot harder to do at compile time, and that, like so many ultra-optimized systems, the real world works much differently and a messier, more random approach ultimately yields far better performance.

I am not an expert on computer history, but my feelings on the matter are as follows:

It's hard for certain domains, like handling millions of web requests. For most computational stuff where you're just blowing through regularly-shaped numerical computation (like for example ML, or signal processing), it's not that hard, but arguably the compilers of the time were still not quite up to it (there's a lot of neat stuff that's getting worked into the LLVM pluggable architecture these days). Of course ML wasn't really a thing back then, and intel didn't seem interested in putting itaniums into cell towers.

One way to think of the OOO and branch predict processing that current x86 (and arm) do is that they are doing on-the-fly re-JITing of the code. There is a lot of silicon dedicated to doing the right thing and avoiding highly costly branch mispredicts, etc. During itanium's heyday, there was a premium of performance over efficiency. Now everyone wants power efficiency (since that is now often a cost bottleneck). Besides which, for other reasons Itanium wasn't as power efficient as (ideally) the chosen architecture could have achieved.

Re: C Is Not a Low-Level Language

#174

I really really liked this article, and reading the comments here is blowing my mind. Did we read the same thing? I think it's a strong insight that insight that chip designers and compiler vendors have spent person-millenia maintaining the illusion that we are targeting a PDP-11-like platform even while the platform has grown less and less like that. And, it turns out, with things like Spectre and the performance co…

It seems like the article is mostly useful for inspiring research; that is, most of us aren't the target audience.

I'm wondering what will happen as GPU's become more general-purpose. What's next after machine learning?

Would it be possible to make a machine where all code runs on a GPU? How would GPU's have to change to make that possible, and would it result in losing what makes them so useful? What would the OS and programming language look like?

Re: C Is Not a Low-Level Language

#175
post #165

Earlier quoted context omitted.

That's not true - PDP-11 era C isn't either - if you run it on a modern processor. And it's doubtful it even was then.

> PDP-11 era C isn't either - if you run it on a modern processor. And it's doubtful it even was then. With a modern compiler C isn't low-level. But under PDP-11 era C compilers, C really did map closely to processor instructions.

Not closely enough that it would have been considered low level at the time, if you look at the instruction set C isn't even close to one-to-one with the machine instructions. See https://en.m.wikipedia.org/wiki/PDP-11_architecture#Myth_of_... for why people might mistakenly think otherwise

Re: C Is Not a Low-Level Language

#176
post #133

Earlier quoted context omitted.

>the argument made was that predicting likely-parallelizable code is actually a lot harder to do at compile time So don't do it at compile time? That's really a very weak argument against the Itanium ISA, and honestly more of an argument against the AOT complication model. Take a runtime with a great JIT, like the JVM or V8, and teach it to emit instructions for the Itanium ISA. (As an added advantage these runtimes…

This argument has been made since the introduction of the JVM in the early mid-90's. Seems to me like if, in practice, JIT provided better performance then by now people would be rewriting their C/C++ code in Java and C# for speed.

It might still be possible. The JVM and .NET both have their speed annihilated by their awful choice of memory model.

Re: C Is Not a Low-Level Language

#177
post #65
post #14

Earlier quoted context omitted.

I also had the initial impression that the article is misleading, but later on the author made the point that the C compiler is doing significant work to reorder / parallelize / optimize the code. I agree that x86/x64 is not a low-level language either, but even if it was, with the description the author provided, I'd agree with his point of C not being low-level. Regarding cutting off backwards compatibility to impr…

I'm not an expert, but I don't think the optimization phase should be really considered here: the same kind of pattern matching used by (e.g.) LLVM to find optimizable sequence of statements also could be used by any assembler. NASM for instance offer some level of optimizations, so I think optimization should only be considered when it's part of the language specification itself, like in Scheme. IMO C is close to lo…

> the same kind of pattern matching used by (e.g.) LLVM to find optimizable sequence of statements also could be used by any assembler.

Some of the simpler optimizations, sure. But modern backends do many incredibly sophisticated optimizations that are way beyond any kind of simple pattern-matching-and-substitution model.

Even fundamental "optimizations" like register allocation use quite sophisticated algorithms. Optimal register allocation is NP-complete, so compilers use heuristics on top of graph coloring algorithms to do their best.

Most other optimizations rely on type analysis, data flow analysis, liveness analysis, etc.

Re: C Is Not a Low-Level Language

#178
post #167

Earlier quoted context omitted.

The point I'm trying to make with the analogy is that the x86 instruction set is not representative of what the hardware is actually doing. It is not "low level" because it is an abstraction or virtual platform that the processor exposes and then interprets using its own internal resources and programming interface (microcode). The x86 interface does not map closely to the actual hardware, just as the article states.…

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 level. Let us take advantage of them in our compilers and virtual machines.

The JVM can beat C in many scenarios because it can make optimizations based upon runtime information that a static compiler will never have available.

Imagine what we could do if we weren't chained to the x86 abstractions.

Re: C Is Not a Low-Level Language

#180
post #129

Earlier quoted context omitted.

> If C is not a low level language then a low level language does not exist for modern CPUs I think that's a fair conclusion though, I don't think the article is misleading. x86 assembly is a high level language. It's analogous to JVM bytecode. Modern x86 processors are more like a virtual machine for x86 bytecode.

>x86 assembly is a high level language. It's analogous to JVM bytecode. If you take this position, then having the distinction between "low level" and "high level" languages becomes pointless, and we have no way to distinguish between languages like x86 assembly and C and languages like Python and Haskell. This is why we use the terms "low level" and "high level": some of these languages have a lower level of abstrac…

> The fact that it's not giving you a great idea of exactly what's happening in the transistors is irrelevant

The author's point is that what's happening in the transistors is relevant — not controlling it is what led to Spectre and heavy performance losses if you aren't smart about cache usage. Thinking of C as a "low-level language" makes it easier for people to overlook that fact.

Post reply on HN