Модераторы: feodorv

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Правильность алгоритма сервера, Высоконагруженный сервер,порты завершеня 
:(
    Опции темы
REZiaMIX
Дата 25.7.2008, 10:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 346
Регистрация: 3.11.2007

Репутация: нет
Всего: 4



Пишу сервер , который должен выжимать максимум из ресурсов компьютера)
Использую порты завершения. Вот примерный алгоритм функции пула :
Код

{
1) Жду события на сокете: GetQueuedCompletionStatus(....)
2) Произошло событие на сокете(пришли данные,коннект и тд) 
               Выделяю память под overlapped структуру , определяю тип события.
3)Если тип событие - прибытие пакета , то
                тутже подгоняю другие структуры, определяю тип пакета, и тд логика;
4)Заказываю новый прием данных
}

Теперь вопрос : нужно ли создавать лишние потоки под обработку логики(пункт 3)
и создавать какую-то свою очередь пакетов т.е 
Код

1)Принимаю пакет , копирую в очередь, без обработки(ей занимается другой поток) заказываю
следующий пакет.

Зависит ли это от среднего времени обработки логики?


--------------------
user posted image
PM MAIL   Вверх
Lazin
Дата 25.7.2008, 11:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 5
Всего: 154



мало того, можно даже ждать событий от сокета из нескольких потоков
PM MAIL Skype GTalk   Вверх
REZiaMIX
Дата 25.7.2008, 11:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 346
Регистрация: 3.11.2007

Репутация: нет
Всего: 4



Цитата(Lazin @ 25.7.2008,  11:17)
мало того, можно даже ждать событий от сокета из нескольких потоков

Сейчас так и сделано, по 1 потоку на 1 ядро/процессор. 
   Как лучше реализовать очередь ? 


--------------------
user posted image
PM MAIL   Вверх
Lazin
Дата 25.7.2008, 11:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 5
Всего: 154



то-есть алгоритм тот-же, только вместо одного потока - пулл потоков, в каком потоке приняли данные, в том и обрабатываем, а другие потоки в это время могут принимать данные...

Добавлено через 1 минуту и 4 секунды
думаю нет смысла создавать очередь пакетов

Добавлено через 1 минуту и 38 секунд
очередь нужно будет синхронизировать, это приведет к простою потоков
PM MAIL Skype GTalk   Вверх
REZiaMIX
Дата 25.7.2008, 11:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 346
Регистрация: 3.11.2007

Репутация: нет
Всего: 4



А разве такая ситуация не будет ошибочной , без внутренней очереди?
2 потока принимают пакеты , на оба потока приходит по пакету (обработка каждого из них занимает допустим 0.5 сек времени), в это время больше никто не сможет принять пакет, тк принимающие потоки будут заняты обработкой пришедшихю

???


--------------------
user posted image
PM MAIL   Вверх
Lazin
Дата 25.7.2008, 12:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 5
Всего: 154



В общем случае очередь ничего не даст, так как данные и так буферизуются, то-есть пока их не прочитали они никуда не денутся. 
в случае одного потока, без очереди алгоритм будет такой:  
Код

ожидание ->  пришел пакет -> обработка пакета -> ожидание -> ...

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

а в случае если у нас 2 потока, один принимает пакет из сокета и кладет его в очередь, другой достает оттуда пакеты и обрабатывает:
Код

1-й поток:
ожидание -> захват очереди ->  добавляем пакет в очередь -> освобождение очереди -> сообщение 2-му потоку -> ожидание -> ...
2-й поток:
ожидание сообщения от 1-го потока -> обработка пакета(ов) -> захват очереди -> удаление пакета(ов) из очереди -> освобождение очереди -> ожидание -> ...

если приходит очень много пакетов, 1-й поток будет непрерывно складывать их в очередь, а 2-й поток будет почти непрерывно их обрабатывать...

в общем разницы особой нет... не считая того, что во 2-м случае происходит много лишних действий...
это конечно всего-лишь мое мнение, хотелось бы услышать чье-нибудь еще.. smile 
PM MAIL Skype GTalk   Вверх
REZiaMIX
Дата 25.7.2008, 12:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 346
Регистрация: 3.11.2007

Репутация: нет
Всего: 4



Да , ждем ответа профессионала , всетаки в голове какойто непорядок насчет необработки пакетов во время приема с сети)
и... думаю надо оба варианта обкатать на практике. ИМХО Если GetQueuedCompletionStatus возвращается сразу по приходу пакета в буффер, то падение производительности может быть в 1ом случае меньше , чем с внутренней очередью, но все над тестировать

Это сообщение отредактировал(а) REZiaMIX - 25.7.2008, 12:39


--------------------
user posted image
PM MAIL   Вверх
Torsten
Дата 26.7.2008, 23:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 174
Регистрация: 10.6.2008
Где: Pskov

Репутация: нет
Всего: 7



Цитата(REZiaMIX @  25.7.2008,  10:35 Найти цитируемый пост)
Теперь вопрос : нужно ли создавать лишние потоки под обработку логики(пункт 3)

Сложный вопрос. Мне кажится наиболее эфектнивная обработка получится, если приемом будет заниматся один поток, а обрабатывать данные другие.
Т.е. у тебя например есть некое количество обработчиков запросов. В интерфейс поступает запрос - ты ищещь свободный обработчик (лучше заранеее создовать пулл при запуске, чем создовать их динамически), передаешь обработчику данные запроса. 
Он уже их парсит и чего-то делает с ним, и шлет ответ через интерфейс.
Тут имеет смысл присмотрется к модели - событие и обработчик. Первычеый обработчик - сетевой интерфейс, который отправляет события другим обработчикам (логикам), те обрабатывают запрос и шлют ответ. Это сделает абстракцию и будет легче написать многопоточный код, т.к. он не будет зависить от чего-то конкретного. Просто есть событие и обработчик, а какое и какой обработчик - дело реализации. Отправил событие, обработал - никаких чистых вызовов функций, которые в обычном случае будут сильно связывать обьекты и классы.

--------------------
We have no begining, we have no end. We are infinite.
PM MAIL   Вверх
Lazin
Дата 27.7.2008, 00:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 5
Всего: 154



Мне кажется что это усложнит архитектуру и уменьшит производительность, так как дублируется часть функционала реализованого в рамках winsock. Как это поможет увеличить производительнсть? 
PM MAIL Skype GTalk   Вверх
REZiaMIX
Дата 27.7.2008, 09:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 346
Регистрация: 3.11.2007

Репутация: нет
Всего: 4



В том дело , что я пишу игровой сервер , надо учитывать что клиент должен получить ответ как можно быстрее и при этом сервер должен держать множество соединений.При варианте потока "что принял , то сам и обработал" возможно какойто из клиентов будет ждать своего ответа относительно долго . При варианте что поток принял , положил в стопку , а другие спец-назначенные обработают, может оказаться что потеря производительности окажется более критической , нежели потеря времени в первом случае. У кого еще какие соображения?) Просто возможно найдется человек , прошедший через все это , который разъяснит ситуацию основываясь на своем опыте.

Это сообщение отредактировал(а) REZiaMIX - 27.7.2008, 09:56


--------------------
user posted image
PM MAIL   Вверх
миг
Дата 15.9.2008, 20:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 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.
PM MAIL   Вверх
REZiaMIX
Дата 20.9.2008, 20:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 346
Регистрация: 3.11.2007

Репутация: нет
Всего: 4



Спасибо за помощь , но это не то. Я уже написал что использую порты завершения (MSDN I/O Completion Ports для справки) , что работает быстрее эвентовой системы , да и вопрос не об этом  smile 


--------------------
user posted image
PM MAIL   Вверх
MAKCim
Дата 21.9.2008, 10:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 6
Всего: 207



Цитата(REZiaMIX @  25.7.2008,  10:35 Найти цитируемый пост)
Пишу сервер , который должен выжимать максимум из ресурсов компьютера)

1. использовать неблокирующий I/O
2. использовать общую очередь пакетов с произвольным доступом
3. один поток - аккептор, все остальные (количество CPU - 1 + CONSTANT) - обработчики
CONSTANT зависит от того, будет ли переключение контекта на данной системе быстрее, чем обработка одного пакета
4. все обработчики равномерно распределяются по всей очереди для параллельной обработки запросов
5. аккептор также участвует в обработке пакетов в случае отсутствия событий
вместо очереди можно использовать огромный статический массив дескрипторов с битом свободно/занято и адресом структуры, описывающей соединение
каждый обработчик посредством rand() % COUNT выбирает индекс в этом массиве и направление движения

есть второй вариант, но он специфичен для Linux
будет эффективнее

Добавлено через 13 минут и 15 секунд
Цитата(Lazin @  25.7.2008,  11:17 Найти цитируемый пост)
мало того, можно даже ждать событий от сокета из нескольких потоков 

фигня
может получится так, что один поток захавает все присоединенные сокеты
остальные будут простаивать
такой подход можно использовать, но тогда надо использовать неблокирующий I/O и поток баллансер, который будет поддерживать равномерность количества соединений на каждом потоке
второй вариант - самобаллансировка, когда в случае долгого отсутствия соедениений потоки начинают обрабатывать существующие коннекты

Это сообщение отредактировал(а) MAKCim - 21.9.2008, 10:36


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
MAKCim
Дата 21.9.2008, 10:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 6
Всего: 207



REZiaMIX
кроме всего прочего нужно использовать самый производительный мультиплексор целевой системы
что-то мне кажется, что под Windows, это WaitForSingleObject/MsgWaitForSingleObjects



--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Lazin
Дата 21.9.2008, 11:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 5
Всего: 154



он написал что использует порты завершения, значит IO там неблокирующий smile 
PM MAIL Skype GTalk   Вверх
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.0916 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.