Chciałbym mojej funkcji C, aby skutecznie obliczyć wysokie 64 bitów produktu dwóch 64-bitowych podpisanych int. Wiem, jak to zrobić w montażu x86-64, z imulq i wyciągając wynik z% rdx. Ale nie jestem w stanie napisać tego w C, nie mówiąc już o tym, żeby kompilator działał wydajnie.Obliczanie wysokiej 64 bitów 64x64 int produktu w C
Czy ktoś ma jakieś sugestie dotyczące pisania tego w C? Jest to wrażliwe na wydajność, więc "metody ręczne" (takie jak rosyjski chłop czy biblioteki bignum) są obecnie niedostępne.
Ta funkcja dorky montaż inline pisałem działa i jest grubsza Codegen Jestem po:
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;
}
Chciałbym użyć współczynnika h. To daje (ha + b) * (hc + d) = hhac + miał + hbc + bd. "H" jest w zasadzie sposobem na śledzenie skali 32-bitowej. Każdy z terminów wymaga 64 bitów (pomijając czynniki h), dając 32-bitowe przenoszenie, ale (2^n) -1 * (2^n) -1 = (2^2n) - 2 (2^n) + 1, który jest <(2^2n) -1, pozostawiając rezerwę, aby dodać przeniesienie na niższe terminy. Termin hhac jest czystym przelewem, podobnie jak w przypadku terminów had i hbc. Prawdopodobnie możesz użyć h (ad + bc) zamiast mieć + hbc - więcej niż 64 bity, ale przepełnienie nie ma znaczenia - zrezygnujesz z przeniesienia. – Steve314
Steve314: zrobiłeś to już wcześniej! Słuszne uwagi. Wczoraj wieczorem napisałem implementację i wysłałem ją jako nową odpowiedź. – DigitalRoss