Рассылка данных от одного сервера к нескольлким клиентам
От: dimchick Украина  
Дата: 14.07.11 10:22
Оценка:
Привет ув All,

Нужен совет. Пишу приложение, которое должно рассылать некоторую информацию (30байт) внутри одного компа нескольлким приложениям (~20). Есть очень жесткие требования к производительности. Процесс передачи не должен занимать больше 5-10 микросекунд.

Сейчас пробую смотреть на Shared Memory в качестве сторейджа для данных. Остановился на том, что не могу найти объект ядра, который бы позволил клиентам спать до наступления изменений в сторейдже и не просыпаться, до тех пор пока не придут новые для него новые данные. Тоесть нужно чтото типа такого:

// On client side
WaitUntilEqual( kernel_object, someVal );

// On server side
Update( kernel_object, new_value );

Если делать это в user-mode, то тогда сильно грузится проц. Пробовал играться с существующими объектами ядра:

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

— С AutoResetEvent обратная фигня — клиент после просыпания должен высталвять этот евент в сигнальное состояние, если есть еще слушающие другие клиента. И потом latency последнего клиента будет сумарным от latency всех предыдущих.

— Семафор тоже не получается применить.

Сейчас буду играться с мультикастом на локале. ИМХО это будет как с пушки по воробьям. Может есть чтоот еще более легковесное?
Re: Рассылка данных от одного сервера к нескольлким клиентам
От: sz36 Россия  
Дата: 14.07.11 21:28
Оценка:
Здравствуйте, dimchick, Вы писали:

D>- ManualResetEvent не подходит потому, что клиент может начать обрабатывать данные по второму кругу и еще нужно както думать, когда его выключать.


Если серверу известно кол-во клиентов, то можно использовать ManualResetEvent вместе с InterlockedExchangeAdd. Сервер прибавляет к значению разделяемой переменной 20 (по числу клиентов) и будит клиентов Event'ом. Каждый клиент вычитывает данные и вычитает из переменной по единичке. Последний клиент понимает, что он последний, по нулевому значению переменной и сбрасывает Event.
Re[2]: Рассылка данных от одного сервера к нескольлким клиен
От: dimchick Украина  
Дата: 15.07.11 06:57
Оценка:
Здравствуйте, sz36, Вы писали:

S>Здравствуйте, dimchick, Вы писали:


D>>- ManualResetEvent не подходит потому, что клиент может начать обрабатывать данные по второму кругу и еще нужно както думать, когда его выключать.


S> Если серверу известно кол-во клиентов, то можно использовать ManualResetEvent вместе с InterlockedExchangeAdd. Сервер прибавляет к значению разделяемой переменной 20 (по числу клиентов) и будит клиентов Event'ом. Каждый клиент вычитывает данные и вычитает из переменной по единичке. Последний клиент понимает, что он последний, по нулевому значению переменной и сбрасывает Event.


Минусов тут два:
1. Клиенты будут просыпаться и в холостую работать, пока все не отработают
2. Если кто-то из клиентов отвалится (упадет процесс), или просто глюк в реализации, то это отразится на остальных клиентах.
Re: Рассылка данных от одного сервера к нескольлким клиентам
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 17.07.11 08:47
Оценка:
Здравствуйте, dimchick, Вы писали:

D>Нужен совет. Пишу приложение, которое должно рассылать некоторую информацию (30байт) внутри одного компа нескольлким приложениям (~20). Есть очень жесткие требования к производительности. Процесс передачи не должен занимать больше 5-10 микросекунд.


Не совсем понятно, что здесь имеется в виду: затраты процессорного времени на отправляющей стороне, интервал между помещением данных "в канал" и началом (завершением?) их чтения получателем, ещё что-то?

D>Сейчас пробую смотреть на Shared Memory в качестве сторейджа для данных. Остановился на том, что не могу найти объект ядра, который бы позволил клиентам спать до наступления изменений в сторейдже и не просыпаться, до тех пор пока не придут новые для него новые данные. Тоесть нужно чтото типа такого:


[...]

D>Сейчас буду играться с мультикастом на локале. ИМХО это будет как с пушки по воробьям. Может есть чтоот еще более легковесное?


Пайпы (pipes) пробовал?

Ещё посмотри в сторону boost::interprocess. Не ахти какая легковесная, но кроссплатформенная и есть много готовых примитивов.

Наконец, есть вот такой, почти классический приём (кстати, применяется в boost::interprocess):

// Client side
void waitForData()
{
  while (!someoneSharedFlag) // Здесь может быть что-то из Interlocked
  {
    Sleep(0); // Пропускаем квант, можно каким-нибудь другим способом
  }
}


Недостатки понятны, конечно: задержка передачи данных в общем не предсказуема и может оказаться равной длительности кванта (миллисекунды), зато надёжно и просто.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[2]: Рассылка данных от одного сервера к нескольлким клиен
От: dimchick Украина  
Дата: 18.07.11 11:00
Оценка:
Здравствуйте, Геннадий Васильев, Вы писали:

ГВ>Здравствуйте, dimchick, Вы писали:


D>>Нужен совет. Пишу приложение, которое должно рассылать некоторую информацию (30байт) внутри одного компа нескольлким приложениям (~20). Есть очень жесткие требования к производительности. Процесс передачи не должен занимать больше 5-10 микросекунд.


ГВ>Не совсем понятно, что здесь имеется в виду: затраты процессорного времени на отправляющей стороне, интервал между помещением данных "в канал" и началом (завершением?) их чтения получателем, ещё что-то?


2-е. Интервал между началом передачи на сервере и завершением приема перед началом обработки на клиенте.

ГВ>Пайпы (pipes) пробовал?


Pipes — это соединение точка-точка. При увеличении кол-ва клиентов, работа по нотификации клиентов будет возрастать. Надо будет думать о разпаралеливании процесса нотификации от основной работы. А это дополнительные издержки синхронизации потоков.

ГВ>Ещё посмотри в сторону boost::interprocess. Не ахти какая легковесная, но кроссплатформенная и есть много готовых примитивов.


Смотрел. Хотел заюзать upgradable mutex и conditional variable. К сожалению они друг с другом не работают.
На счет портабельности — это клево, но не приоритет. Целевая платформа у меня Win Server 2008 x64.


ГВ>Наконец, есть вот такой, почти классический приём (кстати, применяется в boost::interprocess):


ГВ>
ГВ>// Client side
ГВ>void waitForData()
ГВ>{
ГВ>  while (!someoneSharedFlag) // Здесь может быть что-то из Interlocked
ГВ>  {
ГВ>    Sleep(0); // Пропускаем квант, можно каким-нибудь другим способом
ГВ>  }
ГВ>}
ГВ>


ГВ>Недостатки понятны, конечно: задержка передачи данных в общем не предсказуема и может оказаться равной длительности кванта (миллисекунды), зато надёжно и просто.


Sleep(0) уже не такой как раньше. Раньше он проц не грузил. Сейчас он грузит проц на 100%.

If you specify 0 milliseconds, the thread will relinquish the remainder of its time slice but remain ready.

Re: Рассылка данных от одного сервера к нескольлким клиентам
От: uhh  
Дата: 18.07.11 11:13
Оценка:
Здравствуйте, dimchick, Вы писали:

<skip>
D>Сейчас пробую смотреть на Shared Memory в качестве сторейджа для данных. Остановился на том, что не могу найти объект ядра, который бы позволил клиентам спать до наступления изменений в сторейдже и не просыпаться, до тех пор пока не придут новые для него новые данные. Тоесть нужно чтото типа такого:
<skip>

http://en.wikipedia.org/wiki/Dekker's_algorithm
Re: Рассылка данных от одного сервера к нескольлким клиентам
От: dkotov  
Дата: 25.07.11 21:28
Оценка:
Каково решение?
Отпишитесь,
... << RSDN@Home 1.2.0 alpha 5 rev. 1526>>
Re[3]: Рассылка данных от одного сервера к нескольлким клиен
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 26.07.11 01:45
Оценка:
Здравствуйте, dimchick, Вы писали:

ГВ>>Пайпы (pipes) пробовал?


D>Pipes — это соединение точка-точка. При увеличении кол-ва клиентов, работа по нотификации клиентов будет возрастать. Надо будет думать о разпаралеливании процесса нотификации от основной работы. А это дополнительные издержки синхронизации потоков.


Сдаётся, что тебе так и так придётся распараллеливать раздачу сообщений и основную работу. А пайпы хороши тем, что их можно использовать как объект синхронизации, т.е. приёмнику не понадобится терять time slice в ожидании.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.