|
|
|
Канал Игры Мечты: «Два пути - количество или качество игр» |
|
|
Minx
1011 EGP
        Рейтинг канала: 6(332) Репутация: 139 Сообщения: 10548 Откуда: Gomel, Belarus Зарегистрирован: 19.11.2005
 |
|
Sh.Tac. : |
вширь или вглубь?
|
Совершенно верно.
Sh.Tac. : |
от некоторых затратных идей
|
А можно пару примеров идей?
_________________ μηδείς αγεωμέτρητος εισίτω |
|
|
Sh.Tac.
151 EGP
  Рейтинг канала: 5(108) Репутация: 14 Сообщения: 1426
Зарегистрирован: 27.07.2005
 |
|
а это почти всё что должно быть в игре мечты
взять хоть глобальную экшн-стратегию где смешались "кони-люди", по сети такое передавать, любая сетка нагнётся
более того, попытки сделать влобную стратегию с использованием сети UE4 также быстро наталкиваются на то, что сеть заточена под другое, имеющихся механизмов управлением репликацией недостаточно, грубо говоря сервер не может запомнить слал он что-то определённому клиенту или нет, и продолжает спамить всем
_________________ This is what you get ...
(c) Radiohead |
|
|
Minx
1011 EGP
        Рейтинг канала: 6(332) Репутация: 139 Сообщения: 10548 Откуда: Gomel, Belarus Зарегистрирован: 19.11.2005
 |
|
Diff : |
Методы решения - укрупнение блоков памяти и, по возможности, отказ от постоянного выделения-освобождения вообще - тоже придуманы не вчера. Эти в огромном количестве выделяющиеся блоки (в случае ТБС, как я понимаю, это блоки обсчета 100500 веток вариантов) как правило однотипные - так и нефиг гонять их туда-сюда, создай сразу пачку и дальше только подгружай в них новые данные.
Ну и я не верю, что автор не в курсе всего этого. Получается, при проектировании TBS перед ним встали невиданные ранее в отрасли проблемы производительности?
|
У Джонатана следующие примеры.
1. Создаем например объект-пул. В нем сразу резервируем 64К. Выделение памяти в пуле делается как на ленте, т.е. быстро. Удаляется из пула только все сразу целиком. Т.е. тоже быстро.
Например, в игре герой зашел на экран. Сделали ему пул. Вышел на следующий экран - грохнули пул и создали все снова, но для нового экрана.
В случае по умолчанию глобальных new/delete malloc/free получаем дефрагментацию и тормоза для выделения и освобождения.
2. Создаем пул, только non-thread-safe. И выдаем каждой нити свой пул. Как результат, во время new/delete malloc/free менеджер памяти не должен синхронизироваться с другими нитями, соответственно использовать mutex и т.п.. Как следствие, возрастает производительность для многопоточных систем.
В случае его TBS соображения такие. Если много AI, и запустить их многопоточно, то они будут конкурировать друг с другом, т.е. им поможет пункт 2. Если AI использует для решения малый объем информации, то этот объем можно засунуть в отдельный для него малый пул. И соответственно, получаем преимущество кэша процессора и пункта 1 (например если нужно решать постоянно задачу обхода дерева решений, где при возврате нужно чистить нижеотбрасываемую инфу по дереву).
_________________ μηδείς αγεωμέτρητος εισίτω |
|
|
Diff
708 EGP
      Рейтинг канала: 2(11) Репутация: 44 Сообщения: 4179 Откуда: Сферическая Земля в вакууме. Зарегистрирован: 04.07.2003
 |
|
Minx : |
Например, в игре герой зашел на экран. Сделали ему пул. Вышел на следующий экран - грохнули пул и создали все снова, но для нового экрана.
|
Ну это же какой-то трындец. Если б я такое написал даже в первый год работы - имел бы душеспасительную беседу с техлидом на тему "так делают только пид@%@сы". Здесь нет причины удалять-создавать. Надо создать один раз.
Minx : |
Создаем пул, только non-thread-safe. И выдаем каждой нити свой пул.
|
Если у него и впрямь большое количество пулов - изобрел бы асинхронную реализацию с масштабированием по ядрам, пользы было бы больше. Если небольшое - то см предыдущий пункт.
Кстати, правда, новых языков - как блох на собаке, а вот универсальной асинхронной библиотеки я не встречал, хотя потребность в ней явно есть - в какой крупный проект ни загляни, там либо свои велосипеды на эту тему (nginx), либо треш угар и содомия с потоками (apache). Правда, я давно уже не интересовался.
Надо было делать такую библиотеку самому тогда .
Minx : |
нужно решать постоянно задачу обхода дерева решений, где при возврате нужно чистить нижеотбрасываемую инфу по дереву
|
Ну вот тут действительно надо что-то придумывать.
_________________ Конец света в конце тоннеля |
|
|
Minx
1011 EGP
        Рейтинг канала: 6(332) Репутация: 139 Сообщения: 10548 Откуда: Gomel, Belarus Зарегистрирован: 19.11.2005
 |
|
Diff : |
Ну это же какой-то трындец. Если б я такое написал даже в первый год работы - имел бы душеспасительную беседу с техлидом на тему "так делают только пид@%@сы".
|
Поэтому у Джонатана нет техлида (;
И наверно потому он может делать такие вещи, как Braid.
Diff : |
Здесь нет причины удалять-создавать. Надо создать один раз.
|
Вроде как мы рассмотрели причины выше в топике.
Diff : |
Если у него и впрямь большое количество пулов - изобрел бы асинхронную реализацию с масштабированием по ядрам, пользы было бы больше. Если небольшое - то см предыдущий пункт.
|
Может он и написал. Этож просто пример.
Хотя я не понял при чем тут асинхронная реализация. Делать асинхронный запрос на каждый чих new и delete - это какое-то абы что.
Diff : |
универсальной асинхронной библиотеки я не встречал
|
Универсальных асинхронных велосипедов и библиотек сейчас куча.
Вот в вики список только про Actor model: https://en.wikipedia.org/wiki/Actor_model#Actor_libraries_and_frameworks
_________________ μηδείς αγεωμέτρητος εισίτω
Последний раз редактировалось: Minx (15:11 20-10-2015), всего редактировалось 2 раз(а) |
|
|
Diff
708 EGP
      Рейтинг канала: 2(11) Репутация: 44 Сообщения: 4179 Откуда: Сферическая Земля в вакууме. Зарегистрирован: 04.07.2003
 |
|
Minx : |
Хотя я не понял при чем тут асинхронная реализация. Делать асинхронный запрос на каждый чих new и delete - это какое-то абы что.
|
Я про то, что наштамповать потоков, а потом мужественно бороться с блокировками и синхронизацией - это... ну, собственно, то что почти все и делают. Но вообще-то это делать не обязательно. Другое дело, что в геймдеве это всегда была наименьшая из проблем, ибо геймдев не склонен к многопоточности.
_________________ Конец света в конце тоннеля |
|
|
Minx
1011 EGP
        Рейтинг канала: 6(332) Репутация: 139 Сообщения: 10548 Откуда: Gomel, Belarus Зарегистрирован: 19.11.2005
 |
|
Diff : |
Другое дело, что в геймдеве это всегда была наименьшая из проблем, ибо геймдев не склонен к многопоточности.
|
За весь геймдев не скажу, и про него вообще мало чего могу сказать, но вот такое я встречаю:
2005 год : |
Причем на heap. Этим-то он и хуже.
а еще у него дергается mutex на каждом копировании указателя.
Те, кто бездумно рекомендуют shared_ptr либо не знают как он устроен, либо пишут не игры, а тулзы, где производительность не нужна.
http://www.gamedev.ru/code/forum/?id=34739
|
Diff : |
Я про то, что наштамповать потоков, а потом мужественно бороться с блокировками и синхронизацией - это... ну, собственно, то что почти все и делают.
|
Непродуманная штамповка и бессистемная борьба приводит к большой утилизации CPU и полной деградации производительности.
Про слабую многопоточность геймдевовских программ могу только судить по том, как они грузят CPU. Вот у меня сейчас KSP - загружает максимум одно ядро. E: D - где-то на 1.3 ядра. Такую же картину наблюдал в ряде других игрушек. А также архитектурный стиль в виде жесткого cyclic executive.
_________________ μηδείς αγεωμέτρητος εισίτω
Последний раз редактировалось: Minx (23:25 20-10-2015), всего редактировалось 1 раз |
|
|
Sh.Tac.
151 EGP
  Рейтинг канала: 5(108) Репутация: 14 Сообщения: 1426
Зарегистрирован: 27.07.2005
 |
|
shared_ptr уже давно использует interlockedатомарный increment (всё ещё путаюсь когда дело доходит до виндовых терминов)
касаемо многопоточности я как-то открыл для себя схему MPSC (multiple producers single consumer) и вообще забыл думать о том, как там ещё синхронизировать, потокобезопасный контейнер сам вызывает _lock на каждый push и один раз на consume + спит в остальное время, если потребитель не главный тред там какой-нибудь
_________________ This is what you get ...
(c) Radiohead
Последний раз редактировалось: Sh.Tac. (00:45 21-10-2015), всего редактировалось 1 раз |
|
|
Minx
1011 EGP
        Рейтинг канала: 6(332) Репутация: 139 Сообщения: 10548 Откуда: Gomel, Belarus Зарегистрирован: 19.11.2005
 |
|
Sh.Tac. : |
shared_ptr уже давно использует
|
Речь идет о
Minx : |
Причем на heap. Этим-то он и хуже.
а еще у него дергается mutex на каждом копировании указателя.
|
т.е. важна фрагментация хипа и дергание mutex'a. А shared_ptr так.. субъект обсуждения (;
Но shared_ptr все равно дергает mutex, на декременте.
добавлено спустя 9 минут:
Sh.Tac. : |
я как-то открыл для себя схему MPSC
|
А мы уже много лет используем SObjectizer, и такого рода проблем нет в принципе, как и множества геммороя в написании практически любой многопоточности, от временных затрат как на разработку, так и на верификацию. И MPSC там один из кирпичиков из коробки.
В общем случае такие схемы как MPSC занимаются общением между потоками, а общение между потоками (если хочется производительности) должно быть сведено к минимуму. Поэтому если хочется скорости, то в любом случае думать надо головой, и серебряной пули далеко нет и даже намека не предвидится.
_________________ μηδείς αγεωμέτρητος εισίτω
Последний раз редактировалось: Minx (01:31 21-10-2015), всего редактировалось 2 раз(а) |
|
|
Sh.Tac.
151 EGP
  Рейтинг канала: 5(108) Репутация: 14 Сообщения: 1426
Зарегистрирован: 27.07.2005
 |
|
Minx : |
shared_ptr все равно дергает mutex, на декременте
|
нет же, если смогли осилить инкремент, то и декремент туда же
Цитата: |
И MPSC там один из кирпичиков из коробки
|
ага, помницца даже выкинул свой контейнер когда убедился, что boost::asio::io_service делает ровно то же самое, но знание это опять пригодилось для UE4, в общем иногда полезно что-то делать на уровне "кирпичика"
добавлено спустя 10 минут:
З.Ы. по поводу interlocked меня смутил гугл, который в качестве релевантного подсовывает например такой пост, чувак явно пишет про lock и ещё получает плюсы
добавлено спустя 2 минуты:
З.З.Ы. атомики в ходу с 2008 точно, если что
_________________ This is what you get ...
(c) Radiohead
Последний раз редактировалось: Sh.Tac. (01:55 21-10-2015), всего редактировалось 2 раз(а) |
|
|
Minx
1011 EGP
        Рейтинг канала: 6(332) Репутация: 139 Сообщения: 10548 Откуда: Gomel, Belarus Зарегистрирован: 19.11.2005
 |
|
Sh.Tac. : |
нет же, если смогли осилить инкремент, то и декремент туда же
|
Блин.. почему-то на основании этого поста Саттера думал, что декремент менее производителен. А сейчас уже таких следов нету..
_________________ μηδείς αγεωμέτρητος εισίτω |
|
|
Sh.Tac.
151 EGP
  Рейтинг канала: 5(108) Репутация: 14 Сообщения: 1426
Зарегистрирован: 27.07.2005
 |
|
кста кто что думает про ThreadPool в контексте быстродействия синхронизации?
я везде выкидывал когда видел, задачно-ориентированный подход имхо лучче и опять же укладывается в MPSC
_________________ This is what you get ...
(c) Radiohead |
|
|
Minx
1011 EGP
        Рейтинг канала: 6(332) Репутация: 139 Сообщения: 10548 Откуда: Gomel, Belarus Зарегистрирован: 19.11.2005
 |
|
Смысл любого пула в основном в том, что не нужно заново создавать окружение для решения задачи. Т.е. если для решения задачи нужно иметь коннект к БД, привязанный к нити, то пул избавляет от такой проблемы.
Есть и более минорные плюшки. Если например клиент-сервер, где последний обслуживает кучу рандомно появляющихся запросов. То удобно держать пул, всегда готовый к работе.
Также пул может иметь настраиваемые параметры, например число одновременно работающих нитей (min/max), кол-во запросов в очереди (ожидающих если max) и т.д. Потому что для high-load часто получается так, что ограничение max спасает от деградации системы и позволяет в случае ахтунга её держать на пике производительности. И техподдержка может быть более довольна - получает например бегунки min/max и дополнительную свободу для танцев с бубном.
_________________ μηδείς αγεωμέτρητος εισίτω |
|
|
Sh.Tac.
151 EGP
  Рейтинг канала: 5(108) Репутация: 14 Сообщения: 1426
Зарегистрирован: 27.07.2005
 |
|
Minx : |
коннект к БД, привязанный к нити, то пул избавляет от такой проблемы.
|
опасная штука, нужно всё заворачивать в транзакции тогда, а то можно прочитать что-нибудь не того пока другой тред пишет
_________________ This is what you get ...
(c) Radiohead |
|
|
Minx
1011 EGP
        Рейтинг канала: 6(332) Репутация: 139 Сообщения: 10548 Откуда: Gomel, Belarus Зарегистрирован: 19.11.2005
 |
|
Sh.Tac. : |
опасная штука, нужно всё заворачивать в транзакции тогда, а то можно прочитать что-нибудь не того пока другой тред пишет
|
Транзакционность и обеспечение целостности/инвариантов в БД это основы. Без них в БД вообще лучше не лезть.
Нити и пулы необязательно могут быть 1 к 1 в БД. Например, ломится много одиночных запросов по какому-нибудь HTTP, и на уровне БД нужно обеспечить одиночную вставку присланных данных, и только потом отвечать HTTP OK. Вставлять по одному не выгодно (долго), целой нитью ждать на один HTTP жирно (там данные плетутся долго), поэтому ресурсы нитей деляться между запросами, а вставку нужно делать массовым INSERT'ом. Делается пул например в 100 потоков и 8 нитей (например по 2 на железное ядро, но это не строгое правило), и вешается барьер на 20 мьютексов. Приползло 20 полноценных HTTP - массовый INSERT в 20 шт. Не приползло - INSERT послабее по таймауту. Приползло очень много, БД не успевает даже массовыми вставками - все в очередь на ожидание свободных мест пула.
Здесь наверно даже не вопрос производительности нитей и синхронизации, а архитектурное решение и гибкость последующего применения.
Ещё бывают случаи когда удобно абстрактно разбивать ресурсы по сущностям типа пулов. Например, запрос обрабатывается в три этапа A, B и С. Каждому из них дали по пулу каким-то размером и в какое-то число нитей. Запускаем нагрузку. Если получается, что один из (например B) начинает просаживаться, то перебрасываем ресурсов из одного этапа в другой (из A или C в B).
_________________ μηδείς αγεωμέτρητος εισίτω
Последний раз редактировалось: Minx (18:24 21-10-2015), всего редактировалось 1 раз |
|
|
Sh.Tac.
151 EGP
  Рейтинг канала: 5(108) Репутация: 14 Сообщения: 1426
Зарегистрирован: 27.07.2005
 |
|
Minx : |
Транзакционность и обеспечение целостности/инвариантов в БД это основы.
|
в геймдеве эти основы в основном попираются
т.к. БД обычно нужно просто как долговременное хранилище, желательно быстрое и масштабируемое, вот и развелось всяких NoSQL + одни и те же данные на разных узлах могут быть неконсистентны, и с этим приходится работать
_________________ This is what you get ...
(c) Radiohead |
|
|
Minx
1011 EGP
        Рейтинг канала: 6(332) Репутация: 139 Сообщения: 10548 Откуда: Gomel, Belarus Зарегистрирован: 19.11.2005
 |
|
Sh.Tac. : |
в геймдеве эти основы в основном попираются
|
Полагаю что это потому, что одно дело если геймеру не записалось в БД первооткрытие одной звезды из 1000 в E: D, и совершенно другое, если человек положил на счет в банке, и сумма не положилась с вероятностью 0.1%. Или ещё более совсем другое, если вероятность не перейти улицу 0.1%.
Хотя с целостностями вроде даже у Амазона проблемы [были?].
_________________ μηδείς αγεωμέτρητος εισίτω |
|
|
Shirson
1605 EGP
           Рейтинг канала: 7(626) Репутация: 219 Сообщения: 16511 Откуда: 79°W 44°N Зарегистрирован: 29.01.2002
 |
|
Minx : |
совершенно другое, если человек положил на счет в банке, и сумма не положилась с вероятностью 0.1%.
|
Если занудствовать, то это крайне неудачный пример - транзакционность, именно тут, никак проблему не решает.
Она решает, когда делаются транзакции со счёта на счёт, в чистом виде. Тогда либо есть перевод, либо нету (и можно повторить) - целостность операции.
А вот если засунул бапки в автомат, а что-то сбойнуло и транзакция в БД не прошла, тут без разницы - откат транзакции кэш из банкомата не выплюнет
_________________ У меня бисера не доxеpа. |
|
|
Minx
1011 EGP
        Рейтинг канала: 6(332) Репутация: 139 Сообщения: 10548 Откуда: Gomel, Belarus Зарегистрирован: 19.11.2005
 |
|
Shirson : |
Если занудствовать, то это крайне неудачный пример - транзакционность, именно тут, никак проблему не решает.
|
Речь идет о dirty read:
Sh.Tac. : |
можно прочитать что-нибудь не того пока другой тред пишет
|
т.е. например есть две операции из разных точек X и Y: одновременно два человека ложат на один и тот же счет по 1000$.
Алгоритм:
1. Считать состояние счета.
2. Прибавить 1000$.
3. Записать результат в счет.
Без транзакции:
1. X считывает текущее состояние счета (A).
2. Y считывает текущее состояние счета (A).
3. X прибавляет 1000$ (A+1000$). Записывает на счет A+1000$.
4. Y прибавляет 1000$ (A+1000$). Записывает на счет A+1000$.
Результат - на счете A+1000$ вместо ожидаемого A+2000$.
Нарушение целостности/инварианта - дебет с кредитом у сторон не сходится.
С транзакцией:
1. Старт транзакции X. X считывает текущее состояние счета (A).
2. Попытка старта транзакции Y. Ожидание.
3. X прибавляет 1000$ (A+1000$). Записывает на счет A+1000$. COMMIT.
4. Просыпается Y. Y считывает текущее состояние счета (A + 1000$).
5. Y прибавляет 1000$ (A+2000$). Записывает на счет A+2000$. COMMIT.
6. PROFIT.
Вообще, я даже в двух местах типа учебников этот пример с банкоматами как необходимость синхронизации/транзакционности видел.
_________________ μηδείς αγεωμέτρητος εισίτω
Последний раз редактировалось: Minx (20:09 21-10-2015), всего редактировалось 3 раз(а) |
|
|
Sh.Tac.
151 EGP
  Рейтинг канала: 5(108) Репутация: 14 Сообщения: 1426
Зарегистрирован: 27.07.2005
 |
|
по поводу консистентности мне в своё время понравилась картинка с CAP theorem, оказывается в ряде случаев это вообще не важно
Cкрытый текст (кликните здесь для просмотра)
|
_________________ This is what you get ...
(c) Radiohead |
|
|
|
|
|
Канал Игры Мечты: «Два пути - количество или качество игр» |
|