Показать сообщение отдельно
Старый 17.01.2006, 17:34   #14
AsmLover
Оператор ЭВМ
 
Регистрация: 12.01.2006
Сообщений: 21
Написано 0 полезных сообщений
(для 0 пользователей)
Originally posted by impersonalis@Sep 19 2005, 04:39 PM

Настоятельно рекомендую использовать операцию *.5 вместо /2, и вот почему.
Простенький тест уменьшит все числа ряда от 1 до 30000 двумя способами, измерив при этом время выполнения:
time1=MilliSecs()
For i=1 To 30000
	a=i/2
Next
time1=MilliSecs()-time1
time2=MilliSecs()
For i=1 To 30000
	a=i*.5
Next
time2=MilliSecs()-time2
Print " [\2] "+time1
Print " [*.5] "+time2
WaitKey()
У меня результаты 75 и 4* :o
Комментарии излишни...
Возвращаясь к вышеизложенному, с прискорбием сообщаю, что ув. г-н Impersonalis не прав абсолютно. Меня заинтересовала полученная разница во времени, которая не может быть объяснена никакими таймингами и тактами процессора, FPU и т.д.

Итак, ищем причину странного явления.

Добавим в самое начало программы простую строку - Delay 3000.
Происходит чудо ) - времена выравниваются! Если задержку уменьшать, то, соответственно, первое время начинает возрастать. Что происходит? Смотрим - режим отладки включен! Вот он, мерзавец, и вступил в тайный сговор с Impersonalisom!
Но нет, если поменять местами а=i/2 и a=i*.5, то есть a=i*.5 вставить в первый цикл, то НИЧЕГО не меняется!

Просто - напросто при включенной отладке запускается дополнительно в фоне основной программы инициализация отладчика - выделяется память под символьные переменные, переключается стек, нумеруются строки и пр. Это может длится пару секунд (чем слабее процессор, тем дольше). Соответственно, самый первый тест выполняется медленнее.

Чтобы это устранить, нужно задать в цикле не 30 тысяч вычислений, а три миллиона. Тогда этот эффект нивелируется. Ну а лучше вообще отключить отладку и попробовать посчитать:


time1=MilliSecs()
For i=1 To 3000000
 * *a = i * .5
Next
time1=MilliSecs()-time1

time2=MilliSecs()
For i=1 To 3000000
 * *a = i / 2
Next
time2=MilliSecs()-time2

time3=MilliSecs()
For i=1 To 3000000
 * *a = i Shr 2
Next
time3=MilliSecs()-time3

time4=MilliSecs()
For i=1 To 3000000
 * *b# = i / 3
Next
time4=MilliSecs()-time4

Print " [*.5] " * + time1
Print " [/2] " * *+ time2
Print " [shr 2] " + time3
Print " [/3#] " * + time4
WaitKey()
Теперь все встает на свои места. У множение на .5 использует FPU, естественно, оно медленнее регистрового сдвига SHR 1. Деление на 2 целого числа компилятор заменяет на сдвиг, поэтому деление целых чисел на 2 ГОРАЗДО БЫСТРЕЕ умножения на .5. Ну и медленне всего (из представленных вариантов) выполняется деление на 3.

ЛОГИЧЕСКИЙ СДВИГ РУЛИТ - это делается одним сдвигом процессорного регистра!

Предлагаю тов. Impersonalis заменить рекламный слоган.
(Offline)
 
Ответить с цитированием