Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Sleep(DWORD) - разная задержка на разных компах


Автор: mastaflow 2.5.2008, 13:47
Проблема такая:
пишу змейку - точнее уже написал и работает, но есть некоторый глюк или еще что, который я не могу объяснить

Часть игры выглядит так:
Код

/**
 * gameSpeed = скорость перемещения змейки
 * speedCount = счетчик
 */

while(1) {
    if(kbhit()) {
        input = _getch();
    }
    if(speedCount == gameSpeed) {
        moveSnake(snake, input);
        speedCount = 0;
    }
    speedCount++;
    Sleep(1);
}//while


Соответственно все работает нормально, НО!
На некоторых компах, при запуске исполняемого файла, задержка в данной части кода эквивалентна Sleep(10), т.е. змейка двигается со скоростью в 10 раз меньшей - вот почему так происходит - я не понимаю. При этом в одной части кода Sleep(1000) - работает нормально.
Писал в MS Visual Studio 2008 под вистой.
Тестил на домашнем компе с ХР - работает медленно, тестил на компах друзей - работает нормально, тестил в универе - работает медленно.
В чем может быть подвох?
если что, что скачать змейку можно http://vti160.ucoz.ru/files/Snake_1.1.rar

Автор: JackYF 2.5.2008, 14:18
Во-первых, это надо было не общий раздел, а в раздел по WinAPI. Во-вторых, если мне помнится, задержку в 1 мс тебе ОС не гарантирует, минимум в районе 6-10 мс.

Автор: mastaflow 2.5.2008, 14:26
Цитата(JackYF @  2.5.2008,  14:18 Найти цитируемый пост)
Во-первых, это надо было не общий раздел, а в раздел по WinAPI

Да, соглашусь, не сообразил
Цитата(JackYF @  2.5.2008,  14:18 Найти цитируемый пост)
Во-вторых, если мне помнится, задержку в 1 мс тебе ОС не гарантирует, минимум в районе 6-10 мс.

а обойти это выходит нельзя? Т.е. проще будет изменить задержку?

Автор: JackYF 2.5.2008, 15:09
Цитата(mastaflow @  2.5.2008,  13:26 Найти цитируемый пост)
а обойти это выходит нельзя? Т.е. проще будет изменить задержку? 

Думаю, что да.

Автор: mastaflow 2.5.2008, 15:25
спасибо за помощьsmile, а то сообразить не мог

Автор: mes 2.5.2008, 19:42
Цитата(mastaflow @  2.5.2008,  14:26 Найти цитируемый пост)
а обойти это выходит нельзя? Т.е. проще будет изменить задержку? 

или  не ориентироваться на задержку   (использовать в расчетах коэфициент на прошедшее время)

Автор: mastaflow 3.5.2008, 00:15
В общем я прошел такой путь решения проблемы:
воспользовался функцией GetSystemTimeAdjustment и получил, что системное время обновляется с частотой 15.625 мс, и соответственно задержка в Sleep становится фактичестки кратной данному значению (в среднем).
Предпринял следующее:
Код

    timeBeginPeriod(1);
    Sleep(TIME);
    timeEndPeriod(1);

функция timeBeginPeriod устанавливает интервал обновления таймера. Тестировал на 4х компах с разными процами на ХР, и на двух с Вистой, при этом под управлением ХР вне зависимости от процессора результаты одинаковые, на висте - разнятся:
Код

       реальные значения (ХР)
TIME    ср.знач.    мин.    макс.
1        1.95       1.92    1.98
2        2.93       2.79    3.07
3        3.91       3.32    4.49
4        4.88       4.76    5.01
5        5.86       5.74    5.86
10       10.74      10.53   10.96

       реальные значения (Виста)
           T9300(ноут) / T5450 (стационар)
TIME    ср.знач.    мин.      макс.
1    0.87/0.78   0.19/0.19   3.91/2.79
2    2.07/1.59   0.48/0.46   5.56/5.43
3    3.13/2.10   0.91/0.32   5.90/4.05
4    3.72/3.39   0.89/0.61   6.50/7.27
5    6.11/5.04   1.21/4.06   8.82/6.94
10   9.73/7.89   2.67/2.75  15.47/13.05

При этом под ХР результаты не прыгали, в отличие от Висты, но у Висты среднее время ближе к реальности.
Тестирование проводилось при помощи вставки 
Код

unsigned __int64 getCPUTicks() {
    _asm rdtsc
}

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

Так же тупо поставил, чтобы змейка крутилась на месте при Sleep и сравнивал с системным временем:
При Sleep(10) - на ХР время в игре отстает примерно на 3-5 секунд в минуту, на Висте - на 0-1.

В итоге что я сделал в программе
Код

    timeBeginPeriod(1);
    Sleep(10);
    timeEndPeriod(1);

и не стал заморачиваться ибо завтра надо сдавать курсовую.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)