|
FAQ Туториалы и часто задаваемые вопросы |
19.09.2005, 18:39
|
#1
|
Зануда с интернетом
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений (для 20,935 пользователей)
|
Настоятельно рекомендую использовать операцию *.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
Комментарии излишни...
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
19.09.2005, 18:48
|
#2
|
Зануда с интернетом
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений (для 20,935 пользователей)
|
101 к 8 проиграло деление умножению при работе с float
time1=MilliSecs()
For i=1 To 30000
a#=i*0.3/2
Next
time1=MilliSecs()-time1
time2=MilliSecs()
For i=1 To 30000
a#=i*0.3*.5
Next
time2=MilliSecs()-time2
Print " [\2] "+time1
Print " [*.5] "+time2
WaitKey()
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
19.09.2005, 18:52
|
#3
|
Зануда с интернетом
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений (для 20,935 пользователей)
|
140 к 10
при случайной подборке чисел (int/float)
time1=MilliSecs()
For i=1 To 30000
If Rand(0,1)=1
a#=i*0.3/2
Else
a=i/2
EndIf
Next
time1=MilliSecs()-time1
time2=MilliSecs()
For i=1 To 30000
If Rand(0,1)=1
a#=i*0.3*0.5
Else
a=i*0.5
EndIf
Next
time2=MilliSecs()-time2
Print " [\2] "+time1
Print " [*.5] "+time2
WaitKey()
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
22.09.2005, 03:05
|
#4
|
|
Всё по нулям, по этой причине увеличил цикл на несколько порядков
в первом - /2 в 3 раза быстрее *.5
в остальных - почти поровну, ну 0.5 немного впереди.
П4 2.8, 512.
|
|
|
22.09.2005, 09:00
|
#5
|
|
7,7
7,6
16,13
и кто же у нас быстрее ? :o
|
|
|
22.09.2005, 15:13
|
#6
|
Администратор
Регистрация: 03.09.2005
Сообщений: 2,408
Написано 301 полезных сообщений (для 996 пользователей)
|
а теперь дружненько напишем у кого какой проц... чтоб точно знать как оно и где вполняется..
__________________
Как минимум я помог многим (с)
|
(Offline)
|
|
22.09.2005, 15:40
|
#7
|
Дэвелопер
Регистрация: 04.09.2005
Адрес: Красноярск
Сообщений: 1,376
Написано 491 полезных сообщений (для 886 пользователей)
|
вижу появление запятой в названии темы!
А если часто надо использовать что-то вроде этого: value = value + 1.0/koef
тогда как?
Если koef не меняется, то понятно, а если меняется? Можно ускорить как-то?
|
(Offline)
|
|
22.09.2005, 17:34
|
#8
|
Администратор
Регистрация: 03.09.2005
Сообщений: 2,408
Написано 301 полезных сообщений (для 996 пользователей)
|
тогда прийдется делить..... да ладно вы так, все это всерьез принимать... не так уж это и страшно... вы просмотрите свой код, через сколько итераций у вас наберется 30000 действий деления?? не через 5000 ли??
оно (умножение) конечно и увеличивает скорость но не надо этим увлекаться, а то щас начнем писать функцию в которой будем просматривать, что если значение четное, то использовать ротацию и т.п....
УМНОЖАЙТЕ ПРИ СЛУЧАЕ, А В ОСТАЛЬНОМ НЕ БЕСПОКОЙТЕСЬ!
__________________
Как минимум я помог многим (с)
|
(Offline)
|
|
22.09.2005, 19:09
|
#9
|
Зануда с интернетом
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений (для 20,935 пользователей)
|
Originally posted by SubZer0@Sep 22 2005, 03:34 PM
конечно и увеличивает скорость но не надо этим увлекаться, а то щас начнем писать функцию в которой будем просматривать, что если значение четное, то использовать ротацию и т.п....
|
или с криками "долой выгрузку в стек!" на GOTO кодить
да гото чуть быстрее, но сомневаюсь, что в вашей проге применение оператора безусловного перехода будет оправдано
Тесты выполнять надо несколько раз и брать среднее - я поторопился и не автоматизировал этот процесс, сорри :o''
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
|
(Offline)
|
|
22.09.2005, 23:46
|
#10
|
|
интересно пять раз проверил - одно и тоже было , pentium 4 1.7ghz
|
|
|
23.09.2005, 00:01
|
#11
|
Администратор
Регистрация: 03.09.2005
Сообщений: 2,408
Написано 301 полезных сообщений (для 996 пользователей)
|
у мя на Athlon XP Pro3+ работает где деление на два у мя быстрей деление работает, а вот такой код
time1=MilliSecs()
For i=1 To 1000000
a=i/10
Next
time1=MilliSecs()-time1
time2=MilliSecs()
For i=1 To 1000000
a=i*.1
Next
time2=MilliSecs()-time2
Print " [/2] "+time1
Print " [*.5] "+time2
WaitKey()
то результат обычно 42 и 14
вот такой код
time1=MilliSecs()
For i=1 To 1000000
a=i/5
Next
time1=MilliSecs()-time1
time2=MilliSecs()
For i=1 To 1000000
a=i*.2
Next
time2=MilliSecs()-time2
Print " [/2] "+time1
Print " [*.5] "+time2
WaitKey()
работает 46 и 15
умножение рулит!
__________________
Как минимум я помог многим (с)
|
(Offline)
|
|
01.01.2006, 22:46
|
#12
|
|
Originally posted by SubZer0@Sep 22 2005, 10:01 PM
у мя на Athlon XP Pro3+ работает где деление на два у мя быстрей деление работает, а вот такой код
time1=MilliSecs()
For i=1 To 1000000
a=i/10
Next
time1=MilliSecs()-time1
time2=MilliSecs()
For i=1 To 1000000
a=i*.1
Next
time2=MilliSecs()-time2
Print " [/2] "+time1
Print " [*.5] "+time2
WaitKey()
то результат обычно 42 и 14
вот такой код
time1=MilliSecs()
For i=1 To 1000000
a=i/5
Next
time1=MilliSecs()-time1
time2=MilliSecs()
For i=1 To 1000000
a=i*.2
Next
time2=MilliSecs()-time2
Print " [/2] "+time1
Print " [*.5] "+time2
WaitKey()
работает 46 и 15
умножение рулит! :rolleyes:
|
Рулит не умножение, а знание алгоритмов, по которым работает транслятор/компилятор конкретного языка (вернее, конкретной реализации). Например, операции целочисленного деления или умножения могут выполняться заменой на операции сдвига и суммирования, то есть
x / 2 = x shl 2
x / 5 = 10 * x / 2 = ((x shr 3)+(x shr 1)) shl 2
и т.д.
Blitz3D из вышеперечисленного оптимизирует только деление на два.
Поэтому, заменив в примере из предыдущегого поста x / 5 на вышеприведенную формулу, умножение больше не рулит:
time1=MilliSecs()
For i=1 To 1000000
a=((i Shr 3) + (i Shr 1)) Shl 2
;a=i / 5
Next
time1=MilliSecs()-time1
time2=MilliSecs()
For i=1 To 1000000
a=i * .2
Next
time2=MilliSecs()-time2
Print " [/2] "+time1
Print " [*.5] "+time2
WaitKey()
А для разработчиков Blitza было бы лучше вообще перейти на арифметику с фиксированной точкой, (даже тип double не спасет за счет относительно низкой скорости). Тем более сейчас уже наступила эра 64-битных процессоров.
Хотя Марку все равно респект и уважение.
|
|
|
07.01.2006, 21:35
|
#13
|
|
Сорри за описку в предыдущем посте - Новый год, все-таки был!
Нужно поменять местами команды SHL и SHR (естественно, сдвиг вправо делит целое число на два, а сдвиг влево - умножает. Хотя именно в том примере это не принципиально, но тем не менее прокол-с.)
|
|
|
17.01.2006, 17:34
|
#14
|
Оператор ЭВМ
Регистрация: 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)
|
|
17.01.2006, 21:17
|
#15
|
Зануда с интернетом
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений (для 20,935 пользователей)
|
Ну, то что "сдвиг рулит" - это очевидно. Я как-то заметил вот такую констукцию на С++
и теперь стараюсь её юзать при написании быстрых алгоритмов.
В остальных же случаях это не критично.
Не совсем правда понял - почему AsmLover сдивгает на 2 разряда (т.е. делит на 2^2=4, а не на один разряд )
Вот за дополнительные расследования - респект.
Переходим на деление обратно.
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
|
(Offline)
|
|
Ваши права в разделе
|
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 18:36.
|