Me gustaría que mi función C calcule eficientemente los 64 bits altos del producto de dos entradas firmadas de 64 bits. Sé cómo hacer esto en el ensamblaje x86-64, con imulq y sacando el resultado de% rdx. Pero no sé cómo escribir esto en C, y mucho menos convencer al compilador para que lo haga de manera eficiente.Computing alto 64 bits de un producto int 64x64 en C
¿Alguien tiene alguna sugerencia para escribir esto en C? Esto es sensible al rendimiento, por lo que los "métodos manuales" (como Russian Peasant, o bignum libraries) están fuera.
Esta función ensamblado en línea dorky escribí funciona y es más o menos la codegen que busco:
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;
}
Me gusta usar un factor h. Eso da (ha + b) * (hc + d) = hhac + had + hbc + bd. La 'h' es básicamente una forma de seguir la escala de 32 bits. Cada uno de los términos necesita 64 bits (dejando fuera los factores h), dando 32 bits acarreos, pero (2^n) -1 * (2^n) -1 = (2^2n) - 2 (2^n) + 1, que es <(2^2n) -1, dejando margen para agregar un acarreo de menor duración. El término hhac es puro desbordamiento, como lo son los carry de los términos had y hbc. Probablemente puedas usar h (ad + bc) en lugar de had + hbc - son más de 64 bits, pero el desbordamiento no importa - descartas ese carry de todos modos. – Steve314
Steve314: ¡has hecho esto antes! Buenos puntos. Escribí una implementación anoche y la envié como una nueva respuesta. – DigitalRoss