Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.04.05;
Скачать: CL | DM;

Вниз

Прием большого потока данных по UDP   Найти похожие ветки 

 
MBo ©   (2008-01-31 07:26) [0]

Задача следующая - некий спецдевайс передает по сети по протоколу UDP данные (видеопоток), порядка 11 мегабайт в секунду, пакет 770 байт - строка. Прием занимает очень значительную часть процессорного времени (применяется WSA-функции + RecvFrom, также пробовал использовать Indy и ICS), причем, если программа занимается еще чем-то, то пакеты, приходящие  в этот момент, теряются. Например, если после приема кадра отрисовывать его, то несколько первых строк следующего кадра не принимаются.

Можно ли предпринять какие-то меры к улучшению ситуации?
C сетями ранее не работал, так что могут помочь любые идеи.


 
ketmar ©   (2008-01-31 08:53) [1]

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

%-)


 
Сергей М. ©   (2008-01-31 08:55) [2]


> если программа занимается еще чем-то


Сделай так чтобы она занималась только этим и ничем более


 
MBo ©   (2008-01-31 09:11) [3]

т.е., такое потребление ресурсов и потери пакетов -  это нормальная ситуация?


 
Anatoly Podgoretsky ©   (2008-01-31 09:13) [4]

> MBo  (31.01.2008 07:26:00)  [0]

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


 
ketmar ©   (2008-01-31 09:26) [5]

>[3] MBo ©(31.01.08 09:11)
для UDP — да. оно ж лежит в буфере только пока новое не притащат. да и не факт, что старое дойдёт. потеряется по дороге — и всё.


 
MBo ©   (2008-01-31 09:43) [6]

>11 мегабайт в секунду можно передать только в тепличных условиях
судя по снифферу, в стомегабитной локалке до машины пакеты доходят все, да и если программа не занимается обсчетом/отрисовкой, то она их все принимает.

>оно ж лежит в буфере
насчет размера буфера я пока не разобрался. В ICS и в Indy можно выставить размер буфера, который, как я понимаю, отвечает за максимальный размер пакета. А есть ли еще какие-то возможности указать сетевой подсистеме винды, чтобы побольше непрочитанных еще пакетов накапливалось?


 
ketmar ©   (2008-01-31 09:48) [7]

>[6] MBo ©(31.01.08 09:43)
а максимальный размер пакета, афаир, всё равно 64к. и очереди в UDP нет. не успал поймать — кранты тому, что лежало.


 
Сергей М. ©   (2008-01-31 09:51) [8]


> MBo ©   (31.01.08 09:43) [6]


см. SetSockOpt(..SO_RCVBUF..)

Но это не спасет, если выборка из буфера стабильно медленней, чем запись в буфер.


 
Anatoly Podgoretsky ©   (2008-01-31 09:52) [9]

> MBo  (31.01.2008 09:43:06)  [6]

судя по снифферу, в стомегабитной локалке до машины пакеты доходят все, да и если программа не занимается обсчетом/отрисовкой, то она их все принимает.

Этого не должно быть, что то неправильно, в программе конечно.
Но я бы все таки задумался 11 мегабайт это на пределе возможностей 100 мб сети. Не каждая машина и сетевая карта в состоянии обеспечить.
А для процессора это ничто, доли процента.

Но сам протокол UDP не обеспечивает гарантированой доставки. Размер пакета надо снижать до минимума и делать буферизации, часть буферизации делает система.


 
Сергей М. ©   (2008-01-31 09:53) [10]


> MBo ©


Выноси транспортную логику в отдельный поток, повысь ему приоритет до разумных пределов.


 
ketmar ©   (2008-01-31 09:58) [11]

>[10] Сергей М. ©(31.01.08 09:53)
так нечестно, я это уже посоветовал! %-)


 
MBo ©   (2008-01-31 10:11) [12]

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


 
ketmar ©   (2008-01-31 10:19) [13]

>[12] MBo ©(31.01.08 10:11)
ну, ты учти, что поток не может быть особо приоритетней приложения. подними ещё приоритет самому приложению. другим потокам приоритет поспускай.

а лучше таки накапливай где-то на отдельном сервере и с него уже забирай. и на гигабитке, желательно.


 
MBo ©   (2008-01-31 10:37) [14]

> лучше таки накапливай где-то на отдельном сервере и с него уже забирай. и на гигабитке, желательно

Увы, не получится - в реальности будут полевые условия, железка - кабель - ноутбук.


 
Сергей М. ©   (2008-01-31 10:54) [15]


> MBo ©   (31.01.08 10:37) [14]


Ты бы код своего транспортного алгоритма показал ..


 
ketmar ©   (2008-01-31 11:23) [16]

>[15] Сергей М. ©(31.01.08 10:54)
я подозреваю, что ничего там такого нет. тупо сетка успевает впритык.

однако ж глянуть не помешает в любом случае, да.


 
MBo ©   (2008-01-31 13:52) [17]


инициализация в конструкторе потока

 if WSAStartup($0202, WSAD) <> 0 then
   Exception.Create("WSAStartup Error");
 Ud := Socket(AF_INET, Sock_Dgram, 0);
 if INVALID_SOCKET  = Ud then
   Exception.Create("Socket Create Error");
 Addr.sin_family := PF_Inet;
 Addr.sin_addr.S_addr := Inet_Addr("0.0.0.0");
 Addr.sin_port := HtoNS(FPort);
 FillChar(Addr.sin_zero, SizeOf(Addr.sin_zero), 0);
 if Bind(UD, Addr, SizeOf(Addr)) = Socket_Error then
   Exception.Create("Socket Bind Error");

поточная функция

 Len := 770;
 while not Terminated do begin
   FromLen := SizeOf(TSockAddr);
   WSResult := RecvFrom(UD, LineBuf, Len, 0, Addr, FromLen);
   Wrd := Swap(PWord(@LineBuf[0])^);
   LineNum := Wrd and $3FF;
   CadrNum := (Wrd shr 12) and 1;

   if LineNum = 0 then begin
     Inc(FrameCount);
     PostMessage(Form3.Handle, WM_USER, FrameCount and $F, CadrNum xor 1);
   end;

   Move(LineBuf[2], Buf[CadrNum, LineNum, 0], Wdt);
 end;

Buf - 2 массива, один заполняется, предыдущий отрисовывается

в обработчике WM_USER отрисовка
 SetDiBitsToDevice(Canvas.Handle, 0, 0, Wdt, Hgt, 0, 0, 0, Hgt,
   @Buf[M.LParam], PBitmapInfo(@Info)^, DIB_RGB_COLORS);



 
ketmar ©   (2008-01-31 14:11) [18]

у-у-у. PostMessage… да ещё и SetDiBits… есть (ничем не обоснованое, правда) мнение, что:
эту фигню надо тихонько совать в буфер моска сразу по получении. раз.
наладить frame skiping, если не успевает отрисоваться, а в буферг гадит.
рисовать директиксом на оверлеях (тут, возможно, вылезут тормоза с преобразованием цветовых пространств, искать карты, оверлеи на которых потянут rgb).

да, это: присылает, как я понял, не твоя программа, так что вправить моск именно ей никак?


 
MBo ©   (2008-01-31 14:32) [19]

>PostMessage… да ещё и SetDiBits
Отрисовку, временно забыв об опасностях обращения к основному окну из доп. потока, можно вести и прямо из потока, ничего принципиально это не меняет.
SetDiBitsToDevice  - оказался в данном случае наименее затратный способ из испытанных (альтернатива, например - формирование битмапа, происходит дольше)

насчет DirectX - еще не прорабатывал, побоялся затрат времени на преобразование цветов.


 
Сергей М. ©   (2008-01-31 15:16) [20]


> один заполняется, предыдущий отрисовывается


А если отрисовка медленней заполнения ?
Подумай ...


 
Anatoly Podgoretsky ©   (2008-01-31 15:41) [21]

> MBo  (31.01.2008 14:32:19)  [19]

Для испытания временно отключи отрисовку.


 
MBo ©   (2008-01-31 15:47) [22]

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

В данном случае хватает двух буферов.
14400 пакетов в секунду, 0.07 мс один пакет
Отрисовка сначала у меня происходила более сложно, и занимала 3-4 мс, это по времени порядка 60 пакетов, около 40 КБ данных.
Визуально - если критерий отрисовки - приход нулевой строки, то в районе 20-50 строк было много выпавших.
Сейчас отрисовка быстрее, и артефактов на моей машине (Athlon 3500) практически нет, но на машинах вдвое медленнее - все-таки появляются.

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

(С цифрового видеограббера без проблем принимаю, достаточно сложным образом обрабатываю и отрисовываю втрое-вчетверо больший поток)


 
Anatoly Podgoretsky ©   (2008-01-31 16:28) [23]

> MBo  (31.01.2008 15:47:22)  [22]

100 мегабит это ничто для процессора, проблема не в количестве, а в другом месте.


 
MBo ©   (2008-01-31 18:31) [24]

>а в другом месте.
Вот и хочется понять, что это за место ;)


 
Anatoly Podgoretsky ©   (2008-01-31 20:05) [25]

> MBo  (31.01.2008 18:31:24)  [24]

Э, ну ты даешь, программа то у тебя, задача сложная, явно не для форума, да и сеть у тебя работает за пределами возможностей. 11 мб не любая сеть обеспечит, а еще твоя обработка.
Так что придется тебе самому грызть.


 
DVM ©   (2008-01-31 23:58) [26]


> MBo ©

А что за девайс такой? IP камера? Просто знакомая мне тематика.


 
DVM ©   (2008-02-01 00:01) [27]


> Собственно, интересно - так и должна машина нагружаться
> при приеме из сети потока такой интенсивности, или руки
> нужно выпрямлять?

Нет, не должна. Вся нагрузка возникает, если в принимаемом потоке надо. что то искать, выцеплять, декодировать. Отрисовка это тоже мелочи.


 
Slym ©   (2008-02-01 04:51) [28]

procedure x;
type
 TLineRec=packed record
   Info:word;
   Data:array[0..192*4-1] of char;
 end;
var
 Bitmap:TBitmap;
 Line:TLineRec;
 FromLen,LineNum,CadrNum,Wrd:integer;
 WSResult:integer;
 UD:TSocket;
 Addr:TSockAddr;
begin
 Bitmap:=TBitmap.Create;
 try
   Bitmap.PixelFormat:=pf32bit;
   Bitmap.Width:=192;
   Bitmap.Height:=192;
   while not Terminated do begin
     FromLen := SizeOf(TSockAddr);
     WSResult := RecvFrom(UD, Line, SizeOf(Line), 0, Addr, FromLen);
     if WSResult<>SizeOf(Line) then continue;
     Wrd := Swap(Line.Info);
     LineNum:= Wrd and $3FF;
     if (LineNum>-1) and (LineNum<Bitmap.Height) then
       Move(Line.Data,Bitmap.ScanLine[LineNum]^,SizeOf(Line.Data));

     if LineNum = Bitmap.Height-1 then
     begin
       Inc(FrameCount);
       FCanvas.Lock;
       try
         FCanvas.Draw(0,0,Bitmap);
       finally
         FCanvas.Unlock;
       end;
     end;
   end;
 finally
   Bitmap.Free;
 end;
end;


 
ага   (2008-02-03 11:46) [29]

2 MBo ©

WSARecv c кучей буферов сразу под весь кадр не пробовал? Те буфер один, но разбит на несколько, по числу строк.

Синхронизацию сообщениями я бы выкинул. Как и многопоточность, скоре всего, использовал бы асинхронный режим. В любом случае, синхронизация здесь - лишние потери, имхо. Два буфера, один рисуется, второй принимается. Буферы переключает "приемник", а по WM_PAINT выводится "рисуемый", независимо от того, было ли обновление.

Как гипотеза - может вывод через DirectX побыстрее будет. Не знаю, не спец.


 
Slym ©   (2008-02-04 05:13) [30]

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



Страницы: 1 вся ветка

Текущий архив: 2009.04.05;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.019 c
2-1234282835
Dr. Genius
2009-02-10 19:20
2009.04.05
Непонятки с WM_TIMECHANGE


15-1233787788
Германн
2009-02-05 01:49
2009.04.05
Телефон, телефонный кабель и RJ разъём


2-1234971867
ford
2009-02-18 18:44
2009.04.05
TlistView Has no parent control


3-1218631083
gentle
2008-08-13 16:38
2009.04.05
как отобразить в dbgrid результат выполнения ....


10-1153825601
AlexeyMir
2006-07-25 15:06
2009.04.05
Регистрация ActX библиотеки из своей программы