Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2009.04.05;
Скачать: [xml.tar.bz2];

Вниз

Прием большого потока данных по 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.53 MB
Время: 0.007 c
2-1234686924
Roll
2009-02-15 11:35
2009.04.05
добавление нескольких файлов через OpenDialog


15-1233900281
123-ий
2009-02-06 09:04
2009.04.05
Перенос данных из одной БД в другую


15-1233835334
Ega23
2009-02-05 15:02
2009.04.05
Знатоки JavaScript - посоветуйте


2-1234527816
snake-as
2009-02-13 15:23
2009.04.05
Открытие сохраненного проекта


15-1234179927
dark_volk
2009-02-09 14:45
2009.04.05
C++ Кто знает





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский