adic3x
offline
Опыт:
108,439Активность: |
[Info] Плюсы и минусы кэша
сразу скажу, что неЖассерам все ниженаписанное может быть интересно только как набор букф, посему... =)
вступ.вобщем то этот вопрос рассматривался тут: http://xgm.guru/forum/showthread.php?t=7630 так же в природе существует мой перевод ридми vJass, где косвенно затрагивается этот вопрос: http://xgm.guru/forum/showthread.php?t=13118 еще в природе существует описания паралельных массивов от wampir'а, но по некоторым причинам его мы преднамеренно проигнорируем ;) кешь - злорезонный вопрос - пчму? 0) для индексации используются строки, хотя никакой прямой необходимости впринципе в этом нет. стоит отметить, что строки в варе неудаляються, хотя это и не самое важное в нашем случае. впринципе я не знаю как именно работает используемая хеш фция, но тем не менее это не так важно, т.к. такими небольшими утечками можно было бы пренебрегнуть, если бы не... 1) в кешь можно сторить только bool, int, real и string. меня спросят а как же H2I? и будут ой как неправы... начнем с того, что все handle и наследники в варе являются ссылками (а вообще ссылками являются так же string). т.е. вызываю функцию как call DoSomethihg(u) мы передаем в качестве аргумента именно ссылку на юнита, помещенного в данную переменную. теперь, при set uUnit=CreateUnit(... мы в переменную типа указатель на юнита записываем указатель на конкретного юнита. set iInt=H2I(CreateUnit(... поместит в переменную цифровое значение ссылки, если можно так сказать. Пока вроде неясно, но сейчас поясню... если hOne==hTwo то это значит, что обе эти переменные являетсю ссылками на один и тот же обьект. BUT! xD рассмотрим пример: Код:
напомню, что хендл обьекта освобождаеться (т.е. может быть создан новый обьект с таким же хендлом) в том случае, когда обьект выходит из области видимости (т.е. не находить не в одной переменной) правда это имеет отношение не ко всем типам (исключение texttag к примеру) BUT! мы отошли от темы=/ исполните код, и вы увидите, что вроде как обе переменные должны ссылаться на разные обьекты, BUT! реально же они будут ссылаться на один и тот же обьект! т.е. если мы уверены, что тот обьект, ссылку на которого мы сторим (от англ store - запомнить/записать) в кешь не будет удален где либо еще (его область видимости ограничина) мы говоря образно можем спать спокойно. а если мы сторим обьект, удаление которого мы не контролируем? к примеру юнит может быть удален движком? в этой статье есть решение уважаемого Sergey'а, но оно настолько очевидно лузерское, что надеюсь его в серьез рассматривать никто небудет. вобщем проблема думаю ясна ;) 2) и есть проблема, вытикающая из п.2. а именно то, что если мы сторим какое либо значение на хендл обьекта, удаление которого мы так же не контролируем, мы можем получить... ммм, ничего хорошого грубо говоря) Код:
вот скажем сторим мы на нашего юнита какое либо значение... а юнит возми и ремувнись=) что теперь? либо утечка, либо будет создан новый юнит, на хендл которого будет повешено значение, вобщем он унаследует кроме хендла еще и аттач на его значение, что тоже не есть гуд, думаю это ясно... борьба со зломбыло бы очень мило с моей стороны предложить варианты решения вышеописанных проблем ;) что я и хочу сделать... начну с паралельных массивом. это массивы одной длины (в жассе все массивы одной длины), обращение к которым происходит по одному индексу. если вы разбирались в vJass'е - то структуры там работают по принципу паралельных массивов. т.е. есть алгоритм ФриСлота (ммм, как я его прозвал ^^) - вот он: Код:
говоря образно aGet() вернет нам свободжный слот, а aRemove(int i) сделает слот i свободным. именно этот int и будет использоваться как индекс к паралельным массивам u_a; r_a_x; r_a_y. зачем нам это надо? к примеру спел, должен переместить юнита в точку с опред. координатами через некоторое время. какова бы была его реализачия черешь кешь? сторим на кешь юнита, которого надо переместить, а также координаты на созданый таймер, и по истечению таймера мувим юнита. BUT! в нашем случае мы сторим только индекс к массивам, а в массивы сторим все наши параметры! т.е. если вы знакомы с ооп то может смотреть с той точки зрения, что мы создаем некоторый класс спела, члены (паралельные массивы) которого и будут описывать его свойства (к примеру свойства спела телепорт рассмотренного выше - кого и куда переместить) все! теперь мы уже не рискуем, что обьект будет удален (а он и не будет удален, точнее новый обьект с таким же хендлом создан не будет!) мало того, это будет работать быстрее да и писать такой код куда легче (тот кто скажет что сторить много значений в кешь легче чем в массив будет послан в сторону австралии) отлично! теперь вопрос относительно того, на кого и как сторить. в случае если предусмотренна у типа обьекта userData (unit; item) то именно в нее мы и будет сторить тот индекс, который и будет давать доступ к массивам, правда тут есть одно но, мы конечно уже застрахованы от бага, когда вместе с хендлом новый обьект унаследует что то еще, но осталась утечка. мы с Tc впринципе нашли решения этой проблемы, за счет цикличексой проверки, впринципе я постараюсь ее скоро реализовать ;) с остальными же обьектами, на которые нужно что то аттачить можно быть спокойным - таймеры и тригеры сами по себе не исчезают, и програмист может вполне контролировать их, а с юнитами как быть я вроде написал выше=) мы можем спокойно сторить как и в кешь наш индекс, либо можем использовать свои сисмы (XAT as example), тут уже на любителя... заключ.вот вроде, писал, сам вроде достаточно четко понимая о чем, если кто чего не понял, спросите, нестесняйтесь=) кста если кто с чем несогласен или имеет свои решения относительно темы, говорите тоже, обсудим=) Отредактировано ADOLF, 13.02.2008 в 17:40. |
13.02.2008, 17:18 | #1
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
exploder
iOS zealot
offline
Опыт:
19,394Активность: |
Цитата:
А как происходит проверка на существующий или уже ремувнутый юнит ссылается переменая? Проверкой типа юнита? |
|
13.02.2008, 18:35 | #2
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
df Hunter
Нападатель
offline
Опыт:
5,749Активность: |
ну про то как проверить количество ссылок кидал свои идеи |
13.02.2008, 18:41 | #3
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
exploder
iOS zealot
offline
Опыт:
19,394Активность: |
Цитата:
Смысл вашего поста уважаемый разъясните? Хотя бы ссылку привел куда кидал... а то пост ниочом... |
|
13.02.2008, 18:46 | #4
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
df Hunter
Нападатель
offline
Опыт:
5,749Активность: |
Цитата:
я про то, что возможно проверить количество ссылок, которые ссылаются на обьект, собственно при 0 ссылок получить обьект невозможно, при 1 ссылке всё гуд, при больше чем одной ссылке утечки, на которые впринципе все забивают кидал в аську df Hunter добавил: З.Ы. кэш не зло ))) |
|
13.02.2008, 18:55 | #5
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
exploder
iOS zealot
offline
Опыт:
19,394Активность: |
Цитата:
Кстати все время в в такого рода багах повинен бедный кеш, хотя сам он по себе не багнутый (если закрыть глаза на баг с лимитом в 256 кешей, который собсна здесь и оффтоп), и Адольф сам же и описывает, что некорректные ссылки появляются в следствии работы механизма рецикла хендлов... |
|
13.02.2008, 19:04 | #6
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
ZeToX2007
offline
Опыт:
7,009Активность: |
Ну незнаююю незнаю... Скажем теоретически, если у меня в карте содержиться около ста тригеррах(99) с локалками(И не по одной в каджой), то можно весело наблюдать как из плавного и красивого движение юнитов и движение камерой постепенно переходит в СЛАЙД ШОУ. И алгоритм ФриСлота ( ЫЫ=) )) Дейсвительно может помочь даному несчастному случаю ? ну незнаю, попробую "ФриСлота" юзать) |
13.02.2008, 19:21 | #7
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
exploder
iOS zealot
offline
Опыт:
19,394Активность: |
ZeToX2007, прочитай статью про оптимизацию, даная статья вообще не об этом.
Отредактировано exploder, 13.02.2008 в 19:46. |
13.02.2008, 19:40 | #8
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Toadcop
offline
Опыт:
54,313Активность: |
Цитата:
юзеры зло =) такс время пинать *PREVED* xD коментить не буду. но этот код с таймерами ты НА ПРАКТИКЕ тестировал ? =) фичя вся заключаетьса точ ресайкл хендлов происходит на евентах. окончание очереди выполнения джасс потока. т.е. очереди даже. ну тот же слирекшен вызывает это. (а возможно что то и еще круче) что здесь написано пишетьса в несока предложений а точней. 1) некогда не удаляйте триггер в самом себе. // call DestroyTrigger(GetTriggeringTrigger()) // или как там ? 2) ОЧЕНЬ ЖЕЛАТЕЛЬНО не используйте TriggerSleepAction() и всё наследованы конструкции. т.к. это по настоящему сложная функции которая нисёт много ролей (включтельно синхронизации) впринципе всё. да и еще я лично использую арреи из за того что они быстрей + удобней а не из за того что кеш зло. кеш это лутчый способ хеширования строк варе. не считая s2i xD но т.к. таблица ребилдитьса так что это не совсем тру НО если у вас не планируетьса использование сохранение игры то самое то =) напр взять зделать бинарное древцо на 32К записей и Modulo(s2i("myfucking string xD"),32K) ну можно больше но там потом смысл теряетьса =) да и еще Цитата:
елементы массива выдиляетьса "уровнево" по уровню потребности (ака макс нужны слот иммено по значению а не по заполненым ячейкам) т.е. поэтому скока бы ты не имелл сначало массивов они будут требовать оч мало памяти. а потом во время игры разширятьса что приводит к лаганцам ;D ну короче это уже другая история =) дык ну что 100% кеш НЕЗЛО =) да и про ссылки и остальную биду как то не так написано =) фичя в том что всё достаточно нубо устойчево сделано. ДА локалки надо обнулять но потерь как таковых не происходит. т.е. я уверен что косяки во время работы происходят из за удаления рабочего триггера. и почти всё конечно наверно есть иные случие но они особо не известны. а да =) самое медленое в кеше это клеиние строк =) (ну ясно что если строка не статичная.) а да снова =) причём вампир то ? -_- он хрен знает когда об них писал (ака поздно). но да это впринципе старо как програмирование =) кстати я сам сначало придумал юзать паррарельные арреи а потом узнал что такое ООЕ програмирование =) и все эти функции для алокации тож сам "придумал" помню когда еще достаточно отделеный от нета был и девелопил ТРС... пришла такая идея в голову =) Toadcop добавил: блин апасный пост получилса =) |
||
14.02.2008, 02:40 | #9
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
adic3x
offline
Опыт:
108,439Активность: |
начну коментить с поста Тс ибо самое сложное)))
Цитата:
+1 Цитата:
наверное) ну т.е. как я понял в одной фции оно не выделит такой же хендл, ну опять тут смысл в том что если хранить не сами ссылки на обьетов, а их H2I (как зачастую и постопают) и неконтролировать их удаление то и могут быть такие косяки хотя конечно шансов мало, но...) Цитата:
я это видел в коде доты xD Цитата:
это тоже ясен пень, но впринципе если бы я запускал фции таймером (в моем примере) 99% эффект был таким же) ну т.е. я вообще как немного не об этом писал) Цитата:
смысл в том что они грубо говоря одной длины для юзера т.е. он может обращать к любому слоту в всех массивах от и до... ну наверное я немного таки дал маху, надо было назвать "кешь - зло если руки из пожи" но если они из пожы то тогда зло все и вся lol=) ну т.е. возможные ошибки при работе с кешем) Цитата:
ммм, ну вообще по логике тогда и воходить что арреи относительно кеша добро, а кешь относительно арреев зло xD ну а реально все зависит от рук) да и что я нетак про ссылки написал ?) вот, вроде от самого страшного отбился))) Цитата:
ну собтвенно я же вроде предлагаю механизм решения проблемы...=) ZeToX2007, первый пост внимательно читал?) помойму тема необэтом впринципе... |
|||||||
14.02.2008, 10:37 | #10
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
exploder
iOS zealot
offline
Опыт:
19,394Активность: |
Цитата:
Ну никтож не спорит) Просто название "Кэш - Зло" здесь почти как "Система пятиэтажных зданий" ^_^ |
|
14.02.2008, 10:43 | #11
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Toadcop
offline
Опыт:
54,313Активность: |
Цитата:
ну про я же писал (теперь внимательно просмотрел код с таймерами) написал логичискую операцию ТТ некаких багов там нету. вообщем лол мне надо верить своему чуству которое сразу подсказывает мне что *палево*. =) ака дети не пугайтесь в том примере всё как должно быть =) на крайняк произойдёт косяк и в нём будет виноват тока юзер хотя я сомневаюсь что он произойдёт как таковой. Цитата:
Цитата:
Цитата:
есть тока 1 иссуе. это нескока копий одного и того же хендла. но фичя в том 1) просто чрез многих юнитов ты будеш ссылатьса на 1го. (через них) 2) самое интересное то что вар3 в курсе этого =) и при срабатывания триггера он пытаетьса фиксить это !!! (это факт) т.е. если есть подвоеные объект он подвойному объекты выделяет новый хендл до тех пор пока у всех не будут разны хендлы. фичя в том что это чисто джасс фичя (связана с ним) а не интернал стафф самой игры т.к. напр эти юниты будут существовать в норм форме тока джасс операции будут косячить. т.е. если тупо закастить простой спелл на такого юнита то всё будет ок. (т.е. он получит напр урон и всё) ааа во вспомнил =) что хотел написать Цитата:
лутче бы тему про косяки написал бы =( Цитата:
Цитата:
|
|||||||
14.02.2008, 11:22 | #12
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
adic3x
offline
Опыт:
108,439Активность: |
вот, извоял наглядную карту пример, демонстрирующую стак хендлов, короче приносим тюленя в жертву сотоне, и пишем "-а" что бы узнать хендл вновь созданного юнита... заметите, когда от ластоногого неостанеться и рожек с ножками будет стак)
» code function Test takes nothing returns nothing local unit u=CreateUnit(Player(0x00), 0x6e736561, 0., 0., 0.) call BJDebugMsg(I2S(H2I(u))+" "+I2S(iu)) call RemoveUnit(u) set u=null endfunction function Init takes nothing returns nothing local trigger t=CreateTrigger() call TriggerRegisterPlayerChatEvent(t, Player(0x00), "-a", true) call TriggerAddAction(t, function Test) set iu=H2I(CreateUnit(Player(0x00), 0x6e736561, 0., 0., 0.)) call BJDebugMsg(I2S(iu)) endfunction ADOLF добавил: Цитата:
я и неписал что там баги, т.е. там косяк допущеный самим кодером) Цитата:
хм? поподробней плз) вообще как ни странно все действительно зависит от рук, но основная трабла, собственно о чем я и писал в первом посте в том, что просто надо контролировать хендлы (ну или как сказать) короче не удалять чего не надо или не сторить на то что может быть удалено) |
||
14.02.2008, 11:29 | #13
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Toadcop
offline
Опыт:
54,313Активность: |
ADOLF лолед... по кругу одно и тоже =) то что ты приводиш в пример называетьса ресайклинг хендлов ака "это так должно быть" для этого и обнуляютьса локалки... ТТ
я же говорю у мну внутриние чуство (интуицыя) на эти вещи не плохая мне стоит взгленить на всю картину нескока секунд я в курсе дела а точней или всё ок или есть какойнить корявый косяк. (с точки зрения неправильности) а что подробней ? подробней я уже даже написал. любой объект из диапазона 0x100000 использует один и тот же стек свободных хендлов. т.е. ему присваиваетьса от туда хендл "джассовый". существует фактический трюк =) забивать в этот стек (который хардкодед) напр один и тотж хендл n раз =) и потом H2I будет УЖАСТНО СОСО =) ХОТЯ и переменые тоже будут сосо =) но фичя в пременх что они вроде "авто правятьса" хотя я на 100% неуверен. а H2I сбе статично будет весеть. это и есть проблма о который ты ДОЛЖЕН был писать. а не о какой то детской аниме саге с тру метолским примесем =). как это делаетьса ? объясну на словах (тексте xD) есть любой триг.... есть там хендл (а возможно и не надо) корчое так сработал тригг function triggaction .... local unit u=null call DestroyTrigger(GetTriggeringTrigger()) call TriggerSleepAction(0) call TriggerSleepAction(0) call TriggerSleepAction(0) call TriggerSleepAction(0) call TriggerSleepAction(0) ... n call TriggerSleepAction(0) // n-2 вроде == скока раз будет один и тот же хендл помещён в стек свободных хендлов. ... set u=CreateUnit(...) call echo(I2S(h2i(u))) set u=CreateUnit(...) call echo(I2S(h2i(u))) set u=CreateUnit(...) call echo(I2S(h2i(u))) set u=CreateUnit(...) call echo(I2S(h2i(u))) // О ЧУДО ! =) у них будут одинаковые хендлы но по факты через всех этих юнитов вы будете оращатьса к ихнему "мастеру" :pray: =) (как точно определяетьса мастер я на 100% не понял но вроде первый юнит с этим хендлом) endfunction короче вот такой прикольный косячок =) хотя очень таки интересный можно поекспереминтировать с ним (я это делал но конечно не супер долго ибо это просто баг) если вы не понял то прочтите это еще и еще раз =) |
14.02.2008, 11:50 | #14
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
exploder
iOS zealot
offline
Опыт:
19,394Активность: |
Цитата:
call KillUnit(u) будет убивать нужного юнита или "мастера"? Баг в H2I, или с самой ссылке? |
|
14.02.2008, 12:22 | #15
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Toadcop
offline
Опыт:
54,313Активность: |
"мастера" я же написал типо другие юнитами буду просто носить ссылку на другого =)
Цитата:
да и еще раз во время того когда эти юниты "триггерят" напр он вошол в регион или т.п. (общий евент) то если вар3 "видит" что есть одинаковые хендлы он начинает их править =) т.е. напр один момент хендл был одним а в другой иной =) |
|
14.02.2008, 12:39 | #16
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
adic3x
offline
Опыт:
108,439Активность: |
=) ну так я писал насчет ресайкинга хендлов, и что нуно быть осторожным при сторе в кешь... короче проехали=)))
ща пойду тестить твой код) ADOLF добавил: все проверил, насколько я понял, просто абуз алгоритма выделения хендла... т.е. если не не стараться абузить специально то дб все норм) и кста h2i тут непричем т.к. оно даже разных юнитов может считать за одного... |
14.02.2008, 13:15 | #17
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Axe_Man
offline
Опыт:
170Активность: |
Не понял суть темы, но помойму вы отстаивайте одну точку зрение тока с своей сторони. Хватит флудить. Всем известно что кеш ето хорошо но newgenpack лучше... |
14.02.2008, 13:24 | #18
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Toadcop
offline
Опыт:
54,313Активность: |
ага вроде короче после созданый объект с этим хендлом и есть мастер.
а те юниты как бы "потеряные" хоть как уже писал сам вар с ними норм работает. Код:
вот вроде рабочий триг =) |
14.02.2008, 13:42 | #19
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
exploder
iOS zealot
offline
Опыт:
19,394Активность: |
Прото близзы очевидно сделали лимит на размер стека хендлов и для юнитов, на которых можно воздействовать из джасса, так же как и для уберсплатов, текстагов и т.д. Когда юнит возбуждает какое-нибудь джасс событие, движку приходится таки выдать корректный хендл, чтобы можно было обработать этого юнита из джасса. |
14.02.2008, 14:18 | #20
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|