It doesn't, because there are lots of special-purpose x86 instructions that would be more trouble than they're worth to teach a compiler about. For example, instructions for accessing particular CPU features that the C and C++ languages have no concept of (cryptographic acceleration and instructions used for OS kernel code spring to mind). Some of these the compiler might know about via intrinsic functions, but won't…
is there any point in multiplying by 1 ?
Does a compiler use all x86 instructions? (2010)
171–180 of 198 posts
Re: Does a compiler use all x86 instructions? (2010)
#172Earlier quoted context omitted.
> What you're describing is a GPU I would say I'm describing something halfway between a CPU and a GPU. It's not just an ALU, it's a complete microprocessor, with pipelining, caches, etc. The main difference is that the instruction set is optimized, backward compatibility is no longer a requirement, and redundancy of the architecture is eliminated.
What you are looking for is called the Mill: https://millcomputing.com/
Though it is an awesome architecture and I recommend anyone to check it out.
Re: Does a compiler use all x86 instructions? (2010)
#173Earlier quoted context omitted.
IIRC, when a new version of OSX stops working on older hardware, it's usually because Apple started using a "new" version of SSE that's not supported on a given CPU. For handcoded assembly, it's not uncommon for code to check a CPU's capabilities at runtime (e.g. OpenSSL checks at runtime if it can use the really fast AES-NI instructions,. If not, it fall backs to other assembly or C implementations). That way you do…
The Intel compiler (used to?) do runtime CPUID checks. If your CPU came back "GenuineIntel" (and only Intel), it took the fast SSE path. Theres more here: http://www.agner.org/optimize/blog/read.php?i=49#49
Re: Does a compiler use all x86 instructions? (2010)
#174There are instructions that would almost never be useful. See Linus's rant on cmov http://yarchive.net/comp/linux/cmov.html The tl;dr is that it would only be useful if you are trying to optimize the size of a binary.
It is _very_ useful when hand optimizing loops in assembly. But for the compiler, the newer processors have such incredible branch predictors it is usually a bad idea for the compiler assume a branch is poorly predicted. Now if you are using profile guided optimizations (--prof-gen/prof-use) AND you use the processor's performance counters as part of the feedback to the compiler _then_ I could see the compiler correc…
Is it somewhat similar to these two examples?
> If it owns that line then CAS is extremely fast - core doesn't need to notify other cores to do that operation. If core doesn't own it, the situation is very different - core has to send request to fetch cache line in exclusive mode and such request requires communication with all other cores. Such negotiation is not fast, but on Ivy Bridge it is much faster than on Nehalem. And because it is faster on Ivy Bride, core has less time to perform a set of fast local CAS operations while it owns cacheline, therefore total throughput is less. I suppose, a very good lesson learned here - microbenchmarking can be very tricky and not easy to do properly. Also results can be easily interpreted in a wrong way
http://stas-blogspot.blogspot.com/2013/02/evil-of-microbench...
> On current processors, POPCNT runs on a single execution port and counts the bits in 4B per cycle. The AVX2 implementation requires more instructions, but spreads the work out across more ports. My fastest unrolled version takes 2.5 cycles per 32B vector, or .078 cycles/byte (2.5/32). This is 1.6x faster (4 cycles per 32B /2.5 cycles per 32B) than scalar popcnt(). Whether this is worth doing depends on the rest of the workload. If the rest of the work is being done on scalar 64-bit registers, those other scalar operations can often fit between the popcnts() "for free", and the cost of moving data back and forth between vector and scalar registers usually overwhelms the advantage.
Re: Does a compiler use all x86 instructions? (2010)
#175Earlier quoted context omitted.
According to [1], on recent Intel CPUs, each instruction is translated by hardware decoder to up to four micro-ops: either trivial micro-ops like addition, subtraction, bitwise and/or/xor, or a special "microcode assist" micro-op which is essentially a function call into the CPU microcode table. According to the same source, CPU microcode table is believed to consist roughly of 20,000 micro-ops which handle edge case…
The new slides for AMD Zen say explicitly that it has hardware sha256 support.
Re: Does a compiler use all x86 instructions? (2010)
#176My question is if compilers use "new" x86 instructions, as then the program won't work at all on old systems. For example, if Intel decided today that CPUs need a new "fast" hashing opcode (I don't know if they actually do), a compiler can't compiles to it, as programs won't work on older computers. Is it like the API cruft in Android, where "new" Lollipop APIs are introduced for 10 years from now, when no one uses a…
In addition to what others have said, sometimes stuff gets added in a backwards compatible way. For example, Intel added two new instruction prefixes for their hardware lock elision extension. Actually, they reused existing instruction prefixes which were valid but did nothing on older CPUs when used on the instructions where the HLE prefixes apply. The semantics are such that "do nothing" is valid, but CPUs which un…
Re: Does a compiler use all x86 instructions? (2010)
#177Earlier quoted context omitted.
What you are looking for is called the Mill: https://millcomputing.com/
I don't think that is quite what he's looking for, the Mill is not exactly RISC. Though it is an awesome architecture and I recommend anyone to check it out.
Re: Does a compiler use all x86 instructions? (2010)
#178Earlier quoted context omitted.
LEA (load effective address) can perform computations of the form BASE + SCALE * INDEX + OFFSET, where scale can be 1, 2, 4 or 8. This allows optimisation of multiplications and additions into a single instruction, and the compiler takes advantage of that. So if you write: a = 4 * b + c + 10; It will be optimised to a single instruction like: lea 0xa(%rsi,%rdi,4),%rax Rather than the more naive: imul $0x4,%rdi,%rax a…
Right, that's what I mean by pointer arithmetic -- specialized instruction for calculating memory addresses. It seems it can be co-opted to do math and other calculations as well. But at least that was its intended use? Also Zen of Assembly mentions that LEA can store its result in any register and doesn't alter flags.
struct foo
{
int field1;
int field2[10];
}
Then an access like: fooptr->field2[index]
Would compile to: fooptr + sizeof(int) * index + offsetof(struct foo, field2)
Which is: lea $4(fooptr,index,4)Re: Does a compiler use all x86 instructions? (2010)
#179Earlier quoted context omitted.
The AS/400 is more like an AOT than a JIT compiler. When I hear JIT I think opportunistically compiling portions of a program, but falling back to an interpreter. The way AS/400 works, IIUC, is that the compiler compiles to an intermediate byte code, which has remained stable for decades. When the program is first loaded, the entire program is compiled to the native architecture, cached, and then executed like any ot…
I would disagree with almost everything you said here. JIT compilers can beat equivalent AOT compilers by about 20%, or at least, that's the kind of loss you get in HotSpot from not doing profile guided compilation and doing it all AOT instead. So that point seems wrong. If you're comparing Java and C++ well, that is affected by many things and you can quite easily construct microbenchmarks where Java beats C++. In r…
reality seems to agree with the parent. Case in point there are no production level JIT compilers for C/C++.
The fact that a java AOT compiler is not competitive with HotSpot might have more to do to the maturity of HotSpot and the amenability of Java to AOT compilation.
> JIT compilers tend to be better at unguided vectorisation than AOT compilers because they know what CPU features are available to them at compile time.
runtime dispatching to specialized functions makes this a moot point point. I'm not aware of the state of the art, but last I heard HotSpot wasn't particularly great at vectorization.
Re: Does a compiler use all x86 instructions? (2010)
#180Earlier quoted context omitted.
It is _very_ useful when hand optimizing loops in assembly. But for the compiler, the newer processors have such incredible branch predictors it is usually a bad idea for the compiler assume a branch is poorly predicted. Now if you are using profile guided optimizations (--prof-gen/prof-use) AND you use the processor's performance counters as part of the feedback to the compiler _then_ I could see the compiler correc…
I have a mixed feeling about that incredible progress in modern CPUs branch prediction. Don't they just use idle execution units and run both branches in parallel behind the scenes? It looks great on microbenchmarks when there's a bunch of idle execution units to use, a memory bus and caches are underused. It may not perform so well on real load when there's no idle execution units available to use for free, and memo…
No, I do not know of any production CPU that does it; Branch predictor accuracy today is ~98-99% so it would be a waste of power and execution capability to speculate both paths of a branch.
Also, I think code in average executes 1 jump every 5 instructions and an OoO core can speculate hundreds of instructions in advance, so the number of possible code paths would explode very quickly.