Note that there are some explanatory texts on larger screens.

plurals
  1. POOptimizing x64 assembler MUL loop
    primarykey
    data
    text
    <p>I'm writing math code which needs to multiply large numbers fast. It breaks down to multiplications of an array of integers with a single integer. In C++ this looks like this (on unsigned's):</p> <pre><code>void muladd(unsigned* r, const unsigned* a, unsigned len, unsigned b) { unsigned __int64 of = 0; // overflow unsigned i = 0; // loop variable while (i &lt; len) { of += (unsigned __int64)a[i] * b + r[i]; r[i] = (unsigned)of; of &gt;&gt;= 32; ++i; } r[i] = (unsigned)of; // save overflow } </code></pre> <p>I unrolled this loop manually, converted it to 64 bit and worked on the .asm compiler output to optimize it further. The main .asm loop now looks like this:</p> <pre><code>mov rax, rdi ; rdi = b mul QWORD PTR [rbx+r10*8-64] ; rdx:rax = a[i] * b; r10 = i mov rsi, QWORD PTR [r14+r10*8-64] ; r14 = r; rsi = r[i] add rax, rsi adc rdx, 0 add rax, r11 ; r11 = of (low part) adc rdx, 0 mov QWORD PTR [r14+r10*8-64], rax ; save result mov r11, rdx ; this repeats itself 8 times with different offsets </code></pre> <p>When I benchmark this, I find that it takes about 6.3 cycles on avarage per multiplication on my Core2 Quad. </p> <p>My question is: can I speed this up somehow? Unfortunately, I see no way to avoid one of the additions and the multiplication always needs RDX:RAX, so I need to move the data around and can not sort of "multiply in parallel".</p> <p>Any ideas anyone?</p> <p><strong>Update:</strong> After some more testing, I've managed to bring the speed up to about 5.4 cycles per 64-bit MUL (that includes all add, move and loop overhead). I guess this is about the best you can get on a Core2, since the Core2 does not have a very fast MUL instruction: it has a throughput of 3 and a latency of 6 (resp. 7) cycles. Sandy bridge will be much better with a throughput of 1 and a latency of 3 (resp. 4) cycles.</p> <p>Regarding the much lesser number for GMP: I got that from their source code and it seems to me that it is a theoretical number. But what's sure is that it's a number that was calculated for an AMD K9 CPU. And from what I have read I gather the AMDs have a faster MUL unit than the (older) Intel chips.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload