![]() |
Модераторы: feodorv |
![]() ![]() ![]() |
|
REZiaMIX |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 346 Регистрация: 3.11.2007 Репутация: нет Всего: 4 |
Пишу сервер , который должен выжимать максимум из ресурсов компьютера)
Использую порты завершения. Вот примерный алгоритм функции пула :
Теперь вопрос : нужно ли создавать лишние потоки под обработку логики(пункт 3) и создавать какую-то свою очередь пакетов т.е
Зависит ли это от среднего времени обработки логики? -------------------- ![]() |
||||
|
|||||
Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 5 Всего: 154 |
мало того, можно даже ждать событий от сокета из нескольких потоков
|
|||
|
||||
REZiaMIX |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 346 Регистрация: 3.11.2007 Репутация: нет Всего: 4 |
Сейчас так и сделано, по 1 потоку на 1 ядро/процессор. Как лучше реализовать очередь ? -------------------- ![]() |
|||
|
||||
Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 5 Всего: 154 |
то-есть алгоритм тот-же, только вместо одного потока - пулл потоков, в каком потоке приняли данные, в том и обрабатываем, а другие потоки в это время могут принимать данные...
Добавлено через 1 минуту и 4 секунды думаю нет смысла создавать очередь пакетов Добавлено через 1 минуту и 38 секунд очередь нужно будет синхронизировать, это приведет к простою потоков |
|||
|
||||
REZiaMIX |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 346 Регистрация: 3.11.2007 Репутация: нет Всего: 4 |
А разве такая ситуация не будет ошибочной , без внутренней очереди?
2 потока принимают пакеты , на оба потока приходит по пакету (обработка каждого из них занимает допустим 0.5 сек времени), в это время больше никто не сможет принять пакет, тк принимающие потоки будут заняты обработкой пришедшихю ??? -------------------- ![]() |
|||
|
||||
Lazin |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 5 Всего: 154 |
В общем случае очередь ничего не даст, так как данные и так буферизуются, то-есть пока их не прочитали они никуда не денутся.
в случае одного потока, без очереди алгоритм будет такой:
если приходит больше пакетов чем обрабатывается, просто ожидания не будет, поток будет выбирать и обрабатывать пакеты непрерывно а в случае если у нас 2 потока, один принимает пакет из сокета и кладет его в очередь, другой достает оттуда пакеты и обрабатывает:
если приходит очень много пакетов, 1-й поток будет непрерывно складывать их в очередь, а 2-й поток будет почти непрерывно их обрабатывать... в общем разницы особой нет... не считая того, что во 2-м случае происходит много лишних действий... это конечно всего-лишь мое мнение, хотелось бы услышать чье-нибудь еще.. ![]() |
||||
|
|||||
REZiaMIX |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 346 Регистрация: 3.11.2007 Репутация: нет Всего: 4 |
Да , ждем ответа профессионала , всетаки в голове какойто непорядок насчет необработки пакетов во время приема с сети)
и... думаю надо оба варианта обкатать на практике. ИМХО Если GetQueuedCompletionStatus возвращается сразу по приходу пакета в буффер, то падение производительности может быть в 1ом случае меньше , чем с внутренней очередью, но все над тестировать Это сообщение отредактировал(а) REZiaMIX - 25.7.2008, 12:39 -------------------- ![]() |
|||
|
||||
Torsten |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 174 Регистрация: 10.6.2008 Где: Pskov Репутация: нет Всего: 7 |
Сложный вопрос. Мне кажится наиболее эфектнивная обработка получится, если приемом будет заниматся один поток, а обрабатывать данные другие. Т.е. у тебя например есть некое количество обработчиков запросов. В интерфейс поступает запрос - ты ищещь свободный обработчик (лучше заранеее создовать пулл при запуске, чем создовать их динамически), передаешь обработчику данные запроса. Он уже их парсит и чего-то делает с ним, и шлет ответ через интерфейс. Тут имеет смысл присмотрется к модели - событие и обработчик. Первычеый обработчик - сетевой интерфейс, который отправляет события другим обработчикам (логикам), те обрабатывают запрос и шлют ответ. Это сделает абстракцию и будет легче написать многопоточный код, т.к. он не будет зависить от чего-то конкретного. Просто есть событие и обработчик, а какое и какой обработчик - дело реализации. Отправил событие, обработал - никаких чистых вызовов функций, которые в обычном случае будут сильно связывать обьекты и классы. --------------------
We have no begining, we have no end. We are infinite. |
|||
|
||||
Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 5 Всего: 154 |
Мне кажется что это усложнит архитектуру и уменьшит производительность, так как дублируется часть функционала реализованого в рамках winsock. Как это поможет увеличить производительнсть?
|
|||
|
||||
REZiaMIX |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 346 Регистрация: 3.11.2007 Репутация: нет Всего: 4 |
В том дело , что я пишу игровой сервер , надо учитывать что клиент должен получить ответ как можно быстрее и при этом сервер должен держать множество соединений.При варианте потока "что принял , то сам и обработал" возможно какойто из клиентов будет ждать своего ответа относительно долго . При варианте что поток принял , положил в стопку , а другие спец-назначенные обработают, может оказаться что потеря производительности окажется более критической , нежели потеря времени в первом случае. У кого еще какие соображения?) Просто возможно найдется человек , прошедший через все это , который разъяснит ситуацию основываясь на своем опыте.
Это сообщение отредактировал(а) REZiaMIX - 27.7.2008, 09:56 -------------------- ![]() |
|||
|
||||
миг |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 158 Регистрация: 15.9.2008 Репутация: нет Всего: 1 |
если для виндовс то можно ... для асинхронной работы.
1. cоздать объект события функцией WSACreateEvent 2.делаем сокет с объектом события и говорим какие события нужны функция WSAEventSelect 3.ожидать событие функцией WSAWaitForMultipleEvents один из параметров функции массив объектов событий(клиенты) чтоб узнать какое событие сработало нужно вычесть из возвращаемого функцией(WSAWaitForMultipleEvents) значения константу WSA_WAIT_EVENT_0 функции стандартные API винды. смотрите msdn libraryы --------------------
Oaks may fall when reeds stand the storm. |
|||
|
||||
REZiaMIX |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 346 Регистрация: 3.11.2007 Репутация: нет Всего: 4 |
Спасибо за помощь , но это не то. Я уже написал что использую порты завершения (MSDN I/O Completion Ports для справки) , что работает быстрее эвентовой системы , да и вопрос не об этом
![]() -------------------- ![]() |
|||
|
||||
MAKCim |
|
||||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 6 Всего: 207 |
1. использовать неблокирующий I/O 2. использовать общую очередь пакетов с произвольным доступом 3. один поток - аккептор, все остальные (количество CPU - 1 + CONSTANT) - обработчики CONSTANT зависит от того, будет ли переключение контекта на данной системе быстрее, чем обработка одного пакета 4. все обработчики равномерно распределяются по всей очереди для параллельной обработки запросов 5. аккептор также участвует в обработке пакетов в случае отсутствия событий вместо очереди можно использовать огромный статический массив дескрипторов с битом свободно/занято и адресом структуры, описывающей соединение каждый обработчик посредством rand() % COUNT выбирает индекс в этом массиве и направление движения есть второй вариант, но он специфичен для Linux будет эффективнее Добавлено через 13 минут и 15 секунд
фигня может получится так, что один поток захавает все присоединенные сокеты остальные будут простаивать такой подход можно использовать, но тогда надо использовать неблокирующий I/O и поток баллансер, который будет поддерживать равномерность количества соединений на каждом потоке второй вариант - самобаллансировка, когда в случае долгого отсутствия соедениений потоки начинают обрабатывать существующие коннекты Это сообщение отредактировал(а) MAKCim - 21.9.2008, 10:36 -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
||||
|
|||||
MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 6 Всего: 207 |
REZiaMIX,
кроме всего прочего нужно использовать самый производительный мультиплексор целевой системы что-то мне кажется, что под Windows, это WaitForSingleObject/MsgWaitForSingleObjects -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 5 Всего: 154 |
он написал что использует порты завершения, значит IO там неблокирующий
![]() |
|||
|
||||
![]() ![]() ![]() |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Сети | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |