Реально быстрый алгоритм вычисления НОД
Запись от Jin X размещена 03.02.2018 в 02:24
Показов 4896
Комментарии 0
Метки asm, asm7x, euclid, fasm, gcd, math, алгоритм, алгоритм евклида, алгоритмы, бинарный алгоритм, математика, наибольший общий делитель, нод
|
Реально быстрый алгоритм вычисления НОД Основными популярными алгоритмами вычисления наибольшего общего делителя (НОД) являются алгоритм Евклида и бинарный алгоритм. Первый очень простой и компактный, второй – якобы быстрый, поскольку в нём отсутствуют "долгие" операции деления, а присутствуют лишь операции сдвига. Однако на практике бинарный алгоритм зачастую работает раза в 2(!) медленнее алгоритма Евклида, поскольку в нём присутствует довольно много операций ветвления. Описанные в различных источниках бинарные алгоритмы вычисления НОД (в т.ч. в Википедии) подразумевают единичные операции на каждом цикле итерации и кучу проверок. По факту же за одну итерацию можно совершить сразу группу операций (сдвигов). Для тех, кто знает, как работает этот алгоритм, поясню, что сдвиг (деление пополам) можно производить безо всяких лишних проверок до тех пор, пока каждое из чисел не станет нечётным. После этого уже можно сделать сравнение значений с единицей, а далее (при отсутствии единицы) – нахождение разницы полученных нечётных значений с делением пополам и повтор цикла. Проверку же на 0 достаточно сделать 1 раз в самом начале. ![]() А вот, собственно, и сам код (на fasm):
Скорость работы бинарного алгоритма выше алгоритма Евклида примерно на 35-40% (на моём компьютере с процессором Intel Core i5-2500K @ 3.7 ГГц). Для кого-то это может показаться несущественным, поэтому алгоритм Евклида вполне имеет право на жизнь . Кроме того, справедливости ради хочу сказать, что в алгоритме Евклида отсутствуют инструкции cmovcc, требующие процессора Pentium Pro+ (правда, сейчас трудно найти более слабый процессор), без которых скорость алгоритма значительно снизится. К тому же, бинарный алгоритм не может работать с отрицательными числами (даже если заменить shr на sar), хотя этот вопрос легко решается заменой первых инструкций (до метки .next) на следующие, приводящие оба числа к абсолютному (положительному) значению:
![]() Прикрепляю к статье архив с исходниками и программами для теста корректности и скорости работы алгоритмов. Наслаждайтесь ![]() Эта и другие мои статьи на форуме. Updated 03.02.2018:
p.s. Тестовые программы есть только в архиве GCD.zip !!! | |||||||||||||||
Метки asm, asm7x, euclid, fasm, gcd, math, алгоритм, алгоритм евклида, алгоритмы, бинарный алгоритм, математика, наибольший общий делитель, нод
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 0
Комментарии


. Кроме того, справедливости ради хочу сказать, что в алгоритме Евклида отсутствуют инструкции 

