Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Игры";
Текущий архив: 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.52 MB
Время: 0.044 c
3-1101476166
Dimedrol
2004-11-26 16:36
2004.12.26
EhLib dropdown lookup list


1-1102620522
SergP
2004-12-09 22:28
2004.12.26
Есть ли функции для преобразования строки в множество?


6-1097439529
Alex_G
2004-10-11 00:18
2004.12.26
Запрос к Web-cерверу системы WebMoney Transfer


11-1084435973
dimon1979
2004-05-13 12:12
2004.12.26
KOL-компоненты и тип PControl


14-1102609969
12345
2004-12-09 19:32
2004.12.26
Add-on for Internet Explorer.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский