Vorrei che la mia funzione C calcolasse in modo efficiente gli alti 64 bit del prodotto di due firmati a 64 bit. So come farlo nell'assemblaggio x86-64, con imulq e estraendo il risultato da% rdx. Ma non riesco a scriverlo affatto in C, e tanto meno convincere il compilatore a farlo in modo efficiente.Elaborazione di alti 64 bit di un prodotto int 64x64 in C
Qualcuno ha qualche suggerimento per scrivere questo in C? Questo è sensibile alle prestazioni, quindi i "metodi manuali" (come le librerie di Russian Beasant o bignum) sono fuori.
Questa funzione assembly inline dorky ho scritto funziona ed è grosso modo la codegen che sto cercando:
static long mull_hi(long inp1, long inp2) {
long output = -1;
__asm__("movq %[inp1], %%rax;"
"imulq %[inp2];"
"movq %%rdx, %[output];"
: [output] "=r" (output)
: [inp1] "r" (inp1), [inp2] "r" (inp2)
:"%rax", "%rdx");
return output;
}
Mi piace usare un fattore h. Ciò dà (ha + b) * (hc + d) = hhac + ha avuto + hbc + bd. La 'h' è fondamentalmente un modo per tenere traccia della scala a 32 bit. Ognuno dei termini ha bisogno di 64 bit (tralasciando i fattori h), dando 32 bit di carrys, ma (2^n) -1 * (2^n) -1 = (2^2n) - 2 (2^n) + 1, che è <(2^2n) -1, lasciando headroom per aggiungere un carry a basso termine. Il termine hhac è puro overflow, così come lo sono le caraffe dai termini had e hbc. Probabilmente puoi usare h (ad + bc) piuttosto che + hbc - ha più di 64 bit, ma l'overflow non ha importanza - lo scarti comunque. – Steve314
Steve314: lo hai già fatto prima! Punti buoni. Ho digitato un'implementazione la scorsa notte e l'ho inviata come una nuova risposta .. – DigitalRoss