· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.A&O —› Привести число к виду 1 + 2^k * q

. 1 . 2 . 3 . >>

Посл.отвђт Сообщен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

. 1 . 2 . 3 . >>


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.066