Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / Архитектура много пользовательского игрового сервера. (3 стр)

Архитектура много пользовательского игрового сервера. (3 стр)

Поделиться

Страницы: 1 2 3

ZabПостоялецwww10 сен. 201721:35#30
Chupakaber
> вобщем-то 50000 потоков даже для ммо-сервера довольно таки дофига, так что бенч
> так для сравнения корутин с потоками чисто принципиально. а на деле в 10000
> потоках разница намного меньше
Я вникал в это примерно лет 10 назад, сейчас возможности слегка возросли, но не настолько же...
10 лет назад 50 тыс потоков были смертельны для любой системы, кроме соляриса. Да и на солярисе зависело от задач, если все эти потоки не сумели стать легкими, загибался и солярис. 10 тыс - это был примерно предел возможностей для юниксовых систем, при котором они страшно уже тормозили, но еще работали. Без заметных тормозов - примерно 1 тыс потоков. Под виндой все эти цифры надо делить на три, для того же самого оборудования.
ChupakaberПостоялецwww10 сен. 201722:54#31
Zab
ты абсолютно прав
это был лажовый бенч (:
на деле оказалось, что часть потоков успевала закрываться пока новые потоки ещё создавались

в итоге на тесте с 1000 действительно параллельными потоками юнити сказало "фатал еррор", ту мэни тредс

удалось прогнать тест на 100 потоках и 100 корутинах

Thread benchmark
Invoke time: 55ms
Work time 127ms
Total time: 182ms
Rendered frames: 45


Coroutine benchmark
Invoke time: 3ms
Work time: 251ms
Total time: 234ms
Rendered frames: 56


получается корутинки вызываются быстрее, но за счет того, что используют главный поток, одно ядро - немного проигрывают

да и корутинок удалось вызвать 10тыс параллельных (возможно и больше можно. но ждать не охото)

Coroutine benchmark
Invoke time: 60ms
Work time: 5121ms
Total time: 5181ms
Rendered frames: 70

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

надо на шарпе в VS или Mono сравнивать мультипоточную асинхронность и однопоточный менеджер операций (какой нибудь самописный)

но думаю это уже как-нибудь потом

Sh.Tac.Постоялецwww10 сен. 201723:21#32
Chupakaber
> лажовый бенч
да уж : )
не гуманно мерять thread.Start() + lock(threadLock) vs CoroutineMethod()

ну вернее можно если бы CoroutineMethod() и его аналог были хоть сколько-нибудь длинными

З.Ы. может выдать обоим ровно одну и ту же задачу известной длины, для потоков нарезать её по-крупному, для корутин мелко?

Правка: 10 сен. 2017 23:26

ZabПостоялецwww10 сен. 201723:40#33
Предлагаю посмотреть в сторону erlang'а. Большинство проблем там исполняющая система решает сама. Но программировать придется на специфическом языке, ведущим свое происхождение от пролога.
Для справки, систему разрабатывала фирма ericsson, но было принято политическое решение уходить на java. Все наработки пошли в открытый доступ и стали очень популярны при разработке серверов. Не знаю насколько оно пригодно для программирования игр.
kvakvsПостоялецwww11 сен. 20170:48#34
Zab
> Предлагаю посмотреть в сторону erlang'а. Большинство проблем там исполняющая
> система решает сама. Но программировать придется на специфическом языке,
> ведущим свое происхождение от пролога.
> Для справки, систему разрабатывала фирма ericsson, но было принято политическое
> решение уходить на java. Все наработки пошли в открытый доступ и стали очень
> популярны при разработке серверов. Не знаю насколько оно пригодно для
> программирования игр.
На той же основе разработано множество языков, из популярных Elixir, LFE, Alpaca, не обязательно давиться "трудным" Эрлангом, и он кстати совсем не трудный.
Прекрасно подходит для серверов где время ответа некритично (фпс шутеры не подходит, медленные спокойные ммо должно в принципе подходить).
MixeYaПостоялецwww11 сен. 201712:51#35
Chupakaber
> в итоге на тесте с 1000 действительно параллельными потоками юнити сказало
> "фатал еррор", ту мэни тредс
> удалось прогнать тест на 100 потоках и 100 корутинах
Не понял, что за фигня. Написал простенький скриптик на питоне:
import threading
from time import sleep


def печатальщик(номер_потока):
    счётчик = 0
    while True:
        счётчик += 1
        print("Вывожу текст. Поток номер:", номер_потока, "Номер вывода: ", счётчик)
        sleep(10)


for номер_потока in range(10000):
    поток = threading.Thread(target=печатальщик, kwargs={"номер_потока": номер_потока})
    поток.start()

Вот результат(десять тыщь потоков, двадцать тыщь десткрипторов):

+ Показать

Chupakaber
Память, конечно сожрало почти всю, больше потоков делать нельзя. Но это всё-таки не сотня.

Чем мой код отличается от вашего, что у вас на тысяче потоков уже фатал еррор?

Правка: 11 сен. 2017 12:55

Sh.Tac.Постоялецwww11 сен. 201723:04#36
MixeYa
> Чем мой код отличается
очевидно тем, что он ничего не делает : )
спит вместо этого, так можно табуны чего угодно гонять пока все спят
ChupakaberПостоялецwww11 сен. 201723:57#37
Sh.Tac.
> спит вместо этого, так можно табуны чего угодно гонять пока все спят
не, нельзя. на каждый поток через дискретный отрезок времени система тратит время на проверку спит он или нет. и это как раз камень преткновения, когда кол-во потоков = кол-ву ядер процессора а процессы в этих потоках тяжеловесны и их рассчет занимает на процессоре этот заранее извесный дискретный отрезок времени, то наносекунды прохода по списку потоков и переключение контекста несущественны по отношению к милисекундам полезной нагрузки
но с какого-то момента (количества активных и пассивных потоков вместе) сервисные действия - проход по списку потоков и проверка спят они или нет, и не пора ли переключить контекст, занимает существенную часть процессорного времени, и для конкретного железа есть конкретный предел суммарного количества потоков, когда система вместо того, чтобы рассчитывать полезную нагрузку будет заниматься на 100% только проверкой списка процессов спят они или нет

MixeYa
> Чем мой код отличается от вашего, что у вас на тысяче потоков уже фатал еррор?
я же писал: юнити-проблемы

ошибка звучит дословно как "Fatal error in gc: too much threads"
не уверен точно, это захардкоденый лимит какой-то или случается seg.fault из-за шареной переменной счетчика завершенных процессов. а может gc всю память сожрал, я как-то не обратил внимания

Sh.Tac.Постоялецwww12 сен. 20170:22#38
Chupakaber
> система тратит время на проверку спит он или нет. и это как раз камень
> преткновения
я конечно не пишу планировщики по три на дню в свободное время : )

но что мешает закинуть thread_id и time_stamp = now + sleep_period  в сортированную очередь и совсем не трогать треды время которых ещё не подошло к разморозке?

З.Ы. и вообще я не понимаю этого загона с тредами : )
сам же писал на первой странице

> один поток из коллекции сообщений достает и обрабатывает сообщения быстрообрабатываемые
> и частые. а другой поток достает только тяжелые сообщения

тут правда следует уточнить, что один поток является диспетчером сообщений, неважно быстрые они или тяжёлые, и отдаёт тяжёлые другому, который их ворочает сколько хочет

Правка: 12 сен. 2017 0:40

Страницы: 1 2 3

/ Форум / Программирование игр / Сеть

2001—2017 © GameDev.ru — Разработка игр