Чтобы сделать этот расчет в сборке, но иметь его отозван из Python, я бы попробовать inline assembly из Python module written in C. Оба компилятора GCC и MSVC имеют встроенную сборку только с различным синтаксисом.
Обратите внимание, что наш модуль p = 1000000007
просто подходит для 30-бит. Результат желаемый (a*b)%p
может быть вычислен в регистрах Intel 80x86 с учетом некоторых слабых ограничений на a,b
не намного больше, чем p
.
Ограничения по размеру a,b
(1) a,b
являются 32-разрядные целые числа без знака
(2) a*b
меньше p << 32
, т.е.p
раз 2^32
В частности, если a,b
каждого меньше, чем 2*p
, переполнение будет предотвращено. Учитывая (1), также достаточно, чтобы либо один из них был меньше p
.
Инструкция Intel 80x86 MUL может умножить два 32-разрядных целых числа без знака и сохранить 64-разрядный результат в пачке регистра аккумуляторов EDX: EAX. Некоторые детали и причуды MUL обсуждаются в Разделе 10.2.1 этого полезного summary.
Инструкция DIV может затем разделить этот 64-разрядный результат на 32-битную константу (модуль p
), сохраняя значение в EAX и остальную часть EDX. См. Раздел 10.2.2 последней ссылки. Результат, который мы хотим, это остаток.
Это такое разделение команд DIV, что влечет за собой риск переполнения, должны 64-битный продукт в числитель EDX: EAX дают фактор больше, чем 32 бита , будучи не удовлетворяют условию (2) выше.
Я работаю над фрагментом кода в сборке C/inline для «доказательства концепции». Однако максимальное преимущество в скорости будет зависеть от массивов дозаций данных a,b
для обработки, амортизации служебных вызовов функций и т. Д. В Python (если это целевая платформа).
Ну, один простой оптимизации было бы объединить все, что в одно заявление ... это примерно на 6% быстрее в моих тестах. – kindall
«Быстрое модульное умножение» в Googling дает ряд документов, таких как [этот] (http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?arnumber=5638011). – unutbu
9 цифр могут быть слишком малы для специальных алгоритмов, таких как [Montgomery reduction] (http: // ru.wikipedia.org/wiki/Montgomery_reduction) дают какую-либо пользу. Не оптимизируйте преждевременно. Каков источник 'a, b' (структура данных)? Что говорит ваш профайлер? – jfs