Some small suggestions for the Intel instruction set
blog.cr.yp.to
blog.cr.yp.to
> of about 25 bits [...]
> Why? Because the multiplier insists on rounding
> its low output bits rather than giving them back to the programmer.
> Why? Because the multiplier is buried inside the floating-point unit.
The reference to the 25-bit success makes it seem like the author is thinking of bits 53-105 of the 106-bit result of multiplying two 53-bit inputs.
The multiplier is not going to “give them back” to the programmer because it never computed them in the first place. Floating-point 53x53->53 multiplication is implemented with a couple of guard bits, the last of which is “sticky”. The multiplier the author is asking for is not “buried”, it does not exist in the processor.
I am not sure why integer multiplication is not preferred. It goes up to 64x64->128, if the author wants all the bits of the product.
> A 53-bit multiplier producing a full 106-bit product won't be much larger than a 53-bit multiplier producing a correctly rounded 53-bit floating-point result.
Yes, it will. It will have to be 106-bit wide instead of 56-bit wide.
I'm a little confused by this also, but given the level of detail in the linked paper (http://eprint.iacr.org/2014/134.pdf) it's definitely not just an oversight. The issue may be that he's aiming for fastest possible performance on Sandy Bridge (AVX), and 256-bit integer vector multiplication wasn't added until Haswell (AVX2). And even then, 64-bit integer elements can only be done one at a time. But since he's suggesting instruction set changes, he's clearly not thinking only of backwards compatibility.
So the answer to your question is... Floating Point numbers "don't round correctly". They're actually quite complicated, and require careful study.
There are very simple rules on how to round. This makes calculation of errors a bit complicated. http://en.wikipedia.org/wiki/IEEE_floating_point#Rounding_ru...
At best, Intel at one point provided 80-bit rounding (ie: 68-bit mantissa). That is, if you use the x87 floating-point coprocessor. But these technically do not match IEEE specifications for rounding.
In particular, to compute a product of two 53-bit floating-point numbers with correct rounding (as the standard mandates), it is certainly not sufficient in general to compute just a 54-bit approximation and round that.
1XXXX
* 1XXXX
_________
XXXXX
XXXXX
XXXXX
XXXXX
1XXXX
Using a sticky bit means computing the logical-or of all the bits that are sufficiently far to the right in all these partial results, instead of computing them individually and summing them.Like for addition, the idea is that the result you obtain is different from the exact result, but rounds the same. The sticky bit only serves to round (midpoint + a small quantity) correctly up.
1XXXXYZZZZ
To round it we need:(1) the X bits for our answer
(2) the Y bit for rounding
(3) the logical-or of the Z bits for rounding
Ok so there might be a trick to compute (3) without computing ZZZZ, but we still want to know how to compute 1XXXXY without computing ZZZZ.
This explanation assumes that the N partial products are added sequentially. I don't know what techniques are used to achieve the 4- or 5-cycle latencies of modern desktop processors. Implementations with more parallelism and/or that are part of an FMA unit have it harder, but I still expect that they don't naively compute a full width partial result before rounding it (in the case of the FMA, it would be impractical as the partial result could be thousands of bits wide)
For some reason (maximum depth reached?) there is no “reply” link at the bottom of the post of yours at which I understood, so I am replying here.
I disagree with this and think he has it backwards; the majority of applications will benefit from early-out multiplication, and it's only crypto that wants constant-time. Also, MUL has never been constant-time on x86, ever since the 8086. My suggestion would be to add a control register bit that puts the CPU into a mode where the guarantees needed for crypto are true. All that software would need to do is set the bit before performing sensitive operations, and clear it afterwards.
Heck, the entire concept of Intel's "Hyperthreading" kills any pipeline determinism you would hope to achieve.
Consider your typical ARM read-modify stall: add r1, r2 / add r1, r3. A stall needs to be inserted into the pipeline because r1's value will change.
In contrast, the typical Out-of-Order (OoO) x86 computer (Steamroller, Ivy Bridge, and Bay Trail) will attempt to look at future instructions to execute during the pipeline stall. In the case of Hyperthreaded CPUs (Intel i7, i3, older Atoms), Intel will grab instructions from _another thread_ to execute while the stall is undergoing.
And worse yet, as Intel and AMD upgrade their systems, sometimes there are massive architectural differences which cause regressions in some code. The infamous AMD Bulldozer (2011 chip) regressed in FPU and Vectorized code for instance, while AMD tried to up the core count and improve integer performance.
If you really want to step into this arena, just use Agner Fog's optimization manual.
http://www.agner.org/optimize/instruction_tables.pdf
But... it isn't as simple as ARM because x86 CPUs are far more complicated. Out-of-order processors just kill any determinism you have.... let alone hyperthreading or the other tricks these bigger CPUs do.
Now hyperthreading does introduce real non-determinism from the standpoint of a single threaded calculation because it doesn't control the other thread using processor resources, but hyper threading introduces that sort of non-determinism even on in order processors.
It may be deterministic at the micro-architecture level, but it is non-deterministic at the architecture level.
And then there are many other things in the mix: speculative execution, instruction tracing, etc.
A 486 and an original Atom are both in order implementations the i386 architecture (though both also implement other extensions), but knowing how code runs on one tells me nothing about the other, and if I just have an ISA reference the i386 without additional documentation or hardware to test on I won't be able to predict how code I write performs on either of them.
Cortex-A15 you get nothing official, even though there's quite a few hidden gotcha's that are critical for performance (Did you know that the NEON pipelines are 64-bit wide? Or that there's only 1 VFP pipeline whereas there's two symmetric NEON pipelines? That's some of the barest of basics, yet nowhere does ARM publicly document this info.)
Intel you get execution port categories (though you have to infer exactly which instructions fall into which categories), official timings (again inferring precise µop counts), and all sorts of details as to the inner workings of pipelines (random example: there's an entire section about how store forwarding works in Nehalem in the optimization manual, which is quite beyond the detail you'd see in any official ARM manual.)
And that's not counting Agner Fog and the details Intel feeds tech journalists.
No one makes modifications that could affect instruction timings (which is a very fundamental aspect of a core), and I very much doubt such modifications are even allowed in the license you buy the cores under, even with a separate architectural license (which is for ground-up designs). Even NVIDIA who bragged about their A9 and A15 core revisions only gave feedback to ARM and had to have them actually implement the changes, and none of those changes affected instruction timing.
How to design an elliptic-curve signature system — There are many choices of elliptic-curve signature systems. The standard choice, ECDSA, is reasonable if you don't care about simplicity, speed, and security.
He goes on to demonstrate his point in minute details.
You could provide all of the isolation and funky instructions that you want without affecting the general purpose CPU. It may also be more efficient as it is a special purpose processor.
http://soekris.com/products/vpn14x1.html
I doubt they will ever become ubiquitous. For most people CPU crypto will always be good enough and saving a few dollars is more important. Otherwise you would already own one.
As djb emphasizes in the article, if it's too expensive it might not make sense for Intel to implement it.
When you're building servers that need to specialize in encryption. The separate chips are often called "cryptoprocessors". https://en.wikipedia.org/wiki/Secure_cryptoprocessor
An example of commercialized cryptoprocessors: http://www.tiempo-ic.com/products/ip-cores/cryptoprocessors....
What DJB is asking (IMHO) is for improvements to general-purpose processors, for example the processor you already have in your laptop.