Форум: "Игры";
Текущий архив: 2004.12.26;
Скачать: [xml.tar.bz2];
Внизбыстро заполнить 2-у мерный массив значениям Найти похожие ветки
← →
Ландграф Павел © (2004-08-23 17:46) [0]Подскажите, как быстро заполнить MapPath[i,j].Status:= двойками,
FillChar(MapPath, SizeOf(MapPath), 2); так не получается... незнаю как сказать ему чтобы не весь массив, а именно .Status заполнял... массив большой, 128х128, поэтому скорость важна... мож кто на асме подскажет как реализовать...
← →
PVOzerski © (2004-08-23 18:13) [1]Сразу куча вопросов:
1) Что делать с другими полями: оставлять прежние значения или можно тоже двойками забить?
2) А что из себя вообще элемент массива представляет?
3) Массив статический или динамический?
← →
Ландграф Павел © (2004-08-23 20:19) [2]1. Прежние разумеется... иначе я бы FillChar использовал...
2. byte, а какая разница?
3. статический
← →
Алхимик © (2004-08-23 21:00) [3]
> [2] Ландграф Павел © (23.08.04 20:19)
> 2. byte, а какая разница?
А не рекорд? MapPath[i,j].Status ?
← →
Ландграф Павел © (2004-08-23 22:22) [4]нет, byte=), но тип массива TTile, а это уже рекорд...
← →
Алхимик © (2004-08-23 23:15) [5]Погонял заполнение STATUS через цикл и забивание всего массива FillCharom.
Первый вариант рулит.
Можно твоему рекорду сказать чтоб был PACKED - в обоих случаях есть небольшое ускорение.var
t1,t2 : integer;
n,
i,j : integer;
begin
t1 := GetTickCount;
for n:=0 to 1000 do // чтоб было заметно
for i := 0 to 127 do begin
for j := 0 to 127 do begin
MyMassiv[i,j].status := 2;
end;
end;
t2 := GetTickCount;
ShowMessage(IntToStr(t2-t1));
t1 := GetTickCount;
for n:=0 to 1000 do
FillChar(MyMassiv,SizeOf(MyMassiv),2);
t2 := GetTickCount;
ShowMessage(IntToStr(t2-t1));
end;
← →
Ландграф Павел © (2004-08-24 18:39) [6]Хм.. странно, что на асме тормознее чем простой перебор... выдимо на последних версиях Делфи хороший компилятор... преобразует еще лучше чем в FillChar, мож даже с использованием расширенных команд
← →
GrayFace © (2004-08-24 19:48) [7]Ландграф Павел © (23.08.04 20:19) [2]
byte, а какая разница?
Большая. В обычном заполнении byte от integer"а принципиально толичается.
Ландграф Павел © (24.08.04 18:39) [6]
В Fillchar используется Асмовская инструкция, которая почему-то работает медленнее обычного заполнения.
А скорость заполнения значительно увеличется, если использовать указатели. Вот пример:function MyFill(First:pByte; Count:dword; Size:DWord; value:byte);
var i:DWord;
begin
i:=dword(first)+Count*Size;
while dword(first)<i do
begin
first^:=value;
inc(first,size);
end;
end;
Вызывать так:MyFill(@(MyMassiv[0,0].status), sqr(128),SizeOf(MyRecord),2);
← →
Anatoly Podgoretsky © (2004-08-24 19:51) [8]Ландграф Павел © (24.08.04 18:39) [6]
Это не компилятор хороший, а ты асмщик плохой.
← →
Darthman © (2004-08-24 20:13) [9]Самая большая скорость будет так достигнута (если тебе это часто надо делать).
При старте заполняешь, потом через копирование памяти. Быстрее уже не будет.
← →
Zer0 © (2004-08-24 20:17) [10]есть предложение - вместо того чтобы каждый раз заполнять массив поиска пути двойками ввести для тайла id поиска и при каждом новом поиске увеличивать некий global_search_id. далее по ходу поиска если id<>globalid значит в этой клетке еще не были. для очень больших карт дает нехилую прибавку в скорости.
← →
ПсихЪ_копия (2004-08-25 00:28) [11]
> Zer0 © (24.08.04 20:17) [10]
Тогда в один прекрасный момент всё равно подвисать будет. Хотя один раз, не каждый новый поиск. Но при достижении некоего критического значения, максимального для выбранного типа переменной, id"шники в массиве придётся сбрасывать в 0, как и глобальную переменную. Проще по моему искать иными алгоритмами. Вообще, нафиг нужен поиск пути, когда всё можно решить грамотным построением уровней + незаметные ограничения, как например в Fallout. Там перемещение жёстко ограничивалось максимальной длинной обзора при вольной хотьбе и количеством ЭкшнПоинтов в пошаговом режиме.
← →
Zer0 © (2004-08-25 01:42) [12]>ПсихЪ_копия (25.08.04 00:28) [11]
>Тогда в один прекрасный момент всё равно подвисать будет. Хотя один раз, не каждый новый поиск.
при integer`e этот прекрасный момент наступит через 2147483647 поисков, можно считать с вероятностью 4,656612875245796924105750827168e-10 что придется обнулять массив при новом поиске.
ф так как последующие значения id поиска заменяют предыдущие (при самом поиске)... Кстати если при загрузке нового уровня вся сетка обнуляется... вобщем это крайне редкий случай =)
>Проще по моему искать иными алгоритмами. Вообще, нафиг нужен поиск пути, когда всё можно решить грамотным построением уровней + незаметные ограничения, как например в Fallout.
в фаллауте как-раз сделан оптимальный по минимуму шагов поиск. другие алгоримы выдают порой настолько кудрявые пути что хочется уйти в келью =)
>Там перемещение жёстко ограничивалось максимальной длинной обзора при вольной хотьбе и количеством ЭкшнПоинтов в пошаговом режиме.
ради експеримента советую попробовать пробежаться по сильно пересеченной местности в фаллауте.
я нашел исходники A* (самый оптимальный при правильно подобраной фунции весов), а затем и двунаправленного A*(находит что пути блокированы гораздо быстрее). кстати есть оптимизации за счет которых из O(n^2) алгорим становится O(n).
я разобрался в алгоритме с оптимизациями и рад этому безмерно, потому что 1000 юнитов в реальном времени неплохо так бегают по лабиринту друг за другом(в одном из тестов).
← →
П7 (2004-08-25 09:18) [13]
> Zer0 © (25.08.04 01:42) [12]
1. Если бы ты ещё ссылочками покидался или там примерчик кинул, то было бы совсем загляденье.
> ради експеримента советую попробовать пробежаться по сильно
> пересеченной местности в фаллауте.
2. Повторюсь: "всё можно решить грамотным построением уровней". При таком подходе отсутствие возможности пройти в указанную точку определяется в разы быстрее, нежеле на уровне, где просто понакиданы всякие предметы. Тут ведь и левел дизигнер ОГРОМНУЮ роль играет.
3. По моему самый идеальный вариант, это просчёт пути в отдельном потоке (не знаю правда, можно ли запустить 1000 отдельных потоков) при паралельном перемещении персонажа. Ясно дело, что путь расчитается раньше, чем юнит пройдёт хотябы четверть, зато при долгом просчёте ("по сильно пересеченной местности") визуально юнит не будет ни на секунду тормозить и ждать, когда же для него просчитается путь.
← →
Ландграф Павел © (2004-08-25 12:47) [14]Anatoly Podgoretsky> а на личности попрошу не переходить, и если бы ты подумал, то понял что ф-цию FillChar писал не я, а как ты думаешь кто? молодец, ребята из борланда, но давно, еще со времен паскаля, поэтому я думаю они с тех пор это ф-цию не усовершенствовали!
П7>нехочу строить уровни под героя, тем более у меня не изометрия как в фаллауте, а псевдоизометрия, расчеты по декартовой, а дома изометрические... да и расчет происходит быстро, за 0.001 сек, меня не напрягает столько ждать=)
Zer0> да, ссылочку бы....=)
← →
Ландграф Павел © (2004-08-25 12:48) [15]GrayFace> пасибо за помощь, действительно быстрее!
← →
Darthman © (2004-08-25 13:34) [16]Вот тебе написал, работает раза в 2 быстрее:
Procedure DarthmanFill (data : Pointer; Size : Integer);
asm
mov ecx, size
@@loop :
mov [eax+0], $02020202
add eax, 4
sub ecx, 4
jnz @@loop
end;
Но заполняет только двойками и только массив байтовый (по размерности кратный четырем, что в этом случае норм).
26000 тактов вместо 49500 у GrayFace :D
← →
Darthman © (2004-08-25 13:35) [17]пользовать так:
DarthmanFill(@mass[0,0], 128*128);
← →
Darthman © (2004-08-25 13:37) [18]Кстати, в седьмой делфи у меня fillchar дает 27000 тактов.
← →
Ландграф Павел © (2004-08-25 14:28) [19]Darthman> круто! буду блин учить асм.. на делфи=) а то стыдно с такой глупостью обращаться.
← →
Darthman © (2004-08-25 15:37) [20]Ландграф Павел © (25.08.04 14:28) [19]
а то стыдно с такой глупостью обращаться.
Для того и форум, чтобы решать вопросы, да помогать...
ЗЫ: я асм в делфи не учил, так книжку для общего образования полистал...
Была у меня как-то надобность нормализовывать значение до ближайшей степени двойки (тоесть при входе 131 выдвать 128, при входе 120 тоже 128, если 193, то 256, а 191 уже 128 и так далее). Написал как только мог быструю функцию на делфи, когда на асм переписал, раза 4 выиграл по скорости. Вот!
← →
Zer0 © (2004-08-25 21:28) [21]хехе
asm
загрузить в es:[edi] адрес указателя
mov eax, $02020202
mov ecx,длинна в longword
rep stosd
end;
работает быстрее =)
← →
Darthman © (2004-08-25 22:23) [22]писал не задумываясь, хехе... браво, блин :D
← →
Zer0 © (2004-08-26 04:52) [23]дык это все любимая книжка "система команд i80386".
где бы найти "использование MMX в повседневном программинге"... помойму при небольших извратах с MMX perlin noise в рилтайме работать будет =)
Страницы: 1 вся ветка
Форум: "Игры";
Текущий архив: 2004.12.26;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.037 c