XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Warcraft> Академия: форум для вопросов> Jass
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

Ответ
 
nic666

offline
Опыт: 5,612
Активность:
[Info] Cache vs udg_Array - сравнение производительности
Очень хотелось лично убедиться в том, что кеш значительно медленее переменных...
Однако все оказалось весьма запутанным.

1. Проблема замера времени - штатными средствами timers, wait , periodic triggers и т.п.
По моему мнению НЕРАЗРЕШИМА.

---------Поясняю:
Нетрудно заметить, что при выполнении длиных тригеров (или периодических триггеров) начинает тормозить графическая составляющая. Это происходит так как движек распределяет динамически процессорное время между тригерами и GUI составляющей. Распространяется ли это на timers, wait , periodic triggers?

Тесты показали: распространяется! Если движек занят выполнением триггера или обработкой очереди, то все временные события откладываются до освобождения триггера.
То есть одно из двух: 1) триггер из очереди выполнился полностью 2) триггер не выполнился за отведенное ему "время жизни" и прерывается движком, т.е его сочли "зависшим" и удалили. То же относится к триггерам запущенным через ExecuteTrigger, за исключением того, что они выполняются в другом потоке и т.м. между тригерами основного потока и ExecuteTrigger тоже время как то динамически распределяется.

Заметьте, триггер существует "время жизни", после этого прерывается как "зависший".
В прилагаемом тесте используется именно эта особенность.


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

2. Расчет хэш функции выполняется асинхронно! Т.е.
При вызове call StoreInteger() происходит занесение данных в некую структуру, а некий поток постоянно сканирует эту структуры и выполняет необходимые операции.

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

в common.j имеются специальные функции для обеспечения немедленного хешированя кеша:
Код:
native SyncStoredInteger        takes gamecache cache, string missionKey, string key returns nothing
native SyncStoredReal           takes gamecache cache, string missionKey, string key returns nothing
native SyncStoredBoolean        takes gamecache cache, string missionKey, string key returns nothing
native SyncStoredUnit           takes gamecache cache, string missionKey, string key returns nothing
native SyncStoredString         takes gamecache cache, string missionKey, string key returns nothing


Таким образом реальная запись в кеш обеспечивается двумя операциями
call StoreInteger(...)
call SyncStoredInteger(...)

3. Кеширование кеша как это ни странно звучит!
Все значения помещенные в кеш продолжают храниться где-то в специальной области, назовем ее "актуальной областью кеша".
Выталкивание значений производится специальным набором функций:
Код:
native  FlushGameCache          takes gamecache cache returns nothing
native  FlushStoredMission      takes gamecache cache, string missionKey returns nothing
native  FlushStoredInteger      takes gamecache cache, string missionKey, string key returns nothing
native  FlushStoredReal         takes gamecache cache, string missionKey, string key returns nothing
native  FlushStoredBoolean      takes gamecache cache, string missionKey, string key returns nothing
native  FlushStoredUnit         takes gamecache cache, string missionKey, string key returns nothing
native  FlushStoredString       takes gamecache cache, string missionKey, string key returns nothing


таким образом: call FlushGameCache() выталкивает все значения в "пассивную область кеша".
При реальном исполнении кода, некие функции подсчитывают число обращений к элементам кеша и наиболее часто используемые помещаются в "активную область", а менее используемые в "пассивную облать кеша".

Очевидно перед записью кеша происходит Sync всех объектов и Flush всех объектов.
Таким образом работа с кешем может означать выполнение трех функций, а не двух:

call StoreInteger(...)
call SyncStoredInteger(...)
call FlushStoredInteger(...)

=================================================

Далее прикладываю тест и ниже выложу свои результаты... как с одной функцией call StoreInteger(...) так и с тремя.
Как ни странно на компах разной мощности результаты получаются одинаковыми, я тестировал на P4 3 Ghz и P4 2.4Ghz
Прикрепленные файлы
Тип файла: w3x CacheTest.w3x (26.9 Кбайт, 42 просмотров )

Отредактировано ShadoW DaemoN, 07.08.2008 в 00:20.
Старый 15.01.2007, 14:28
0pJl9lTa

offline
Опыт: 3,397
Активность:
Кеш медленнее, доказано хз кеми
Старый 15.01.2007, 14:45
DioD

offline
Опыт: 45,134
Активность:
мною доказано, минимум в 3раза медленее, тестировал подвешиванием потока, хотя надо было вочтаймером
Старый 15.01.2007, 14:50
nic666

offline
Опыт: 5,612
Активность:
Результаты,
во всех случаях глобальный массив работает быстрее, поэтому его время работы считаем 100%.

==========================
1. Для трех функций, результаты:
По записи
кеш 16% скорости от массива
по чтению
кеш 19% скорости от массива

p.s. в реальной ситуации функции Flush выполняются очень редко...
==========================
2. Для двух функций
По записи
кеш 19% скорости от массива
по чтению
кеш 16% скорости от массива

p.s. в реальной ситуации так должно работать часто, но Sync выполняется асинхронно и не тормозит самого триггера
странность результатов видимо результат особеннойтей реализации перемещений значений из одной области в другую, хотя скорее речь должна идти о некоей индексации... а может быть "все не так просто"...
==========================
3. Для одной функции
По записи
кеш 42% скорости от массива
по чтению
кеш 16% скорости от массива

P.S. Эта ситуация наиболее распространена в ресльности.
==========================
4. Для одной функции через BJ функции
По записи
кеш 13% скорости от массива
по чтению
кеш 5% скорости от массива

P.S. Anti-BJ оптимизация это вам не шутка! Хотя всего лишь одна вложенная функция...

===========================
Замечание.

фрагмент кода
Код:
set I = I+1
      if (I == 8192) then
        set I=0
      endif
    endloop


работает примерно на 30% медленее, чем
Код:
set I = udg_Next[I]

в массиве занесено следующее значение Next[ 1 ]=2 и т.д. Next[ 8191 ]=0
то есть проверка условия значительно медленее чем обращение к глобальному массиву

nic666 добавил:
Заметьте что в случае 1, когда использованы все три функции, результаты чтения из кеша 19%, а во всех остальных 16%.
Это наводит на мысль, что обслуживание кеша также выполняется и при чтении из него.
В случае 1, просто обслуживать уже нечего - все уже обслужено при записи.
Старый 15.01.2007, 15:08
exAres
I love magic :)
offline
Опыт: 7,788
Активность:
Я пробовал с подвешиванием потока(как DioD) но использовал не массив а просто глобальную переменную(int) у меня получились таки результаты : Кеш записывался 18749 раз до глушения потока а глобалка 33332 раза.
Старый 15.01.2007, 15:17
nic666

offline
Опыт: 5,612
Активность:
MrSmiLe
Да здесь примерно такое же соотношение если считать грубо. Я использую формулу с коррекцией на "накладные расходы", то есть засекается еще скорость выполнения "пустого цикла" и от всех результатов эта величина вычитается...
Вот и получается что не 60% к 100%, а 42%, а то и 13% (через BJ)

nic666 добавил:
Да кстати:
от засорения кеша мало что зависит, видимо хеш функция очень хитрая...
Если бы знать конкретно как она выглядит, то можно было бы разработать метод засореняи, чтобы было заметно...
Старый 15.01.2007, 15:42
exAres
I love magic :)
offline
Опыт: 7,788
Активность:
Моё мнение о КЕШе :
  • Это какое-то подобие INI т.е. его засорение только увеличивает его размер. Хотя это только моё мнение :)
Старый 15.01.2007, 15:59
DioD

offline
Опыт: 45,134
Активность:
storeint(I2S(GetRandomInt(1,999999)),I2S(GetRandomInt(1,999999)),GetRandomInt(1,999999))
хоть за засоряйтесь, но подвешивание потока не покажет результат
только наложение потоков или воч таймер
Старый 15.01.2007, 16:09
Toadcop

offline
Опыт: 54,313
Активность:
блин... вы потоки меряете а не производительность...
кеш в раз 5-6 медленей чем простоя запись в переменую массив
а также инциализация локалок в большом количестве не советуетьса т.к. требует в 3 раза больше времени чем установление переменой значение !
короче не то мериете ! товарищи...
Старый 15.01.2007, 17:20
DioD

offline
Опыт: 45,134
Активность:
всё это мерели уже в доль и поперёк 3 раза...
Старый 16.01.2007, 04:58
nic666

offline
Опыт: 5,612
Активность:
Toadcop
в данном случае результат показывает производительность, хотя я согласен, что между вызовами триггеров может быть еще много чего...
Старый 16.01.2007, 09:26
Toadcop

offline
Опыт: 54,313
Активность:
nic666 в варе ты НЕ как не измереешь произодительность !
Старый 18.01.2007, 14:25
remal
нечто
offline
Опыт: 2,087
Активность:
уже запарился повторять, что первичная оптимизация должна быть на уровне алгоритма. в каких-то случаях кэш будет ЗНАЧИТЕЛЬНО быстрее. да, ещё стоит учеть затраты на разработку кода (для кэша они значительно меньше)

Отредактировано ZlaYa1000, 30.01.2007 в 04:18.
Старый 28.01.2007, 22:41
DioD

offline
Опыт: 45,134
Активность:
remal
Я уже доказал раза 3 что TTL цикла не связан со скоростью функций.

Про массивы, их юзать имеет смысл только в узких местах, в остальных случаях темп глобалки рулят неимоверно.
Старый 29.01.2007, 06:39
nic666

offline
Опыт: 5,612
Активность:
remal
LOL... не нарывайся на оскорбления:
1) Я не говорю что кеш плохая вещь. Я сам им пользуюсь. И многие вещи без кеша не реализуешь 8192 элемента не хватит...
2) "Первичная оптимизация на уровне алгоритма". Это может для не профессионалов звучать профессионально, на деле это СЛОВОБЛУДИЕ. Сам алгоритм строится из "кирпичей", которые в разной степени хороши или плохи.
3) Я уже программировал на АСМЕ Z80 еще когда вы под стол пешком ходили... 1989...


DioD
TTL цикла напрямую связан со скоростью функций, но не для всех функций, так как некоторые работают асинхронно т.е. запускают другой поток. В свою очередь есть ограничение на число запусков потоков, и на число запусков некоторых функций...
Поэтому например нельзя поменять pathable на всей карте в одном цикле - поток прерывается, так как ограничено число запусков.
Все это затрудняет сравнение производительности, но не делает его невозможнам.

===============================================================
Всем кто еще непонял:
Оценка скорости кеша в 15% от скорости массива - даже завышена! Скорее ближе 8-10%.

Отредактировано nic666, 29.01.2007 в 09:59.
Старый 29.01.2007, 09:52
remal
нечто
offline
Опыт: 2,087
Активность:
2nic666:
а ты не понял меня. хотя тут уже моя вина - плохо написал.
- дело не в 8192 элементов. дело в более быстром поиске.
- тут я имел ввиду скорее не алгоритм, а выбор способа решения задачи.
- и? я знаю дофига программистов, которые уже оооочень давно кодили, но при этом получают мизерные зарплаты. так что опыт работы от 10 (цифры с потолка) лет в нашей сфере ни о чём не говорит, если ты не крупный начальник.

про оценку. она бесполезна. ты зря потратил время. давайте ещё сравним производительность PHP и C++! результаты тоже будут резко отличаться. но эти языки предназначены для решения разных задач и, поэтому, их сравнение не имеет смысла. тут точно также.

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

ЗЫ: неужели 20-летний я смог настолько задеть самолюбие старичка программирования? :)

ЗЗЫ: про непроффесианализм я писал, кстати, не про тебя. про тебя можно сразу сказать, что человек смыслит в программировании. писал я про кое-кого на это форуме. которые только и делают, что задрачивают беспелезные тесты.

Отредактировано remal, 29.01.2007 в 12:57.
Старый 29.01.2007, 12:47
nic666

offline
Опыт: 5,612
Активность:
remal
нет... мы друг друга не поняли, но вы говорите "про оценку. она бесполезна."

Я думаю, вовсе нет, - она полезна. Так как находятся умники, которые используют кеш везде и всюду, нисколько не думая что он медленее.

Насчет, "ты зря потратил время"... может быть, но каждый сам решает как его тратить..
Старый 29.01.2007, 12:55
remal
нечто
offline
Опыт: 2,087
Активность:
да, добавлю: меня просто удивляет, как люди на этом и ему подобных форумах рвут допу, чтобы доказать, что его способ решения задачи лучше, когда они даже ни разу книжку кнута в руках не держали...

если у вас так много мозгов, DioD и Toadcop, то почему вы до сих пор сидите на этом форуме и вообще пишите что-то на jass? пора бы уже стать реалистами, имхо..

remal добавил:
nic666, согласись, что таких умников наставлять на пусть истинный путём тестов производительности как-то странно... имхо, тут, на этом форуме, это бесполезно. люди не стремятся создать что-то офигенное. люди пытаются творить. не получается качественно - ну и хрен с ним.
[+] 3 пункта от ZlaYa1000: спровоцировал конфликт
Старый 29.01.2007, 13:05
DioD

offline
Опыт: 45,134
Активность:
Так, задаю вопрос, сколько раз выполняется:

Код:
loop
endloop


?

Я думаю что вы сможете заметить что пустой цикл тоже выполняется.
Раз вы читали кнута сможете всё...
Старый 29.01.2007, 13:50
Toadcop

offline
Опыт: 54,313
Активность:
Цитата:
люди не стремятся создать что-то офигенное. люди пытаются творить. не получается качественно - ну и хрен с ним.


loop
endloop т.к. ты не используешь щётчик... ну где то 40000 раз может чуть больше...
[+] 5 пунктов от ZlaYa1000: оскорбление

Отредактировано ZlaYa1000, 30.01.2007 в 04:20.
Старый 29.01.2007, 14:21
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы можете скачивать файлы

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 10:17.