Феномен ХР раскрыт!

Разговоры на любые темы: вы можете обсудить здесь какой-либо сайт, найти единомышленников или просто пообщаться...
Ariman
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 817
Зарегистрирован: 02.09.2003 (Вт) 16:23
Откуда: Великая наша держава, г.Москва

Феномен ХР раскрыт!

Сообщение Ariman » 30.05.2005 (Пн) 17:53

К сожалению, найти ссылку на соответствующую тему я не смог, поиск не работает, ну да ладно, на всякий случай напомню, о чем там шел разговор...........

Предположим, что у нас есть цикл, который выполняется до тех пор, пока работает программа. Таким, например, может быть главный цикл игры, в котором отрисовывается графика, просчитываются различные игровые параметры и т.д........
Так вот, если не принять меры, то программа с таким циклом, будучи перенесенной на более мощый компьютер будет работать быстрее, а это не всегда хорошо.
Представьте, что будет, если программа разрабатывалась под какой-нибудь Celeron 533, а ее перенесли на пентиум 4, 2.8 ГГЦ.... В этом случае, она будет просто летать....

Есть несколько методов избежать этого - например, при передвижении объекта не приплюсовывать координаты, а задать их как функцию от времени...
Но что плохо - если программа уже написана, то переделывать ее придется долго и муторно.
Есть другой вариант - замедлить цикл. Конечно, замедлять его в прямом смысле не стОит - это приведет к лишней нагрузке на процессор. Поэтому многие люди(и я в том числе) делали так:

1) Смотрим, сколько времени прошло с последнего выполнения цикла
2) Если прошло меньше времени, чем Duration миллисекунд, то пропускаем текущую итеррацию, переходя сразу в конец цикла.

В коде это выглядит так:

do

СurrentTick=GetTickCount()
If (СurrentTick - LastTick) >= Duration) Then
LastTick = СurrentTick
'.....................
'Здесь выполняем все, что нам нужно - отрисовываем карту,
'рассчитываем положения игроков, подбираем пароль к базам
'ФБР и т.д.
'.....................
end if

DoEvents
Loop


Теперь суть проблемы: в 98-х данный код работает на УРА - до тех пор пока не пройдет Duration мс пропускает тело цикла, и тем самым скорость регулируется.
НО!
В ХР код начинает ЖУТКО тормозить. Для примера - при значении Duration = 3 цикл в 98 показывает 200 итерраций в секунду(не пустой, разумеется :wink: ), а под ХР - 64!

Здесь было высказанно множество вероятных причин и пара вероятных способов решения... Но ни одна из причин не была полностью соответствующей действительности и выссказанной доконца, ни одно из решений не помогало.
А оказалось все довольно просто..

Все дело в том, что в Win98 GetTickCount возвращает значения с точностью до 1 Мс, а в ХР - с точность до 10.....
Т.е. в XP GetTickCount считает десятками, и за 1000 МС идет 1010 МС.... вот так-то... А это, разумеется, приводит к тому, что минимальное дельта-время равно 10 МС, а значит, значение Duration от 0 до 10 эквивалентно значению 10....

В этом легко убедиться, попробовав запустить этот код в ХР, с подсчетом итерраций в секунду, и проверить показания при Duration=3 и Duration=10. Результат будет одинаковый.

Ну, зная причину, легко найти и способ решения - использовать боее точную функцию. Я сам теперь использую QuerryPerformanceCounter, благодаря которой можно получить значения с точностью до 10^-14 c

Замедляйте на здоровье :D
P.S. Если нужны примеры кода - скажите.
Выложу пример с подсчетом итерраций, с GetTickCount и такой же, но с QuerryPerformanceCounter.............

RayShade
Scarmarked
Scarmarked
Аватара пользователя
 
Сообщения: 5511
Зарегистрирован: 02.12.2002 (Пн) 17:11
Откуда: Russia, Saint-Petersburg

Сообщение RayShade » 30.05.2005 (Пн) 17:54

А вы знаете, что Linux обрабатывает на 50% больше бесконечных циклов в час, чем Windows? :)

Ariman
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 817
Зарегистрирован: 02.09.2003 (Вт) 16:23
Откуда: Великая наша держава, г.Москва

Сообщение Ariman » 30.05.2005 (Пн) 18:00

RayShade
Учитывая то, что даже в ХР GetTickCount считает десятками, то не удивлюсь, если это так :lol: :lol:

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Re: Феномен ХР раскрыт!

Сообщение tyomitch » 30.05.2005 (Пн) 18:45

Ariman писал(а):Ну, зная причину, легко найти и способ решения - использовать боее точную функцию. Я сам теперь использую QuerryPerformanceCounter, благодаря которой можно получить значения с точностью до 10^-14 c

Ну-ну... Расскажи ещё, откуда в твоём компьютере таймер, позволяющий отмерять такие интервалы? Афаик даже 10^-6 с нереально отмерить компьютером. Один цикл проца длится порядка 10^-9 c, а в твоём компе есть таймер с в 100 000 раз большим быстродействием? :roll: :roll:
Изображение

Ariman
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 817
Зарегистрирован: 02.09.2003 (Вт) 16:23
Откуда: Великая наша держава, г.Москва

Сообщение Ariman » 30.05.2005 (Пн) 19:04

tyomitch
Да, это я, кончно ошибся :oops:
Просто дело в том, что итоговое значение получается делением на значение, возвращенное QueryPerformanceFrequency, чтобы получить значение в секундах, так там и получается число с 14 знаками после запятой.....
Как-то сразу не вспомнил, что это не QPC его возвращает :lol:


Вернуться в Народный треп

Кто сейчас на конференции

Сейчас этот форум просматривают: Google-бот и гости: 67

    TopList  
cron