Я бы хотел, чтобы моя функция C эффективно вычисляла 64-разрядные 64-разрядные данные из двух 64-битных подписных int. Я знаю, как это сделать в сборке x86-64, с imulq и вытягивая результат из% rdx. Но я не понимаю, как написать это в C вообще, не говоря уже о том, чтобы заставить компилятор сделать это эффективно.Вычисление высоких 64 бит 64x64 int продукта в C
У кого-нибудь есть предложения по написанию этого в C? Это чувствительно к производительности, поэтому «ручные методы» (например, русские крестьяне или библиотеки бигума) отсутствуют.
Этой функция тупой встроенного ассемблера я писал работу и примерно Codegen я после:
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;
}
Мне нравится использовать коэффициент h. Это дает (ha + b) * (hc + d) = hhac + has + hbc + bd. «H» - это в основном способ отслеживания 32-битной шкалы. Каждому из терминов требуется 64 бита (исключая h-факторы), давая 32-битные переносы, но (2^n) -1 * (2^n) -1 = (2^2n) - 2 (2^n) + 1, что составляет <(2^2n) -1, оставляя запас, чтобы добавить более низкий перенос. Термин «ххак» - это чистое переполнение, равно как и переносы из условий has и hbc. Вероятно, вы можете использовать h (ad + bc), а не иметь + hbc - его более 64 бит, но переполнение не имеет значения - вы все равно отказываетесь от этого. – Steve314
Steve314: вы сделали это раньше! Хорошие моменты. Я набрал последнюю версию и отправил ее в качестве нового ответа. – DigitalRoss