PDA

Просмотр полной версии : [Вопрос] PVar's



Ashmy
19.09.2017, 11:40
Здравствуйте. Есть смысл удалять все-все PVar'ы при дисконнекте игрока? Знаю что это необязательно, но не освободит ли это удаление память, которую сервер выделил под них ранее?
P.S да и вообще, какие советы можете дать относительно памяти?

ziggi
19.09.2017, 12:07
Смысла удалять их при дисконнекте нет, так как они автоматически удаляются.

DeimoS
19.09.2017, 12:12
Подробнее о принципах работы pVar (именно по части памяти) можно прочесть тут (http://pro-pawn.ru/showthread.php?14044).

Касаемо последнего вопроса: достаточно лишь просто выделять столько, сколько требуется для работы кода, и этого будет достаточно (подсчитывать нормально размер массивов). Но если ты жаждешь извращений и не самой рациональной траты времени, почитай об упакованных строках (http://pro-pawn.ru/showthread.php?13962-%D0%A3%D0%BF%D0%B0%D0%BA%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D1%8B%D0%B5-%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B8), например.

Hecf
19.09.2017, 16:27
Хочешь вопрос? :D

Привет

Вообщем на PVar я делаю всякую мини п*елку в виде работ и типа готовки еды в моде.
Возник вопрос например я создал 1 pvar с названием cooking и при определенном первом этапе действия системы ему присваивается значение 1, дальше на втором этапе этому же пвару присваивается значение 2, и на третьем этапе присваивают 3 значения ну типа


SetPVar(playerid, "cooking") 1) в начале готовки
SetPVar(playerid, "cooking") 2) когда еда готова
SetPVar(playerid, "cooking") 3) и когда берешь еду

Это как то влияет на нагрузку? Или если создал 1 пвар с одним названием и используешь её. Нагрузка приходиться именно на эту выделеную память или как там. Вообщем думаю ты понял суть вопроса

DeimoS
19.09.2017, 19:14
Хочешь вопрос? :D

Привет

Вообщем на PVar я делаю всякую мини п*елку в виде работ и типа готовки еды в моде.
Возник вопрос например я создал 1 pvar с названием cooking и при определенном первом этапе действия системы ему присваивается значение 1, дальше на втором этапе этому же пвару присваивается значение 2, и на третьем этапе присваивают 3 значения ну типа


SetPVar(playerid, "cooking") 1) в начале готовки
SetPVar(playerid, "cooking") 2) когда еда готова
SetPVar(playerid, "cooking") 3) и когда берешь еду

Это как то влияет на нагрузку? Или если создал 1 пвар с одним названием и используешь её. Нагрузка приходиться именно на эту выделеную память или как там. Вообщем думаю ты понял суть вопроса

Ты просто меняешь значение конкретного pVar, а не создаёшь новые

Ashmy
23.09.2017, 16:32
Зачем тогда вообще использовать PVar'ы? Если под один PV'ar выделяется 58 байт и при этом сразу же при коннекте игрока? Т.е если мне надо запомнить какое-то значение временно, к примеру из перехода игрока из одного диалога в другой, то какой смысл мне использовать PV'ar, если я могу записать это значение в обычную переменную (я рассматриваю только int и float) и "потратить" всего 4 байта? Получается, что профит мы получим только в случае если сервер будет пустовать? У нас есть 1000 слотов, если мы будем использовать обычную переменную, мы выделим 4000 байт под нужную нам переменную игроков, в случае с PV'ar мы выделим 0, но если на сервер зайдут 100 человек, тогда будет выделено 5800 байт? Не понимаю, разъясните, пожалуйста

Betta
23.09.2017, 16:39
В давние времена, когда SAMP был еще "маленький", он был рассчитан на 100 игроков, но прошло время, и SAMP вырос, и уже 500 игроков могли играть одновременно, а потом и 1000.
Еще в SAMP'e была и есть константа MAX_PLAYERS, обозначающая - максимальное количество игроков, сначала она была равна 100, потом 500, и наконец 1000.
Многие "скриптеры", создавали и создают массивы с использованием MAX_PLAYERS, лишь для хранения одиночных флагов (1, 0 и т.п.), когда MAX_PLAYERS была равна 100, это еще было терпимо, но сейчас, подобное использование массивов слишком затратно в плане потребления памяти.

Как нам известно, 1 ячейка массива занимает 4 байта, рассчитаем потребление памяти на один массив:

MAX_PLAYERS при:
100 * 4 занимало памяти 400 байт;
500 * 4 занимало памяти 2000 байт;
1000 * 4 занимает памяти 4000 байт;

А если на сервере играют, к примеру 100 человек, то остальные 900 ячеек массива, возможно, никогда не будут использованы, а это, не задействованные 3600 байт.

В связи с этим, была создана Per-player variable system (сокращенно PVar), система персональных переменых, имеет ряд преимуществ, по сравнению со стандартными переменными:

Доступность из всех загруженных модов и фильтр скриптов, позволяет упростить модуляризацию кода.
Автоматическое удаление PVar'ов, когда игрок выходит с сервера, что позволяет не сбрасывать вручную переменные для следующего подключившегося игрока.
PVar'ы экономят память, не расходуя ее на элементы на не подключенных игроков.
Если даже PVar не был создан, при запросе он по-прежнему будет возвращать значение по умолчанию 0.
PVar'ы могут хранить очень большие строки используя динамически выделяемую память.


К недостаткам, возможно, можно отнести скорость работы, но я считаю, что это не очень критично.

Полное описание PVar можно прочесть тут https://wiki.sa-mp.com/wiki/Per-player_variable_system

Инфо.

DeimoS
23.09.2017, 16:59
Зачем тогда вообще использовать PVar'ы? Если под один PV'ar выделяется 58 байт и при этом сразу же при коннекте игрока? Т.е если мне надо запомнить какое-то значение временно, к примеру из перехода игрока из одного диалога в другой, то какой смысл мне использовать PV'ar, если я могу записать это значение в обычную переменную (я рассматриваю только int и float) и "потратить" всего 4 байта? Получается, что профит мы получим только в случае если сервер будет пустовать? У нас есть 1000 слотов, если мы будем использовать обычную переменную, мы выделим 4000 байт под нужную нам переменную игроков, в случае с PV'ar мы выделим 0, но если на сервер зайдут 100 человек, тогда будет выделено 5800 байт? Не понимаю, разъясните, пожалуйста

Потому что эти 58*800 байт выделяются в любом случае: используешь ты pVar или нет.
Ты ещё начни использовать глобальный string вместо локального, ведь зачем выделять память в стэке (хотя она там выделена ещё при старте сервера и все твои "new" просто резервируют определённые участки памяти под свои нужды, а не выделяют новую память), когда можно создать глобальную переменную и делать всё то же самое, что и делает стэк, только в ручном режиме! :agree:

Hecf
24.09.2017, 03:21
Потому что эти 58*800 байт выделяются в любом случае: используешь ты pVar или нет.
Ты ещё начни использовать глобальный string вместо локального, ведь зачем выделять память в стэке (хотя она там выделена ещё при старте сервера и все твои "new" просто резервируют определённые участки памяти под свои нужды, а не выделяют новую память), когда можно создать глобальную переменную и делать всё то же самое, что и делает стэк, только в ручном режиме! :agree:


Я НЕ шарю, но можешь объяснить, как память заранее выделена ещё при старте и ты говоришь резервируются ну типа занимают места в уже существущих ячейках. Как она создается изначально вот это выделенная память. Что его создает при включении мода?

DeimoS
24.09.2017, 03:54
Я НЕ шарю, но можешь объяснить, как память заранее выделена ещё при старте и ты говоришь резервируются ну типа занимают места в уже существущих ячейках. Как она создается изначально вот это выделенная память. Что его создает при включении мода?

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

#pragma dynamic количество
Собственно, эта память нужна для хранения временных данных (информации о обрабатываемом коллбэке и т.п.), а так же её можно использовать путём создания локальных переменных.

У меня уже давно есть в планах написать урок, где объяснить подобные элементарные и важные вещи максимально доступно, но пока всё руки не доходят.

Ashmy
24.09.2017, 16:07
Потому что эти 58*800 байт выделяются в любом случае: используешь ты pVar или нет.
Ты ещё начни использовать глобальный string вместо локального, ведь зачем выделять память в стэке (хотя она там выделена ещё при старте сервера и все твои "new" просто резервируют определённые участки памяти под свои нужды, а не выделяют новую память), когда можно создать глобальную переменную и делать всё то же самое, что и делает стэк, только в ручном режиме! :agree:
Не подумал про то что память выделяется под PVar'ы сразу. Это всё объясняет). Получается, что DeletePVar стоит использовать разве что для обнуления значения PV'ar'а и всё? Больше никакой пользы, раз память не освобождается

DeimoS
24.09.2017, 16:30
Не подумал про то что память выделяется под PVar'ы сразу. Это всё объясняет). Получается, что DeletePVar стоит использовать разве что для обнуления значения PV'ar'а и всё? Больше никакой пользы, раз память не освобождается

Нет, не получается :)
Удаление нужно не для того, чтоб освобождать память (хотя для чего ты вообще собрался её освобождать, если количество занимаемой модом памяти известно уже на этапе компиляции и никак не изменится при работе сервера?), а для того, чтоб освободить память (слот) для нового pVar. Ведь, как ранее говорилось, у pVar есть свои лимиты и если эти pVar вовремя не удалять, можно легко лимиты превысить.
Да и чем больше создано pVar, тем дольше будет обращение к pVar с последним ID, что хоть и не существенно, но должно тебя волновать, если ты хочешь написать хороший мод, который использует ресурсы по назначению, а не разбрасывается ими.

Ashmy
24.09.2017, 16:54
Нет, не получается :)
Удаление нужно не для того, чтоб освобождать память (хотя для чего ты вообще собрался её освобождать, если количество занимаемой модом памяти известно уже на этапе компиляции и никак не изменится при работе сервера?), а для того, чтоб освободить память (слот) для нового pVar. Ведь, как ранее говорилось, у pVar есть свои лимиты и если эти pVar вовремя не удалять, можно легко лимиты превысить.
Да и чем больше создано pVar, тем дольше будет обращение к pVar с последним ID, что хоть и не существенно, но должно тебя волновать, если ты хочешь написать хороший мод, который использует ресурсы по назначению, а не разбрасывается ими.
Всё понял. Благодарю. Сразу же вопрос хочу здесь задать по поводу динамических арен/сфер стримера, они сильно превосходят по скорости классический вариант с перебором координат по типу цикл + IsPlayerInRangeOfPoint? Если сделать 1 проверку в OnPlayerEnterDynamicArea, стример будет ~20 раз (по-моему каждые 50 мс по дефолту) проверять вошёл ли игрок в зону, верно? С другой стороны, если сделать цикл с перебором координат на какую-нибудь кнопку с откатом в 1-2 секунды...? Я слышал что-то типа: "если ставишь себе стример - используй его по максимуму", - насколько верны эти слова?

DeimoS
24.09.2017, 17:44
Всё понял. Благодарю. Сразу же вопрос хочу здесь задать по поводу динамических арен/сфер стримера, они сильно превосходят по скорости классический вариант с перебором координат по типу цикл + IsPlayerInRangeOfPoint? Если сделать 1 проверку в OnPlayerEnterDynamicArea, стример будет ~20 раз (по-моему каждые 50 мс по дефолту) проверять вошёл ли игрок в зону, верно? С другой стороны, если сделать цикл с перебором координат на какую-нибудь кнопку с откатом в 1-2 секунды...? Я слышал что-то типа: "если ставишь себе стример - используй его по максимуму", - насколько верны эти слова?

Всё зависит от ситуации. Преимущество стримера в том, что он все сверки координат делает на своей стороне, в отдельном потоке. Но из этого вытекает минус в виде "неточности" из-за того, что когда стример находит игрока внутри динамической зоны, он отсылает информацию об этом серверу и сервер не сразу обрабатывает её, а ставит в общую очередь. Соответственно, если пакет пришёл в момент начала выполнения какого-нибудь трудоёмкого коллбэка, OnPlayerEnterDynamicArea не сработает, пока этот коллбэк не обработается.
То бишь, нагрузки на поток, в котором обрабатывается мод, будет меньше, но и точность упадёт

Daniel_Cortez
24.09.2017, 17:44
Имейте в виду, что темы с вопросами здесь архивируются, чтобы не отвечать заново на одни и те же вопросы для каждого такого же пользователя, как вы. Например, если кто-то ещё задаст вопрос про экономию памяти за счёт PVa'ов, ему дадут ссылку на эту тему. Или этот кто-то сам найдёт ответ, отыскав тему по названию (через поиск по форуму).

Если же у вас возник новый вопрос, никак не относящийся к предыдущему, создайте новую тему - иначе ответ на новый вопрос по названию темы найти не получится. Не захламляйте форум бессвязными вопросами в одной теме.

Закрыто.