Приветствую Вас, Гость! Регистрация RSS

Все для CS

Среда, 18.12.2024
Главная » Файлы » Остальное

Лаги в cs 1.6. Причины и способы их устранения.
02.06.2011, 00:01

Лаги в игре: причины и способы борьбы

Решился вот накатать статейку, потому что вижу довольно много тем в стиле "аааа! на серве все лагает! че делать!?", в которых даются советы без объяснения причин. В итоге проблема может быть и решается, но недопонимание о причинах все равно остается. После прочтения данной статьи оно должно исчезнуть

Вступление

Итак, лагом в общем случае можно назвать все внутри-компьютерные явления, которые мешают нормальной игре. Примеры: "слайд-шоу", зависание картинки, зависание игровых объектов. Но соседа с перфоратором к лагам отнести нельзя, хотя играть он мешает

Все причины лагов можно разделить на:

1) Проблемы на компьютере игрока - их в силах решить сам игрок;
2) Проблемы на канале связи между компьютером игрока и сервером;
3) Проблемы на сервере.

Ниже рассмотрим все это подробнее, но для начала список терминов, используемых в статье.

Список определений

ХЛ, Half-Life - в статье используется как название движка (но не игры про Гордона Фримена!). Данные из статьи применимы ко всем модам, созданным на этом движке, в том числе и для Counter-Strike.
Клиент - это программа (Half-Life), запущенная на компьютере игрока, которая обменивается данными с сервером и рисует картинку игрового мира.

хлдс, HLDS, Half-Life Dedicated Server - это программа такая, собственно серверная часть для Half-Life.

Сервер - Компьютер, на котором запускается хлдс
Квар, он же CVar, он же Console Variable - переменная, использующаяся в Half-Lfe, изменяющая какие-либо параметры игры. Может быть изменена пользователем из консоли (отсюда и название). Квары используются как на клиенте, так и в хлдс. Квары, влияющие только на серверную часть, имеют префикс sv_ (примеры - sv_gravity, sv_clienttrace); Квары, влияющие только на клиент имеют префикс cl_ (cl_lw, cl_lc, cl_updaterate).

Список кваров

Список кваров, назначение которых необходимо знать:

1) Клиентские:

cl_updaterate - количество пакетов в секунду, которое клиент хочет получать от сервера (именно хочет, но не факт что получит), 1/сек

cl_rate - исходящая полоса пропускание клиента (для данных от клиента к серву), байт/сек,
то есть максимальная скорость передачи данных к серверу

rate - входящая полоса пропускания клиента (для данных от сервера к клиенту), байт/сек, или максимальная скорость передачи данных к клиенту

net_graph - определяет тип отображения статистики по сетевому подключению. может принимать значения от 0 до 3 (об это позже)

2) Серверные:

sv_maxrate - максимальная скорость отдачи данных для одного клиента, байт/сек

sv_minrate - минимальная скорость отдачи данных для одного клиента, байт/сек

sv_maxupdaterate - максимальное количество пакетов в секунду, которое может быть передано одному клиенту.

sv_minupdaterate - минимальное количество пакетов в секунду, которое может быть передано одному клиенту.

sys_ticrate - определяет максимальное количество кадров, которые сервер может обсчитать за секунду. В хлдсе используется значение 1000/sys_ticrate (это в миллисекнудах) как интервал перерыва между обсчетом кадров.

Матчасть. Как хлдс контролирует поток данных к клиентам.

Отдача данных в хлдс контролируется отдельно для каждого клиента, на основе двух факторов:

1) количество пакетов в секнуду, передаваемых клиенту, назовем это значение updrate

2) максимальная скорость передачи к клиенту, назовем это значение cmrate.

I. Исходными данными для определения updrate служат три переменные - это клиентская cl_updaterate, и серверные sv_maxupdaterate и sv_minupdaterate. Алгоритм определения updrate можно записать так:

Code
updrate := cl_updaterate;
if updaterate > sv_maxupdaterate then updaterate = sv_maxupdaterate;
if updaterate < sv_minupdaterate then updaterate = sv_minupdaterate;


Видно, что по умолчанию updrate равен клиентскому значению. Однако оно не должно вылазить за пределы максимальных и минимальных значений, определенных в хлдс.

Вот несколько примеров для лучшего понимания:

cl_updaterate=30, sv_minupdaterate=20, sv_maxupdaterate=60. В Этом случае клиент будет получать от сервера 30 пакетов в секунду, т е что клиент хотел, то и получил.

cl_updaterate=100, sv_minupdaterate=20, sv_maxupdaterate=60. В Этом случае клиент будет получать от сервера 60 пакетов в секунду, тк значение уперлось в верхний порог.

cl_updaterate=10, sv_minupdaterate=20, sv_maxupdaterate=60. В Этом случае клиент будет получать от сервера 20 пакетов в секунду, тк значение уперлось в нижний порог.

II. Исходными данными для cmrate служат значения клиентской переменной rate и серверных sv_maxrate и sv_minrate. Алгоритм определения точно такой же, как и у updrate, то есть по умолчанию cmrate = rate, однако если значения вылазит за пределы sv_minrate или sv_maxrate, то оно ограничивается.

Матчасть. Как хлдс формирует пакеты. Что такое choke. (Упрощенный вариант)

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

Максимальный размер пакета, связанный с этим ограничением, может быть вычислен как cmrate/updrate, то есть максимальная скорость делится на количество пакетов в секунду. Но что будет, если данных сервер сгенерировал больше, чем может отправить?

Тогда все просто - в пакет записываются только данные, которые укладываются в максимальный лимит, остальные остаются ждать следующей пересылки.

Так же в пакет дописывается однобайтовое сообщение svc_choke, которое сигнализирует о том, что хлдс не смог послать все данные, которые сгенерировал. Да, эти данные придут к клиенту в следующем пакете, однако придут они уже с задержкой.

А если очередь данных на хлдсе разрастается и никогда не заканчивается, то на клиенте можно наблюдать нехилый такой рост пинга, и значение choke = 99 (его можно посмотреть в net_graph 3).

Отдельным пунктом стоит отметить то, что проверка на размер пакета осуществляется только если сервер работает в Internet режиме (sv_lan 0). При sv_lan 1 эта проверка отключается.

Это может быть причиной появления лагов при переводе хлдса на sv_lan 0 при ненастроенных sv_maxrate/sv_minrate.

Проводим диагностику.

Итак, чтобы избавиться от лагов, надо знать их причину. А причину нам поможет узнать очень хорошее встроенное в хл средство под названием net_graph, которе отображает в реальном времени информацию, связанную с передачей данных. Имеется 3 режима отображения, мы будем пользоваться первым (net_graph 1).

Для начала дадим описание того, что там вообще отображается:



1 строчка - фпс, интервал десинхронизации (грубо говоря - пинг), значение cl_updaterate

2 строчка - информация о данных от сервера: текущий размер пакета и средняя скорость приема

3 строчка - информация о данных к серверу: текущий размер пакета и средняя скорость отдачи

4 строчка - график данных от сервера. Каждая точка - входящий пакет, высота точек показывает задержку (пинг), чем выше точка, чем больше задержка.

Сами точки могут быть 3-х цветов: зеленые - нормальный пакет, пришел вовремя, нигде не задержался желтый - пакет с маркером choke, значит сервер не смог отправить все данные из-за политики рейтов; красный - пакет потерялся на просторах интернета ;).

Количество loss (потерянных паетов) и choke пакетов можно так же увидеть в цифрах режиме net_graph 3.

Значение, отображаемые там нужно понимать так - сколько пакетов из последних 100 было потеряно(loss) или переполнено(choke).

5 строчка - текущее значение cl_cmdratre

6 строчка - два графика (хотя трудно их там разглядеть)Обновляются они синхронно, каждый столбец соответствует одному кадру, который отрисовывает клиент.

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

В случае, если пакеты отправляются на сервер после отрисовки каждого кадра, графика вообще не видно.

Второй график - фиолтеовый в нижней части и красный в верхней - показывает уровень десинхронизации состояния клиента и сервера. Если присмотреться внимательно, то он представляет собой гребенку (типа вот так - //////).

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

Примеры, описания и решения

Ниже набор из 6-ти скриншотов + описание к ним



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

Решение: Найти и истребить объект, использующий ЦП, либо бежать в магазин за новым компутером.

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

Решение: Единого способа нет, т к причина может быть независящей от вас (может пьяный одмин за кабель запнулся). Что можно сделать - вырубить все, что использует сеть, особенно торренты и закачки. Можно попробовать собрать диагностику ping/traceroute и отправить в саппорт провайдера

3. А тут у нас фриз на компьютере клиента. Симптомы - внезапомное "замирание" игры на 200-300мсек, после чего нормальное продолжение. На нетграфе сопровождается подскоком зеленого графика "под потолок" (на скрине видно два фриза с небольшим интервалом), при этом на нижнем графике нет никаких отклонений.

Причины - в основном связаны с драйверами или железом. Фриз, который можно лицезреть на скрине был вызван "умным" поведением винчестера - после 5-6 секнуд неактивности он паркует блок головок, а при при попытке чтения чего-либо распарковывает их, при этом вся система ненадолго зависает.

Решения - попробовать поставить "рядом" чистую ОС и посмотреть, будут ли фризы на ней. Если будут - проблема с железом, ищем виновника последовательной заменой комплектующих. Если же полет нормальный - дело было в каком-то шибко умном драйвере. Так же может иметь конфликт железо-железо, либо железо-драйвер. В общем, единый путь решения найти трудно.

4. Самая часто встречающаяся сейчас проблема - choke, желтизна на графике, который должен быть зеленым wink Симптомы - рост пинга при большом количестве игроков, либо на картах, где видно одновременно много объектов, задержка стрельбы, может быть видно передвижение других игроков и объектов рывками.

Причина: Сервер генерирует больше данных, чем может передать.
Решение: Нужно увеличивать скорость, выделяемую клиенту. Ставим rate побольше (например 300000) и смотрим, что произойдет. Если желтизна исчезла - можете поздравить себя с решением проблемы Если нет - пытаемся достучаться админу сервера.

Если админом являйтесь вы, то тогда ставим в хлдсе sv_maxrate побольше (100000 например). Можно так же поднять и sv_minrate - это поможет игрокам с дефолтным конфигом (там вроде стоит rate 6000) избежать choke-ов и лагов.

5. Тут бы наблюдаем явную гребенку на нижнем графике - это означает что клинет получает данные через слишком большие интервалы времени. В игре может выражаться небольшим ростом пинга, небольшим подергиванием объектов, игроков.

Причины: низкий cl_updaterate или очень маленький sv_maxupdaterate на серверное стороне. Лечится увеличением значений этих переменных. Так же такое поведение может вызываться очень низким серверным ФПС (< 50).

Решается разгрузкой процессора на сервере, либо поднятием значения sys_ticrate (если он имеет малое значение, т е < 100). Можно еще поставить плагины для увеличения серверного фпс, только при перегруженном ЦП они не спасут.

6. Здесь можно лицезреть фриз на серверной стороне - был очень большой перерыв между обработками кадров на сервере. На нетграфе выражается подскоком на нижнего графике десинхронизации, при этом с доставкой пакетов проблем не было (верхний график в норме).

Причин несколько:

1) обычно связана с высокой загрузкой диска на сервере, когда хлдс пытается что-либо прочитать - происходит задержка.

2) может происходить из-за блокирующих запросов в перегруженную субд. Решение - переходим на неблокирующие (threaded) запросы, правда тут без переписывания кода плагинов не обойтись

3) низкий приоритет, данный хлдсу. Если на сервере нашелся процесс с намного более высоким приоритетом, чем хлдс, при этом он загрузил весь (все) ЦП, то хлдс отправляется курить на это время.

Источник: http://ya-cs.ru/stati/2184-lagi_v_igre_prichiny_i_sposoby_borby.html


Категория: Остальное | Добавил: eti
Просмотров: 2532 | Загрузок: 0 | Комментарии: 1 | Рейтинг: 5.0/2
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]