![]() |
Модераторы: LSD Страницы: (144) « Первая ... 76 77 78 79 80 ... Последняя »
( Перейти к первому непрочитанному сообщению ) |
![]() ![]() ![]() |
|
Beltar |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 627 Регистрация: 11.1.2006 Репутация: 2 Всего: 7 |
Нет выделения памяти. Вообще. Ни одного конструктора. И все в одном месте сложено. Ну собственно в чем и смысл. Вряд ли при разработке RTS я очень много выиграю по сравнению с обычным созданием объектов в куче. Потому что сложность обработки многократно превышает сложность создания и перебора.
-------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. ![]() Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере. |
|||
|
||||
k0rvin |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 442 Регистрация: 24.1.2010 Репутация: 1 Всего: 5 |
Да какая разница, выделение памяти ты заменил обходом пула в поисках свобоной ячейки (мертвого юнита), чтобы впендюрить туда живого. И опять же, ничто не мешает точно так же в программе с GC выделить пул, который будет жить все время работы программы. Добавлено через 1 минуту и 6 секунд
Ну я тебе уже скинул список бенчмарков, где паскаль всосал по производительности. Не нравится — предлагай свой бенчмарк. -------------------- “Object-oriented design is the roman numerals of computing.” — Rob Pike All software sucks |
|||
|
||||
Beltar |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 627 Регистрация: 11.1.2006 Репутация: 2 Всего: 7 |
Обход пула делается в рамках игрового цикла, юниты ездят, стреляют и т. п. Дырки закрываются попутно. Новый юнит же жестко пишется на вершину пула. Как в Тетрисе, где точки, объединенные в фигуры падают сверху, однако при определенных условиях изымаются из середины.
Вопрос не в этом, а в том, что управляемый мной пул быстрее, чем выделение памяти через конструкторы, и нет потребности в GCб чтобы чего-то освобождать и дефрагментировать.
Ты путаешь Паскаль и компилятор. Кстати, было такое вот измерение для Pascal.ABC http://pascalabc.net/stati-po-pascalabc-ne...roizvoditelnost Вывод в общем-то такой, что все эти хваленые объекты на стеке фуфло полное и правильная оптимизция компилятора рулит. Кстати, делать мне нефиг, и я начал сам это перемножение матриц гонять, благо есть аж 4 Паскаля, да и VS 2008 вроде с шарпом и плюсами есть. Пока сделал на Delphi и Pascal ABC. Или я что-то неправильно конвертнул, или для ABC.NET все печально... На Core Quad 8400-2.66 (это намного слабее i5-3.3) Delphi с неоптимизированным алгоритмом за 10.9 сек управилась, ABC потребовал 37 и лишь с оптимизацией и дикой многопоточностью вышел в 8.7. Интересно, что дальше будет. -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. ![]() Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере. |
||||
|
|||||
Athari |
|
||||||
![]() Новичок Профиль Группа: Участник Сообщений: 1 Регистрация: 27.6.2007 Где: Казань, Россия Репутация: 1 Всего: 1 |
@k0rvin
Вот здесь в шарпе есть нюанс, который меня иногда достаёт. У структур нельзя переопределить конструктор по умолчанию. Он всегда есть сам по себе и забивает структуру нулями. В плюсах в этом плане круче -- конструктор по умолчанию, разумеется, можно переопределить. При создании массива вызовутся все конструкторы. Если конструктора по умолчанию нет, то массив создать будет невозможно. Также в коллекциях STL аллокаторы умеют создавать неинициализированные блоки под будущее заполнение структурами, а потом вызывают inplace new по мере добавления элементов. @Beltar
Это круто. "Но есть нюанс" © Во-первых, ты сделал массив записей. Так не выйдет полиморфизма. Предлагаешь делать switch длиной в 200 пунктов по типу юнита? Предлагаешь в запись пихать все поля всех юнитов? Давай переделывай на class и нормальные полиморфные указатели. У нас ООП, а не детсад. Во-вторых, что это за масштабы такие -- 256 юнитов? Современные игры десятками тысяч могут юниты генерить (и даже не очень современные). Однако и при десяти юнитах, и при сотне тысяч юнитов, массив будет одной длины. Игроки со слабыми компьютерами твою оптимизацию не поймут. Так что давай переделывай на изменяемый размер массива. (Ладно, опционально. Всё равно ты ещё на первом пункте сольёшься.)
Ни черта не понял, что ты здесь расписал и зачем. Но ты вот уплотнение упомянул. Очень интересный и важный вопрос. Вот ссылается один юнит на другой через поле "СледоватьЗаЮнитом". Сможешь упаковать такой массив? Учти, таких полей -- десятки, они идут во все стороны. Также есть ссылки из других объектов, не только из юнитов. |
||||||
|
|||||||
k0rvin |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 442 Регистрация: 24.1.2010 Репутация: 1 Всего: 5 |
Нет, не путаю. Докажи, что делфийский компилятор выдает более производительный код, чем fpc.
Нет, вывод там был такой:
Добавлено через 2 минуты и 4 секунды P.S. Во многих играх логику как раз пишут на более высокоуровневых, так сказать «скриптовых» языках, типа lua например. На плюсах только графический движок. -------------------- “Object-oriented design is the roman numerals of computing.” — Rob Pike All software sucks |
||||
|
|||||
Beltar |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 627 Регистрация: 11.1.2006 Репутация: 2 Всего: 7 |
Не докажу, получается как раз наоборот. Смысл в том, что определяет больше не язык, а компилятор. Кстати, на тесте который там по ссылке вышло на моей машине у DXE3 10.9 и 6.3 сек, У FPC под Лазарусом 10 и 4.9, Pascal ABC.NET 9.8 и 3.3, Delphi Prism 9 и 3. Т. е. в MS програмеры хлеб зря не едят и компилятор с байт-кода нормально оптимизируют, но чтобы увидеть результаты должен быть подходящий алгоритм. Шарп, VС++, и билдер еще не проверял. Но в принципе ожидаемо, что шарп покажет те же результаты, что и призма, билдер будет на уровне Delphi (вряд ли там оптимизатор лучше), VC++ должен всех порвать. Delphi пора бы переводиться на LLVM-компилятор.
Ага, описание юнитов, порядок анимации и т. п. задачи для которых важна скорость разработки и модифицируемость без пересборки exe. При этом язык такой может только то, что ему предотавляет бинарная библиотека игры. -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. ![]() Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере. |
||||
|
|||||
Bother |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 0 Регистрация: 13.4.2013 Репутация: нет Всего: нет |
|
|||
|
||||
Beltar |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 627 Регистрация: 11.1.2006 Репутация: 2 Всего: 7 |
Для этого надо использовать аж STL? А чем обычная дельфовая SetLength от этого отличается? Зачем тут параметризация я в упор не вижу.
Я тебе позавчера кинул статью http://www.programmersclub.ru/Рабство-программистов/ Ты сказал, что автор нуб и опозорился, хотя он там наглядно показал, что наследование спокойно заменяется агрегацией. А в моем случае достаточно создать при старте игры вечные классы с описанием юнитов и каждому новому юниту выдавать ссылку на его класс. Похоже до неотличимости на соединениеме таблицы в БД со справочниками по 1-n. Соответственно имея в игре хоть 10, хоть 1000 моих любимых Missile Defender'ов (C&C Generals Zero Hour) я буду иметь всего один огроменный экземпляр класса, где этот Missile Defender описывается. Там можешь упражняться с полиморфозмом, который, я тебе сразу говорю, если не сфейлится, то не позволит описать цепочки наследования дальше 2-3 ур. Я и без наследования могу в классе написать, что если у юнита есть параметр ReturnToBaseForReload, то он расстреляв боекомплект будет в состоянии Idle двигаться к зданию приписке, switch тут не больно какой получается.
1) Я кроме серии Total War игр с тысячами юнитов одновременно, что-то ни одной не помню. При этом в TW размер отряда в тех играх серии, что я играл, можно задать, есть нормальное значение и есть максимальное (2х) ну так как оно там на максимальной численности работает, это отдельный разговор. В целом можно считать, что там в 1 vs 1 при полных армиях будет при максимальной численности порядка 60-70 юнитов на отряд, у каждого игрока 20 отрядов и того 2500-3000, которые могу только выбывать из боя. А рекламу вида "Runs great on Intel i7", когда этот самый i7 стоил 10к+ можно было воспринимать только как издевку. Игры семейства C&C дают темп строительства юнитов от 5-20 с. на юнит с 2-3 производящих построек на игрока и пару зданий в минуту с диким темпом их уничтожения. В других играх темп похожий, иногда сквадами на 5-20 юнитов. 2) Любая система работает с определенными количественными ограничениям, если комп при 500 юнитов впадает в задумчивость, то нафига 1000? Так что выделить несколько больше памяти, чем будет использоваться в 90% случаев вполне логично. Потом можно запросить больше памяти, расширить массив тебе никто не запрещает, но это в любом случае выгоднее, чем запрашивать постоянно память по мелочи, что с куда большей вероятностью приведет к ее фрагментации. По поводу организации данных, то можно так: а) Массив структур и стек с номерами свободных мест. Новый юнит располагается по адресу взятому из стека, если стек пуст, то добавляется в конец. После смерти юнита, его место помещается в стек. Недостаток метода, массив сложно сжимать, надо учитывать связи между юнитами при перемещении, юниты с большими адресами могут по ним надолго зависать, хотя можно и их смещать. б) Заводим еще один массив с адресами структур в пуле и перебирать будем именно его, очевидно, что указатели в нем можно легко перемещать. Недостаток, чуть больше памяти, чуть дольше доступ с полям структур, если нам потребуется еще память и мы сделаем нашему пулу SetLength, то никто не гарантирует, что он не будет перемещен, поэтому лучше иметь на этот случай еще один пустой массив нулевой длины, ему задать новый размер, и туда все копирнуть с поправкой указателей. Ладно, понятно, что пример, притянутый за уши. В RTS куда больше других вещей, которые надо считать. Да и разного рода объектов весьма переменного размера не учитывает, например, список сидящик в БТР пихотов, или маршрут движения. Но фактически не самыми сложными срествами получается организовать хранение данных, где выделение памяти происходит редко и только крупными блоками. Кто-то будет спорить, что подобный подход в плане производительности куда более эффективен, чем создание раз за разом черт знает где объектов, их уничтожение, а потом шмон программы по каким-то там нетривиальным алгоритмам GC? Впрочем нет смысла говорить о дизайне "программиста" для которого качество языка определяется исключительно наличием GC. Это сообщение отредактировал(а) Beltar - 27.4.2013, 18:24 -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. ![]() Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере. |
||||||
|
|||||||
Bother |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 0 Регистрация: 13.4.2013 Репутация: нет Всего: нет |
можно использовать дек(и производные) и забыть про лимит размера.(C++, не знаю как для дельфей)
Это сообщение отредактировал(а) Bother - 27.4.2013, 19:43 |
|||
|
||||
Bother |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 0 Регистрация: 13.4.2013 Репутация: нет Всего: нет |
"аж STL" используется на каждый чих, это основная библиотека плюсов. А про аллокатор - он позволяет отдельно определять методы для аллокации и инициализации. Не знаю к чему он вообще был упомянут, для этого не нужно дополнительно переопределять поведение стандартного аллокатора. Достаточно вызвать метод reserve у vector'a, например, чтобы аллокатор выделил место в памяти, и по мере заполнения на этом месте будут создаваться объекты. |
|||
|
||||
Beltar |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 627 Регистрация: 11.1.2006 Репутация: 2 Всего: 7 |
По поводу объектов на стеке, ну вот есть они в плюсах, но что-то сами наСИльники далеко не всегда положительно оценивают такую практику, да и если подумать, чем объект в стеке отличается от структуры в стеке? Доступена сразу же, никаких конструкторов\деструкторов помрет так же при выходе. Иногда бывает нужно какую-то функциональность в процедурке получить. Например, файл прочитать. Я извиняюсь спросить, а кто мешает создать глобально один экземпляр нужного класса, который и будет обеспечивать нужную услугу, когда она нужна. Или будем при каждом вызове процедурки его заново создавать и убивать? А еще в других местах, где такая же функциональность понадобилась. Нахрена? Нет, может там нужно один раз при запуске чего-то выполнить, но ради этого проектировать язык так, чтобы сэкономить десяток тактов процессора 1 раз?
![]() Что еще остается? Умные указатели из плюсов? В Delphi сейчас реализуются на основе структур, интерфейсов и дженериков. Ключевой элемент именно дженерики, а не пресловутые, неотличимые от структур объекты в стеке. В общем очередной гнилой наезд от человека, который не знает не то, что Delphi, а вообще программирования. И хоть сколько языков такой изучит все равно в упор не будет видеть очевидного. Это, кстати, и тов. Атари ответ почему он не нашел в Delphi ничего нового. Просто потому что, в Delphi сейчас есть все, и это организовано довольно естественно, но в других языках часто называется по-другому. -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. ![]() Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере. |
|||
|
||||
Bother |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 0 Регистрация: 13.4.2013 Репутация: нет Всего: нет |
Ключевое отличие - тебе не нужно писать то же самое дважды. Иногда это просто нереально(пришлось бы реализовывать функционал сторонних библиотек). Так что объекты полностью отличаются от структур - это другая плоскость. Все твои функции будут работать с одним файлом? Для остальных объектов это не менее тупо.
Код в студию. Сути это не изменит, просто хочу посмотреть не слишком ли уродливо. ![]() Ты так и не реализовал то, что я просил. Так что не нужно тут пустозвонить и уводить разговор в сторону. Про мои навыки можешь и не заикаться - вылези для начала из песочницы. |
|||
|
||||
k0rvin |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 442 Регистрация: 24.1.2010 Репутация: 1 Всего: 5 |
Откуда такие дровишки? Вполне себе используют и часто. Тот же RAII например, хотя он не про производительность.
Опять же RAII. Конструктор захватывает ресурс, деструктор — освобождает. В C# для подобного пришлось специальное ключевое слов ввести. Теперь и в жабу добавили расширение try. В чем его «ключевость»? Ололо, покажи мне в делфи естественное сопоставление с образцом (pattern matching). -------------------- “Object-oriented design is the roman numerals of computing.” — Rob Pike All software sucks |
||||
|
|||||
Beltar |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 627 Регистрация: 11.1.2006 Репутация: 2 Всего: 7 |
Блин, объясните мне, почему я после Паскаля четко представляю себя, что такое элементарный тип, что такое структура, а что такое ссылочные типы, как замаскированные под элементарные (String), так и собственные ссылочные, а данный человек с собачьей головой на аватаре этого не представляет? И что ни один дельфин в здравом уме не будет городить какие-то там классы в качестве локальных переменных, когда весь нужный функционал был представлен в языке структурами с момента своего возникновения.
Вот это и можно назвать ООП в действии, мозг покалечен и человек неклассово мыслить не может.
Еще раз, для альтернативно одаренных. Мне нужно прочитать что-то из файла, у меня есть для этого класс TFile с методом Read(FileName;Buffer). Я создаю этот класс и читаю. Дальше мне, возможно, понадобится еще что-то прочитать\записать и забыть. Зачем я в этом случае должен уничтожать этот экземпляр, чтобы потом только создавать его заново, как дурак? Если же мне это считывание понадобилось разово, то тогда расходы на создание и уничтожение одного экземпляра становятся равны нулю. Так для чего мне нужно создание в стеке? Серьезные объекты там не создашь по определению, они, как правило, нужны глобально. Мелочевка же представима структурами. Ну или object'ами, у них наследование есть примитивное. Проблема существует только в воспаленных мозгах фанатов плюсов и иных языков, исключающих неклассове мышление.
Нагуглишь. -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. ![]() Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере. |
||||
|
|||||
Athari |
|
||||||||||||||||||||
![]() Новичок Профиль Группа: Участник Сообщений: 1 Регистрация: 27.6.2007 Где: Казань, Россия Репутация: 1 Всего: 1 |
@Beltar
STL -- это не "аж", а часть стандарта плюсов. Но ни STL, ни boost, ни .NET Framework дельфи даже в эротических снах не снились. Ты мне уже демонстрировал свой велосипед для рекурсивного прохождения по директории -- спасибо, поржал. И всё вышеупомянутое можно делать и без STL, разумеется. Внутри никакой магии, чистые плюсы. Только обычно так не делают.
Ну ладно, ты изобрёл таблицу виртуальных методов. А специфические для объекта каждого класса данные где будут храниться?
Когда ты сказал: "Скриптовые языки не нужны" -- я выпал в осадок. Когда ты сказал: "Системы контроля версий не нужны" -- я офигел. Когда ты сказал: "Юнит-тесты не нужны" -- я ох##л. Теперь ты говоришь: "ООП не нужен" -- я не нахожу слов, чтобы выразить глубину моего удивления. Я правильно понимаю, что для тебя объектно-ориентированного программирования не существует, и в своих программах ты только пользуешься сторонними компонентами, а твоя собственная иерархия классов -- совершенно плоская, и не использует ни наследования, ни полиморфизма, ни прочих бесполезных и тормозных новомодных штучек?
Ты бы ещё в тетрисе квадратики оптимизировал. Юниты в RTS -- это не то, где возникают проблемы с памятью.
Вот ты снова и вернулся к фрагментации. ![]()
Обратим внимание, что на месте старого массива останется дырка в памяти. И опять фрагментация. Ну и сам "стек свободных ячеек" у тебя будет постоянно меняться в размерах -- снова привет фрагментации.
В твоей архитектуре ты так и не избавился от фрагментации (трижды), но уже успел отказаться от ООП, заметно усложнив написание кода своими велосипедами; добавить промежуточные указатели, просадив тем самым производительность на дополнительном разыменовании указателей и помножив на ноль кэш процессора; добавить дополнительной работы при изменении размеров массивов. Пока ты делаешь только хуже. ![]()
Тащемта, параметризованные классы в плюсах тоже на стеке умеют создаваться, как и обычные классы. Неясно, к чему столько эмоций. Ты при изучении умных указателей не забудь, что в дельфи у записей не бывает деструкторов, а также нет возможности переопределить оператор разыменования. Этого уже достаточно, чтобы "умные указатели" в дельфи были ни разу не умными.
"Есть всё"? Лол. Я же при первом появлении здесь перечислил всё, чего в дельфи нет. Давай, раскрой нам глаза, перечисли всё это в дельфи, но с другими -- естественными! -- названиями. @Bother
Оно бесполезно чуть менее, чем полностью. Если Белтар не поленится пример привести, то мы поржём. ![]() |
||||||||||||||||||||
|
|||||||||||||||||||||
![]() ![]() ![]() |
Правила ведения Религиозных войн | |
|
1. Уважайте собеседника 2. Собеседник != враг 3. Старайтесь воздерживаться от тем вида "Windows Rulez" или "Linux Rulez" С уважением, Smartov. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Религиозные войны | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |