Я пишу код на C для исследовательского проекта по теории чисел, который требует выполнения множества операций модульной арифметики с множеством разных модулей. Проще говоря: мне нужно выполнить операцию (a * b) % n
много-много раз.
Код предназначен для работы на ПК с 64-битными словами, и известно, что все модули меньше 2^64, поэтому все операнды реализованы беззнаковыми 64-битными целыми числами.
Мой вопрос: приведет ли использование модулярного умножения Монтгомери (использующего только сложение и умножение) вместо оператора по модулю C %
(который преобразуется в a % n = a - n*(a / n)
и также использует деление) к более быстрому выполнению?
Интуитивно я бы сказал, что ответ таков: нет, потому что деление (размером слова) на ПК не слишком затратно в вычислительном отношении, чем умножение (размером слова), а сокращение Монтгомери на самом деле вызовет накладные расходы.
Спасибо за любые предложения.
Обновление: с одной стороны, по словам Пола Огилви (см. его комментарий ниже), (a * b) % n
требует 1 умножения и 1 деления. С другой стороны, умножение Монтгомери требует (игнорируя операции, необходимые для преобразования и обратного преобразования операндов в их представления Монтгомери, поскольку они выполняются один раз только для каждого модуля n; и двоичные сдвиги) 3 умножения. Таким образом, кажется, что Монтгомери быстрее, чем ``%'', поскольку умножение выполняется в два раза быстрее, чем деление...