News for hackers. Stuff that matters.
Re:C Is Not a Low-Level Language by mattnewport on Tuesday May 01, 2018 @11:38AM (#16967946)
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 language then a low level language does not exist for modern CPUs and since all other languages ultimately compile down to the same instruction sets they all suffer from some of the same limitations.

It's really backwards compatibility of instruction sets / architectures that imposes most of these limitations. Processors that get around them to some degree like GPUs do so by abandoning some amount of backwards compatibility and/or general purpose functionality and that is in part why they haven't displaced general purpose CPUs for general purpose use.

Re:C Is Not a Low-Level Language by ge0rg on Tuesday May 01, 2018 @11:48AM (#16968080)
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 improve the design, Intel's Itanium (affectionately called "Itanic") was a very progressive approach to shift the optimization work from the CPU (and the compiler) to just the compiler. I'm not sure what the reasons for its failing were, though.

Re:C Is Not a Low-Level Language by pera on Tuesday May 01, 2018 @12:27PM (#16968545)
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 low-level because it's relatively easy to imagine the resulting unoptimized assembly given some piece of code (which is why some people jokes about C being a macro assembly).

Maybe this old debate should get an slight update... and this could be the starting point: Is modern x86 assembly still "low-level"? :)

Re:C Is Not a Low-Level Language by munificent on Tuesday May 01, 2018 @03:44PM (#16970725)
> 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 by verall on Tuesday May 01, 2018 @04:52PM (#16971482)
The K-graph coloring problem for register allocation is NP-complete, but in SSA form is actually linear. The tougher problem isn't the coloring but rather where to optimally place spills and fills around loops and calls.

https://llvm.org/devmtg/2011-11/Olesen_RegisterAllocation.pd...

Re:C Is Not a Low-Level Language by andrewflnr on Tuesday May 01, 2018 @06:42PM (#16972416)
Yeah, the number of "registers" needed isn't really NP-complete the way that the number of colors in a graph is. It's just the maximum number of live values, which, while not exactly trivial, is not that hard to figure out.
Re:C Is Not a Low-Level Language by vvanders on Tuesday May 01, 2018 @04:22PM (#16971140)
It would be interesting to revisit a world where languages/compilers were built explicitly with common memory access semantics/out of order op/etc in mind.

One of the things that really excites me about Rust is that it's single mutable reference enforcement means you can run run `restrict` 100% of the time if you wanted which is a non-trivial performance boost. I think it's not enabled today but from previous discussions it sounds like that's just a matter of plumbing through the right things to LLVM.

Every time I've seen that rolled out in a C/C++ codebase someone invariably forgets about pointer aliasing and you spend a week tracking down some non-deterministic behavior.

Re:C Is Not a Low-Level Language by pera on Tuesday May 01, 2018 @04:34PM (#16971271)
My point was that since optimization is also possible in assembly, and since assembly is considered low-level, then optimization per se shouldn't be used as something that characterize high-level languages exclusively. But it is true that some abstractions used by high-level languages enable quite complex optimization techniques, so there is a clear correlation between the level of a language and the ability of its compiler to analyze and optimize programs.
Re:C Is Not a Low-Level Language by nickpsecurity on Tuesday May 01, 2018 @04:26PM (#16971184)
"the same kind of pattern matching used by (e.g.) LLVM to find optimizable sequence of statements also could be used by any assembler"

Transmeta's x86 CPU's were even doing translations and optimizations dynamically between x86 and their internal representations.

Re:C Is Not a Low-Level Language by still_grokking on Wednesday May 02, 2018 @02:29AM (#16974596)
> Transmeta's x86 CPU's were even doing translations and optimizations dynamically between x86 and their internal representations.

I think every modern x86 CPU is doing exactly that.

Re:C Is Not a Low-Level Language by posterboy on Tuesday May 01, 2018 @04:45PM (#16971400)
C cannot read the overflow bit after an ADD, because of it's abstractions ... so I would say modern ASM is still lower in some aspects because it has less constrains and more importantly, it is less expressive, which is the whole idea of this hierarchy.

The compiler should offer a macro for that. Then the question is whether to take the specification or the implementation at which point it's an absurd question to begin with. You could compare -O0 binaries, bypassing the optimization question, too.

High/low is not fine grained enough. IIRC, prolog for example would be dubbed a fifth generation language, after assembler, goto hell macro compilers, structured functional programming, and DSLs. Now coq and the like seem to be of yet a higher order (pun intended, sorry).

Re:C Is Not a Low-Level Language by jburgess777 on Tuesday May 01, 2018 @05:23PM (#16971808)
> C cannot read the overflow bit after an ADD ... The compiler should offer a macro for that.

If you use GCC then __builtin_add_overflow() is what you are looking for:

"The compiler will attempt to use hardware instructions to implement these built-in functions where possible, like conditional jump on overflow after addition, conditional jump on carry etc."

https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins...

Re:C Is Not a Low-Level Language by posterboy on Wednesday May 02, 2018 @05:43AM (#16975383)
Yes, I know that. Y ou could add macros implementing a complete asm language to become a subset of C and C would still be more expressive
Re:C Is Not a Low-Level Language by skywhopper on Tuesday May 01, 2018 @12:55PM (#16968841)
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 yields far better performance.
Re:C Is Not a Low-Level Language by gh02t on Tuesday May 01, 2018 @02:39PM (#16970010)
Itanium suffered performance wise initially because they had trouble with compilers, but that's not the whole story. You also have to consider that AMD launched AMD64, which was backwards compatible, at about the same time. Later on the Itanium compilers got better, but on release it became a choice of "sluggish, incompatible and expensive Itanium with potential to perform well in the future" versus "backwards compatible, currently faster and cheaper x86_64." It didn't gain any real momentum to start because of this, which ultimately doomed it even when a lot of the issues were resolved later on.
Re:C Is Not a Low-Level Language by mattnewport on Tuesday May 01, 2018 @02:56PM (#16970215)
> which ultimately doomed it even when a lot of the issues were resolved later on.

Was there ever a point in the Itanium's history where there were Itaniums that ran mainstream software with better performance than equivalently priced x64 processors?

Re:C Is Not a Low-Level Language by zlynx on Tuesday May 01, 2018 @03:30PM (#16970585)
There were hand-coded assembly loops that were 3-4 times faster than x86, using Itanium's predicates and rolling register windows.

But I guess you said mainstream. So unless you count database engines, I suppose the answer is "No."

Today you can get the same vector performance using SSE4 and AVX. Almost all of Itanium's good stuff has been rolled into Xeon.

Re:C Is Not a Low-Level Language by gh02t on Wednesday May 02, 2018 @01:11AM (#16974216)
As far as I know (which isn't very far, admittedly) they only really managed to reach parity with some performance gains over x86 in a few niches, but it's also a bit chicken-and-egg. It never had enough attention to really get the optimization and porting efforts it would have seen if it had been successful.
Re:C Is Not a Low-Level Language by dnautics on Tuesday May 01, 2018 @03:35PM (#16970637)
> 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 by drbawb on Tuesday May 01, 2018 @02:13PM (#16969695)
>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 are extremely portable and can be run, with less optimizations, on other ISAs without issue.)

The problem, as always, is that nobody with money to spend ever wants to part with their existing software. (Likely written in C.) In 2001 Clang/LLVM didn't even exist, and I'm not familiar with any C compilers of the era that had so much as a rudimentary JIT.

Re:C Is Not a Low-Level Language by mattnewport on Tuesday May 01, 2018 @02:39PM (#16970012)
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 largely been failures.
Re:C Is Not a Low-Level Language by dnautics on Tuesday May 01, 2018 @07:56PM (#16972869)
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 code on every clock cycle.

As the definition of performance is changing due to the topping out of moore's law and shifting paralellism from amdahl to gustafson, I think there is a real opportunity for non ooo, non specex in th future.

Re:C Is Not a Low-Level Language by mattnewport on Tuesday May 01, 2018 @08:50PM (#16973178)
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 by dnautics on Wednesday May 02, 2018 @04:22PM (#16980817)
My point is that the dominant software programming paradigm is migrating away from highly dynamic to highly regular. A good example is Machine learning, where for any given pipeline, your matrix sizes are generally going to stay the same. A good compiler can distribute the computation quite well without much trouble, and this code will almost certainly not need SpecEx/OOO (which is why we put them on GPUs and TPUs). Or imagine a billion tiny cores each running a fairly regularly-shaped lambda.

Sure some things like nginx gateways and basic REST routers will have to handle highly dynamic demands with shared tenancy, but the trends seem to me to be away from that. As you say, this is all dependent on the structure of code; and I think our code is moving towards one where the perf advantages won't depend on OoO and specex for many more cases than now.

Re:C Is Not a Low-Level Language by mattnewport on Wednesday May 02, 2018 @06:57PM (#16981883)
This might be true for some domains but it's far from true for the performance sensitive domains I'm familiar with - games / VR / realtime rendering. The trend is if anything the opposite there as expectations around scene and simulation complexity are ever increasing.
Re:C Is Not a Low-Level Language by pjmlp on Wednesday May 02, 2018 @02:36AM (#16974628)
Actually if you read IBM's research papers on RISC, their PL/8 compiler toolchain was pretty much like how LLVM kind of looks like, just on the 70's.
Re:C Is Not a Low-Level Language by dnautics on Wednesday May 02, 2018 @04:17PM (#16980786)
no doubt, but popularity and timing matters.
Re:C Is Not a Low-Level Language by admax88q on Tuesday May 01, 2018 @09:45PM (#16973436)
> The promise of JITs outperforming AoT compiled code has never really materialized.

Well JITs do actually outperform AoT compiled code today. Java is faster than C in many workloads. Especially large scale server workloads with huge heaps.

Java can allocate/deallocate memory faster than C, and it can compact the heap in the process which improves locality.

Re:C Is Not a Low-Level Language by mattnewport on Tuesday May 01, 2018 @10:06PM (#16973512)
I haven't seen this convincingly demonstrated. Can you point to good examples? The few times I've seen concrete claims they are usually comparing Java code with C code that no performance oriented C programmer would actually write. In certain cases Java can allocate memory faster than generic malloc but in practice in many of those cases a competent C or C++ programmer would be using the stack or a custom bump allocator.

In practice it's quite hard to do really meaningful real world performance comparisons because real world code tends to be quite complex and expensive to port to another language in a way that is idiomatic. My general observation is that where performance really matters to the bottom line or where there is a real culture of high performance code C and C++ still dominate however. This is certainly true in the fields I have most experience in and where there are many very performance oriented programmers: games, graphics and VR.

Re:C Is Not a Low-Level Language by marshray on Tuesday May 01, 2018 @02:25PM (#16969837)
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.

Re:C Is Not a Low-Level Language by gpderetta on Tuesday May 01, 2018 @05:34PM (#16971914)
Most importantly people would write JITers for C and C++.
Re:C Is Not a Low-Level Language by Tobba_ on Tuesday May 01, 2018 @03:42PM (#16970711)
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 by kartickv on Sunday May 13, 2018 @12:45AM (#17057399)
What are some languages that have a better memory model and work faster with a JIT rather than an AOT compiler?

For that matter, does Java code execute faster or slower with an AOT compiler than with HotSpot? I did a quick Google search but couldn't find an answer, except for JEP 295 saying that AOT is sometimes slower and sometimes faster :(

Re:C Is Not a Low-Level Language by Baeocystin on Tuesday May 01, 2018 @04:01PM (#16970922)
What's wrong with their memory model? Honest question.
Re:C Is Not a Low-Level Language by jeffffff on Tuesday May 01, 2018 @06:37PM (#16972375)
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 making parallel arrays of primitives where there is an array for each field. this is also not ideal for locality but it's better than the alternative since there isn't a data dependency between the loads (they can all be done in parallel).

i am not that familiar with the C# runtime and i know C# has user definable value types, but i'm not sure what their limitations are.

Re:C Is Not a Low-Level Language by DerekL on Tuesday May 01, 2018 @09:18PM (#16973308)
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 by Hemospectrum on Tuesday May 01, 2018 @05:26PM (#16971831)
In a nutshell: Too much pointer chasing. C# actually does much better than Java here, with its features for working with user defined value types, but it could still improve by a lot.
Re:C Is Not a Low-Level Language by TimJYoung on Wednesday May 02, 2018 @11:08AM (#16977606)
In addition to what others have mentioned, there's also the inability to map structures on to an area of memory. The result is that you end up using streams and other methods to accomplish the same thing, and they result in a lot of function/method overhead for reading/writing simple values to/from memory.
Re:C Is Not a Low-Level Language by marshray on Tuesday May 01, 2018 @08:02PM (#16972912)
Garbage Collection is a very consequential design decision. To free that last unused object is going to take O(total writable address space) memory bandwidth.
Re:C Is Not a Low-Level Language by lmm on Tuesday May 01, 2018 @02:28PM (#16969878)
> 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's a little bit faster, not faster by enough to matter. If you're going to rewrite C/C++ code for speed you'd go to Fortran or assembler, and even then you're unlikely to get enough of a speedup to be worth a rewrite.

New projects do use Java or C# rather than C/C++ though.

Re:C Is Not a Low-Level Language by hutzlibu on Tuesday May 01, 2018 @02:41PM (#16970039)
"New projects do use Java or C# rather than C/C++ though."

But not for speed reasons. Java is in no way faster than well written C/C++

Re:C Is Not a Low-Level Language by lmm on Thursday May 03, 2018 @09:24AM (#16985748)
X is not faster than well written Y, for all X and Y; that's not a particularly useful comparison though. I've seen a project pick Java over C/C++ because, based on their previous experience, the memory leaks typical of C/C++ codebases were a worse performance problem than any Java overhead.
Re:C Is Not a Low-Level Language by hutzlibu on Thursday May 03, 2018 @07:21PM (#16990890)
Well written Java is sure to be slower than well written C/C++.

Happy? ;)

But yes, the point you make, is valid, it is much harder to write C/C++ well, because of the burden of memory management. So if you lack the time or skilled people, it might make sense to choose Java out of perfomance reasons.

Re:C Is Not a Low-Level Language by pjmlp on Wednesday May 02, 2018 @02:40AM (#16974652)
Java might not be, but C# is another matter.

Specially after the Midori and Singularity projects, and how it affected the design of C# 7.x low level features and UWP AOT compiler (shared with Visual C++).

Also Unity is porting engine code from C++ to C# thanks to their new native code compiler for their C# subset, HPC#.

Re:C Is Not a Low-Level Language by mattnewport on Wednesday May 02, 2018 @03:01AM (#16974751)
The discussion was about JITs vs AoT compiled native code. Unity is not using a JIT runtime for their new Burst compiler but using LLVM to do AoT native compilation and getting rid of garbage collection. If you get rid of JIT and garbage collection then yes, a subset of C# can be competitive in performance with C++ for some uses.
Re:C Is Not a Low-Level Language by pjmlp on Wednesday May 02, 2018 @04:03AM (#16974969)
JIT vs AOT is an implementation detail, nothing to do with a programming language as such, unless we are speaking about dynamic languages, traditionally very hard to AOT.

In fact C# always supported AOT compilation, just that Microsoft never bothered to actually optimize the generated code, as NGEN usage scenario is fast startup with dynamic linking for desktop applications.

While on Midori, Singularity, Windows 8.x Store, and now .NET Native, C# is always AOT compiled to native code, using static linking in some cases.

As for GC, C# always offered a few ways to avoid allocations, it is a matter for developers to actually learn to use the tools at their disposal.

With C# 7.x language features and the new Span related classes, it is even easier to avoid triggering the GC in high performance paths.

Re:C Is Not a Low-Level Language by kartickv on Sunday May 13, 2018 @12:48AM (#17057402)
For someone who doesn't develop for the MS stack but is still curious, what are these ways to avoid allocations and GC in performance-critical paths?
Re:C Is Not a Low-Level Language by tzahola on Tuesday May 01, 2018 @06:59PM (#16972531)
Nah, nobody in their right mind would use Java/C# over C/C++ for performance...

http://blog.metaobject.com/2015/10/jitterdammerung.html?m=1

Re:C Is Not a Low-Level Language by elcritch on Tuesday May 01, 2018 @10:06PM (#16973510)
That’s a great blog post!

> I agree with Ousterhout's critics who say that the split into scripting languages and systems languages is arbitrary, Objective-C for example combines that approach into a single language, though one that is very much a hybrid itself. The "Objective" part is very similar to a scripting language, despite the fact that it is compiled ahead of time, in both performance and ease/speed of development, the C part does the heavy lifting of a systems language. Alas, Apple has worked continuously and fairly successfully at destroying both of these aspects and turning the language into a bad caricature of Java. However, although the split is arbitrary, the competing and diverging requirements are real, see Erlang's split into a functional language in the small and an object-oriented language in the large.

I still strongly think Apple is taking the wrong approach with Swift by not building on the ObjC hybrid model more.

Re:C Is Not a Low-Level Language by lmm on Thursday May 03, 2018 @09:22AM (#16985727)
Your article is correct that Java/C# performance is unpredictable. But, per the OP, C/C++ performance is also unpredictable, because C/C++ doesn't reflect what a modern processor actually does; there are cases where e.g. removing a field from a datastructure makes your performance multiple orders of magnitude worse because some cache lines now alias.
Re:C Is Not a Low-Level Language by mattnewport on Tuesday May 01, 2018 @02:40PM (#16970024)
> New projects do use Java or C# rather than C/C++ though.

Nobody is picking Java/C# over C/C++ for performance reasons.

Re:C Is Not a Low-Level Language by pjmlp on Wednesday May 02, 2018 @02:44AM (#16974671)
It is not that Java or C# are able to beat C and C++ on micro-benchmarks, rather they are fast enough for most tasks that need to be implemented, while providing more productivity.

The few cases where raw performance down to the the byte level and ms matter are pretty niche.

Re:C Is Not a Low-Level Language by lmm on Thursday May 03, 2018 @09:25AM (#16985762)
I've seen a project pick Java over C/C++ because of the memory leaks they saw in the latter in practice. You can call that a correctness issue rather than a performance issue if you like, but the practical impact was the same as a performance problem.
Re:C Is Not a Low-Level Language by Avshalom on Tuesday May 01, 2018 @05:12PM (#16971700)
One of the big problems with predicting what can be MIMDed is that almost all the languages we use except for Haskell allow for dependency on who knows what. With out very strict refusal of state it's hard as fuck to figure out what is independent of what at compile time.

Not that it can't be done so much as getting programmers to accept it is can't be done.

Re:C Is Not a Low-Level Language by Avshalom on Tuesday May 01, 2018 @11:59AM (#16968192)
Part of it was the sort of giant blind spot that "C is a low level language" creates that made even Intel forget how many man-years of optimization were actually in C compilers and the attendant hubris that "oh we can whip up something that'll beat it between now and when we start shipping the chips"
Re:C Is Not a Low-Level Language by colin_mccabe on Tuesday May 01, 2018 @07:14PM (#16972638)
I think people often overestimate how smart the compiler is. DJB had a slide deck about this: http://cr.yp.to/talks/2015.04.16/slides-djb-20150416-a4.pdf Compilers are really useful... but, if it really has to be fast, you still need to have a human in the loop.

I was also under the impression that there hasn't been much improvement in compiling C/C++ in a long time. It would be interesting to compare the performance of gcc from 15 years ago versus gcc today, on a real world piece of code. I suspect you wouldn't see much difference (aside from the changes in C dialect over time), and some added features in the new version. Has anyone run this experiment?

Re:C Is Not a Low-Level Language by mattnewport on Tuesday May 01, 2018 @12:00PM (#16968199)
I think you can make a good case that the failure of the Itanium (and other similar attempts to un-hide some of this stuff like the IBM/Sony Cell used in the PlayStation 3) was precisely because they tried to shift optimization work from the CPU to the compiler / programmer.
Re:C Is Not a Low-Level Language by greglindahl on Tuesday May 01, 2018 @12:39PM (#16968661)
Funny, the compiler people I've worked with complain that Itanium tried to do too much in hardware, like the hw support for loop unrolling, which made superpipelining optimizations in existing compilers much more complicated.
Re:C Is Not a Low-Level Language by mattnewport on Tuesday May 01, 2018 @01:05PM (#16968921)
Loop unrolling is one of those optimizations that actually highlights the need for dynamic CPU optimizations like out of order execution and speculative execution. It's very difficult to statically make a good decision about the optimal amount of loop unrolling to do, especially if you want to generate code that will continue to perform well on future CPUs using the same ISA. Even when targeting a specific CPU model it's difficult however since you don't know statically how many iterations of the loop you're expecting, what's currently in cache, what other code might be running immediately before or after the loop, what's running at the same time on other threads, etc.
Re:C Is Not a Low-Level Language by greglindahl on Tuesday May 01, 2018 @01:50PM (#16969427)
Itanium's hardware did not make any of these things easier.
Re:C Is Not a Low-Level Language by wbl on Tuesday May 01, 2018 @12:01PM (#16968216)
The compiler wasn't smart enough. There is information available only at runtime that can be used to get out of order execution and superscalar execution, and the compiler doesn't see any of it. More effort on standard architectures paid off.
Re:C Is Not a Low-Level Language by pcvarmint on Wednesday May 02, 2018 @11:36PM (#16983174)
Itanic failed because Intel/HP initially still used a front side bus memory architecture, which could not support the bandwidth necessary for peak performance on anything but matrix multiplication and other computations where most of the work is done in-cache. Then Opteron came around, with its faster memory, and Intel was suddenly thrown back into reality.

Itanic was also in-order (at least as far as dispatch), meaning anytime an instruction was stalled, so were all instructions in the same bundle or after it.

One "non-low-level" idea on Itanic, which never really panned out in practice, was for the assembler to automatically insert stop bits ;; marking assembly code "sequence points", instead of the programmer having to do it manually. But in practice, everyone did it manually, because they'd rather know how well their bundles were being used, and whether they could move instructions around in order get the full 3 instructions / bundle (6 instructions / clock).

And explicit stop bits did not provide any advantage to future hardware by marking explicit parallelism, because at every generation everyone was concerned about obtaining maximum performance on the current machine, which involved shuffling instructions into 6-instruction double-bundles, often at the expense of parallelism on future implementations (which never went beyond two bundles / clock).

Re:C Is Not a Low-Level Language by SolarNet on Tuesday May 01, 2018 @12:04PM (#16968260)
Not sure if facetious, but it failed because shifting that work caused it to be slow and not backwards compatible.
Re:C Is Not a Low-Level Language by PersistentCough on Tuesday May 01, 2018 @12:03PM (#16968257)
> the C compiler

You mean C compiler X has the feature of Y. There are lots of compilers and that's not part of the language.

Re:C Is Not a Low-Level Language by umanwizard on Tuesday May 01, 2018 @12:17PM (#16968425)
Their comment makes sense if you interpret "the C compiler" to mean "mainstream C compilers that 99% people use in production" or even just "gcc and clang".

We're talking about concrete things in the real world here, not philosophizing about the language spec.

Re:C Is Not a Low-Level Language by PersistentCough on Tuesday May 01, 2018 @03:02PM (#16970285)
> not philosophizing about the language spec.

That's exactly what's going on.

Re:C Is Not a Low-Level Language by Avshalom on Tuesday May 01, 2018 @07:05PM (#16972562)
And yet small device C and Gcc/clang are onky kissing cousins and we (well people that aren't me: ustedes) still rhetorically lump them together as a single language.
Re:C Is Not a Low-Level Language by kazinator on Tuesday May 01, 2018 @12:36PM (#16968631)
> Register renaming, cache hierarchies, out of order and speculative execution etc are not visible

That's different from C.

In the history of x86, most new optimizations have preserved the semantics of code. For instance, register renaming isn't blind; it identifies and resolves hazards.

In C, increasing optimization has broken existing programs.

C is like a really shitty machine architecture that doesn't detect errors. For instance, overflow doesn't wrap around and set a nice flag, or throw an exception; it's just "undefined". It's easy to make a program which appears to work, but is relying on behavior outside of the documentation, which will change.

Computer architectures were crappy like that in the beginning. The mainframe vendors smartened up because they couldn't sell a more expensive, faster machine to a customer if the customer's code relied on undocumented behaviors that no longer work on the new machine.

Then, early microprocessors in the 1970's and 80's repeated the pattern: poor exception handling and undocumented opcodes that did curious things (no "illegal instruction" trap).

Re:C Is Not a Low-Level Language by gpderetta on Tuesday May 01, 2018 @05:48PM (#16972037)
Then again store-load reordering is visible across cores and undefined.
Re:C Is Not a Low-Level Language by admax88q on Tuesday May 01, 2018 @12:18PM (#16968435)
> 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.

Re:C Is Not a Low-Level Language by magduf on Tuesday May 01, 2018 @02:07PM (#16969642)
>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 abstraction than others. The fact that it's not giving you a great idea of exactly what's happening in the transistors is irrelevant: "low" and "high" are relative terms, not absolute.

Re:C Is Not a Low-Level Language by munificent on Tuesday May 01, 2018 @03:47PM (#16970760)
> 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.

Re:C Is Not a Low-Level Language by ori_b on Tuesday May 01, 2018 @04:12PM (#16971027)
And the parent's point is that there should be a distinction in level between Haskell and C, for example.
Re:C Is Not a Low-Level Language by Avshalom on Tuesday May 01, 2018 @05:22PM (#16971796)
Then we need a finer grained taxonomy instead of the current model that is essentially: machine code;c/forth; literally everything else.

I mean that should be blindingly obvious anyway looking at the actual history of programming languages and CPUs but here we are in 2018 insisting that we must have exactly three categories with exactly the definitions of: assembly;C/forth; everything else.

Re:C Is Not a Low-Level Language by ninkendo on Tuesday May 01, 2018 @01:40PM (#16969321)
It's a fair conclusion if you're willing to accept that the phrase "low-level language" has approximately zero modern examples.

Or maybe we should relax the definition of "low-level language" a bit?

Re:C Is Not a Low-Level Language by scott_s on Tuesday May 01, 2018 @02:05PM (#16969612)
I think the author of the article is willing to accept that, and it's part of his point. The point is not to label languages, but to illuminate how we ended up with our current combination of software and hardware design. He points out that we are in a local-maximum with respect to processor performance because most of the optimizations we've made in processor design the past few decades break the C abstract machine. That requires the compiler and processor to go through awkward contortions to present the fiction of that abstract machine while still getting good performance. The final section, "Imagining a Non-C Processor", is where he explores this idea.
Re:C Is Not a Low-Level Language by namibj on Tuesday May 01, 2018 @02:14PM (#16969712)
Take a look at maxas [0], and the maxwell/pascal microarchitecture if you want a modern example of low-level language (iirc. they are still manufactured on small mainstream process nodes).

[0] https://github.com/NervanaSystems/maxas

Re:C Is Not a Low-Level Language by jrochkind1 on Tuesday May 01, 2018 @01:45PM (#16969369)
Hmm, what does "virtual machine" mean if the "virtual machine" is implemented in hardware?

And, is nothing but actual binary machine code a "low level language"? I guess it's the lowest, I don't _think_ you can go lower than that... but someone's probably gonna tell me I'm wrong.

Re:C Is Not a Low-Level Language by ummonk on Tuesday May 01, 2018 @02:23PM (#16969815)
VHDL / Verilog is lower level!

In all seriousness, the "assembly is high level" argument is ridiculous and robs the "low level" vs "high level" categorization of all meaning.

Re:C Is Not a Low-Level Language by Avshalom on Tuesday May 01, 2018 @05:27PM (#16971841)
Taxonomies have been rendered meaningless constantly throughout history, fighting it is usually fighting reality.
Re:C Is Not a Low-Level Language by jrochkind1 on Tuesday May 01, 2018 @04:50PM (#16971462)
Perhaps C is a "medium-level language"? :)
Re:C Is Not a Low-Level Language by mikepurvis on Tuesday May 01, 2018 @12:49PM (#16968773)
The JVM provides native primitives around memory and thread management which are not present in x86, but that's a matter of degree.
Re:C Is Not a Low-Level Language by fixermark on Tuesday May 01, 2018 @01:33PM (#16969242)
x86 provides all sorts of memory abstractions. The whole memory segmentation model is an abstraction. https://en.wikipedia.org/wiki/X86_memory_segmentation
Re:C Is Not a Low-Level Language by pvg on Tuesday May 01, 2018 @12:29PM (#16968567)
It's analogous to JVM bytecode.

That's only true in the way everything is analogous to everything.

Re:C Is Not a Low-Level Language by chubot on Tuesday May 01, 2018 @12:40PM (#16968669)
I think it's a good analogy because it's saying that nontrivial optimizations happen below the code layer.

In early CPUs, nothing was optimized. They just executed your instructions. Now there are nontrivial optimizations and rewriting, just like the JVM.

Re:C Is Not a Low-Level Language by coldtea on Tuesday May 01, 2018 @12:40PM (#16968677)
Nope, also in the way the parent explains right after that sentence.
Re:C Is Not a Low-Level Language by pvg on Tuesday May 01, 2018 @12:49PM (#16968774)
It's a pretty terrible analogy in nearly every obvious technical way. What an x86 cpu does with its instructions is almost but not entirely unlike what a JVM does.
Re:C Is Not a Low-Level Language by admax88q on Tuesday May 01, 2018 @01:10PM (#16968978)
None of the "registers" in x86 assembly are real. Few of the instructions are implemented in hardware, most are impelmented in software microcode.

Advanced hardware will re-order and pipeline instructions based upon data dependencies.

Sure it's not doing the exact same things the JVM does with bytecode but the point is that x86 assembly is not the language of the hardware. It's a language that the hardware+firmware knows how to interpret and optimize at runtime similar to what your JVM does with java bytecode.

Re:C Is Not a Low-Level Language by pvg on Tuesday May 01, 2018 @01:27PM (#16969180)
It isn't at all similar. JVM bytecode is a pretty high-level IR for tokenized Java. The JVM's main unit of optimization is a method, not instructions. Its key component is a compiler, it's even called that.

An x86 cpu, as the article points out, spends inordinate resources looking for ILP. It's not a compiler in any reasonable sense of the word, while a JVM is.

Re:C Is Not a Low-Level Language by admax88q on Tuesday May 01, 2018 @02:13PM (#16969701)
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. It exposes a flat memory model with sequential execution and only a handful of registers.

Much the same way that the JVM exposes a virtual machine that doesn't directly map to any of the platforms that it runs on. It's an abstraction that is interpreted or compiled at runtime.

I don't understand why you think the two are so different just because the JVM is higher level.

Re:C Is Not a Low-Level Language by pvg on Tuesday May 01, 2018 @03:23PM (#16970511)
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 abstraction that is interpreted or compiled at runtime' is so broad it's exactly the what I said up top - it's analogous in the way everything is analogous to everything else. It's the sort of thing that might be true if you squint but offers somewhere between zero and negative insight.

Re:C Is Not a Low-Level Language by admax88q on Tuesday May 01, 2018 @03:46PM (#16970745)
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 by gpderetta on Tuesday May 01, 2018 @06:17PM (#16972236)
OoO, renaming, branch prediction, microcode have existed for a long time. If anything, more modern CPUs (x86 included) are RISCer than the older generations which had extensive microcode expansion for each instruction.

Even ignoring the fact that the JVM is typed, memory safe and with builtin GC (all things that were tried architecturally in the past and abbandoned), there is still a large difference between the scope and variety of non-local optimizations perfomed by any non-toy VM and the local, strictly realtime, constrained to a small window, set of reordering done by an OoO engine. Even tracing, which is used by some JITs, has been largely abbandoned in the CPU world.

Transmeta and Denver-like dynamic translation is closer to the behaviour of a software JIT and it is certainly considered drastically different from mainstream OoO.

Re:C Is Not a Low-Level Language by pvg on Tuesday May 01, 2018 @09:21PM (#16973326)
"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 by coldacid on Tuesday May 01, 2018 @01:56PM (#16969497)
`javac` is a compiler. The JVM is an execution platform, just like modern x86.
Re:C Is Not a Low-Level Language by pvg on Tuesday May 01, 2018 @02:00PM (#16969563)
What's the word that comes after 'JIT'?
Re:C Is Not a Low-Level Language by coldtea on Tuesday May 01, 2018 @05:29PM (#16971866)
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.

Re:C Is Not a Low-Level Language by pvg on Tuesday May 01, 2018 @08:47PM (#16973167)
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 by rbanffy on Tuesday May 01, 2018 @12:06PM (#16968284)
Microcode is the new low level language. ;-)

But, to be fair, C is not that low level. In fact, when I first learned it, it was considered a high-level language because CPUs we used it with didn't have functions with parameters, only subroutine jumps.

C reaches into the realm of low-level languages because it allows you to arbitrarily read from and write to the "state" of the context you live in, but it also allows you to express constructs that have no counterpart even on the most complex CPU architectures (even if they have things that disagree fundamentally with C's point of view).

Re:C Is Not a Low-Level Language by pjmlp on Tuesday May 01, 2018 @12:38PM (#16968656)
> Microcode is the new low level language. ;-)

Except for RISC, that has mostly always been the case, when we look back at all those mainframes and their research papers.

Re:C Is Not a Low-Level Language by nerdponx on Tuesday May 01, 2018 @12:14PM (#16968370)
On the flipside, doesn't it allow more or less direct memory access?
Re:C Is Not a Low-Level Language by abofh on Tuesday May 01, 2018 @12:20PM (#16968463)
I mean, yes, no, it depends on what you mean?

You can write to null in C, your operating system rejects it. You can write past your allocated memory, your OS rejects it. It's not like just because it's written in C it gets to read the kernel memory - it's just that you can try.

All memory access in userspace is mediated by the MMU, so nothing in C gets "direct" memory access - but it does allow you to screw up your own memory space pretty well... I'm not sure that's C's fault though

Re:C Is Not a Low-Level Language by pjmlp on Tuesday May 01, 2018 @12:40PM (#16968679)
Many C targets also run bare metal, there is nothing to reject there, unless the hardware has an MMU and the code bothered to configure it on boot.
Re:C Is Not a Low-Level Language by nerdponx on Tuesday May 01, 2018 @01:56PM (#16969490)
That's my whole point. C doesn't try to stop you from doing that. C tries to do exactly what you ask it to, and if the OS doesn't allow it it just crashes.

To me that is about as low level as you can get without bypassing the OS.

Re:C Is Not a Low-Level Language by ryao on Tuesday May 01, 2018 @05:57PM (#16972102)
Try using atomic instructions or initializing various tables during system boot. You will find that there are things C cannot do, unless you write assembly and call to it from C.
Re:C Is Not a Low-Level Language by saagarjha on Tuesday May 01, 2018 @12:46PM (#16968734)
But is there really any programming language that lets you write to arbitrary memory? This is a problem of privileges rather than how low level your language is: it's not like you can write assembly that will give you arbitrary access to kernel memory.
Re:C Is Not a Low-Level Language by billfruit on Tuesday May 01, 2018 @02:00PM (#16969554)
In writing h kernal modules in C for vxworks, I find people quite often write/read data from hard-coded memmory addresses.
Re:C Is Not a Low-Level Language by Avshalom on Tuesday May 01, 2018 @12:01PM (#16968219)
>If C is not a low level language then a low level language does not exist for modern CPUs

correct, but that lack is not an argument for C being low level.

Re:C Is Not a Low-Level Language by swsieber on Tuesday May 01, 2018 @12:05PM (#16968274)
Correct - it's an argument for broadening the title.

Calling out a specific language as not being something leads one to ask, "Well what is?". In this case, there is no qualifying alternative, so the title might as well be, "There is no low-level language for CPUs".

Re:C Is Not a Low-Level Language by munificent on Tuesday May 01, 2018 @12:53PM (#16968821)
> Calling out a specific language as not being something leads one to ask, "Well what is?".

The article does basically answer this. The last section is about what it would mean to design a chip such that a low level language were possible to design for it.

Re:C Is Not a Low-Level Language by Avshalom on Tuesday May 01, 2018 @12:07PM (#16968299)
... any more.

It's not a category that can't exist, it just doesn't have any members right now.

Re:C Is Not a Low-Level Language by mattnewport on Tuesday May 01, 2018 @12:43PM (#16968711)
It actually can't exist at all for current modern CPUs (x64/ARM/PowerPC) since they don't expose a programming interface for many of the things discussed in the article (speculative / out of order execution, register renaming, full cache control).
Re:C Is Not a Low-Level Language by Avshalom on Tuesday May 01, 2018 @12:50PM (#16968787)
Yeah but it can for all sorts of microcontroller-y chips; embedded CPUs; DSPs; theoretical future CPUs that aren't trying to both act like a PDP11 and go faster every year...
Re:C Is Not a Low-Level Language by 0xfaded on Tuesday May 01, 2018 @12:39PM (#16968657)
I played a little bit with gpgpu on the raspberry pi.

I’d imagine it’s relativly primitive compared to whatever shaders are compiled to on modern GPUs, but it was humbling to have to manage things like separate, per core, disjoint register files which can only be read 4 cycles after write. The cores are heterogeneous, so there is special hardware for exchanging register reads between cores if necessary.

Re:C Is Not a Low-Level Language by hencoappel on Wednesday May 02, 2018 @03:33AM (#16974881)
What language do you use for GPGPU?
Re:C Is Not a Low-Level Language by vardump on Wednesday May 02, 2018 @06:56AM (#16975729)
Sounded like Videocore 4 assembler.
Re:C Is Not a Low-Level Language by wmu on Wednesday May 02, 2018 @05:28AM (#16975300)
> Register renaming, cache hierarchies, out of order and speculative execution etc are not visible at the assembly / machine code level

Cache hierarchies are directly accessible with CLFLUSH, INV, WBINVD x86 instructions; we may count also PREFETCHx, but they call it "a hint". FENCE instructions touch even the multicore part of system.

Many low-level CPU concepts leak to higher layer. A bright example is false sharing, which may manifest even in Java or C# programs.

Re:C Is Not a Low-Level Language by fixermark on Tuesday May 01, 2018 @01:30PM (#16969212)
x86 is also there on modern architectures to supply an abstraction that is increasingly divergent from the actual die hardware (but compatible with expectations of e.g. a C compiler that already has an output target for previous x86 hardware).

Modern Intel CPUs basically emulate x86; there are many layers of abstraction between individual opcodes and transistor switching.

Re:C Is Not a Low-Level Language by kev009 on Tuesday May 01, 2018 @09:17PM (#16973301)
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 by ryao on Tuesday May 01, 2018 @05:55PM (#16972087)
Spend a week writing in assembly and you will never call C a low level language again.