|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Авг 17, 2004 00:41:23 Дано - нечетное составное n. Требуется привести n к виду n = 1 + 2kq, где q - нечетное. Прототип функции должен выглядеть так: void do_n(unsigned n, unsigned *k, unsigned *q) -> т.е. функция должна вернуть k и q для данного n. Уравнение можно немножко перевернуть. Изменить его к виду: q = (n - 1)/2k, где k пробегает значения от 0 до ??? - пока не додумался :( Далее q проверяется на нечетность. Задача - оптимизировать по скорости. |
|
|
Дата: Авг 17, 2004 01:01:06 · Поправил: DaemoniacaL q = n-1 while (q is even) { q = q shr 1 } (пока чисто алгоритмически :) |
|
|
Дата: Авг 17, 2004 01:06:35 Я сказал, что функция ДОЛЖНА вернуть k и q для данного n. А ты что написал? Тут просто большой простор для оптимизации. И надо дотумкать до какого k крутить цикл... |
|
|
Дата: Авг 17, 2004 01:36:17 Для начала пусть будет так: dec eax xor ecx,ecx @@: add ecx, 1 ; на PIV быстрее чем inc ecx mov edx, eax shr eax, 1 ja @b mov q, edx dec ecx mov k, ecx С 1 на входе не совсем ясно, у меня приводится к виду: 1+20*0 но 0 - это чётное число. Смысл тут простой - считается количество множителей 2. Думаю это можно ускорить если как-нибудь сразу выдельть 2k, но пока не знаю как :( |
|
|
Дата: Авг 17, 2004 01:59:53 volodya Извиняюсь, это спросонья :)) mov eax, n xor ecx, ecx ; - это будет k dec eax jnp @@exit jz @@err ; - если n > 1 на входе то это можно убрать bsf ecx, eax shr eax, ecx @@exit: ; q = eax ; k = ecx @@err: ; как реагировать на 0?? |
|
|
Дата: Авг 17, 2004 02:04:35 · Поправил: S_T_A_S_mov eax, n dec eax bsf ecx, eax shr eax, cl mov q, eax mov k, ecx О, это уже есть, я думаю долго :) |
|
|
Дата: Авг 17, 2004 02:06:42 S_T_A_S_ Только сдвигать то вправо надо :)) |
|
|
Дата: Авг 17, 2004 02:07:45 Да у меня что-то глюки с копированием кода из olly :) |
|
|
Дата: Авг 17, 2004 02:14:25 Кстати, непонятно ещё, какой вариант будет быстрее - bsf инструкция тормозная (особенно на athlon), а на PIV shr eax, cl медленно выполняется. imho тут от самих чисел будет зависить. |
|
|
Дата: Авг 17, 2004 02:27:48 S_T_A_S_ Нужно просто посчитать время выполнения для варианта с циклом и с bsf |
|
|
Дата: Авг 17, 2004 03:12:28 DaemoniacaL Во-во, но это нужно сделать для всех возможных чисел, учесть вероятность появления каждого из них.. (дальше у меня нехватка математических терминов/знаний, может какие-нибудь там дисперсии :0). Например для чисела вида 2n-1 цикл будет явно быстерее, чем те 2 команды, а для 2n+1 - медленнее. |
|
|
Дата: Авг 17, 2004 03:23:16 S_T_A_S_ Кстати bsf не такой уж и медленный, время его выполнения зависит от числа, и составляет от 6 до 42 тактов для 486. shr - reg, cl = 3 такта.. видимо все таки без цикла будет быстрее |
|
|
Дата: Авг 17, 2004 05:17:00 Дык таких процев уже нет давно :) На athlon и PIV bsf - 8 тактов, в то время как итерация цикла ~ 1-2 такта при правильном предсказании. Вот с shr на PIV проблема -сама команда 4 такта (против 1 на P3), и судя по всему сдвиги > 1 он вообще хреново делает :( документация у них странная стала - половина цифр отсутствует :/ Короче, нужно код компилить и смотреть под профайлером на конкретной задаче, тут только от того, что функцию заинлайнить уже прирост должен быть заметный. |
|
|
Дата: Авг 17, 2004 06:20:37 Да, господа, впечатлен :) Я тут с тренировки пришел. Только как раз подумал, что надо не 2 в степень возводить, а подсчитывать количество итераций как при делении в столбик :) S_T_A_S_, только я не совсем понимаю, что значит: считается количество множителей 2 Множитель-то, в конечном итоге, один! |
|
|
Дата: Авг 17, 2004 06:25:19 А-а! Понял! @@: add ecx, 1 ; на PIV быстрее чем inc ecx mov edx, eax shr eax, 1 ja @b Количество делений на 2! Как в столбик :) Да, и еще. Где тут цикл? mov eax, n dec eax bsf ecx, eax shr eax, cl mov q, eax mov k, ecx |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.066 |