Проблемы с производительностью при использовании необработанного TCP API lwIP

Я использую lwIP, чтобы добавить в свою систему сетевые функции. На своей платформе я построил буфер, который хочу отправлять каждый раз, когда он заполнится. Это может произойти довольно быстро. Система напрямую подключена к коммутатору в частной локальной сети. Первоначально отправка данных имела очень большой промежуток времени между 2 секундами. Вдобавок пакеты имели размер 720 байт, если мне не изменяет память. Используемый буфер в настоящее время имеет емкость около 20000 байт, и я могу решить увеличить ее в будущем. Сеть имеет скорость 100 Мбит, и я хотел бы приблизиться к этим скоростям на своей платформе.

В поисках причины медленных скоростей я остановился на конфигурации lwIP. До этого я переделал свой механизм отправки. Я использую необработанный lwIP API и в настоящее время пишу данные следующим образом:

tcp_write(<pcb>, (const void*) data, <bytes>, TCP_WRITE_FLAG_COPY);
//<bytes> is at most tcp_sndbuf(<pcb>)

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

Я немного поигрался с настройками в lwIP, и мне показалось, что это немного изменилось. Я думаю, что размер окна особенно важен, хотя я не совсем уверен. На данный момент я значительно увеличил размер окна, и хотя я получаю пачку пакетов с интервалом около 2 мс (вместо 2 с!), За ней следует длительный период «ничего», а затем снова пачка пакетов. Я хочу, чтобы он непрерывно отправлял со скоростью, на которую он должен быть способен, которая должна составлять максимум 100 Мбит, но по крайней мере 10 Мбит - это не странно, верно?

Я загрузил wirehark, чтобы посмотреть, что происходит.

192.168.1.26 - мой настольный компьютер под управлением Windows. 192.168.1.192 - это встроенная система, использующая lwIP.

Сначала я отправляю запрос запуска с рабочего стола в систему lwIP, сообщая системе, что она должна начинать отправку буфера каждый раз, когда он заполняется. Если это актуально, это соответствующая часть трассы:

5    2.007754    192.168.1.26    192.168.1.192    TCP    61    [TCP segment of a reassembled PDU]
6    2.008196    192.168.1.192    192.168.1.26    TCP    60    patrolview > afs3-fileserver [SYN] Seq=0 Win=65535 Len=0 MSS=1400
7    2.226238    192.168.1.192    192.168.1.26    TCP    60    afs3-fileserver > 50015 [ACK] Seq=1 Ack=8 Win=65528 Len=0
13    4.976858    192.168.1.192    192.168.1.26    TCP    60    patrolview > afs3-fileserver [ACK] Seq=1 Ack=1 Win=65535 Len=0
22    6.976572    192.168.1.192    192.168.1.26    TCP    60    [TCP segment of a reassembled PDU]
23    7.177903    192.168.1.26    192.168.1.192    TCP    54    50015 > afs3-fileserver [ACK] Seq=8 Ack=2 Win=64399 Len=0

Я считаю, что это нормально, хотя и не уверен. В любом случае, после этого происходит фактическая отправка. Соответствующий график выглядит следующим образом. Время начала - 207.992115, которое следует рассматривать как время начала. Ожидаемая разница между этим и 7.177903:

2578    207.992115    192.168.1.192    192.168.1.26    Gryphon    1422    - Invalid -
2581    208.194336    192.168.1.26    192.168.1.192    TCP    54    afs3-fileserver > patrolview [ACK] Seq=1 Ack=1369 Win=64400 Len=0
2582    208.195880    192.168.1.192    192.168.1.26    TCP    1422    [TCP segment of a reassembled PDU]
2583    208.197035    192.168.1.192    192.168.1.26    TCP    1422    [TCP segment of a reassembled PDU]
2584    208.197134    192.168.1.26    192.168.1.192    TCP    54    afs3-fileserver > patrolview [ACK] Seq=1 Ack=4105 Win=64400 Len=0
2585    208.198712    192.168.1.192    192.168.1.26    TCP    1422    [TCP segment of a reassembled PDU]
2586    208.199867    192.168.1.192    192.168.1.26    TCP    1422    [TCP segment of a reassembled PDU]
2587    208.199965    192.168.1.26    192.168.1.192    TCP    54    afs3-fileserver > patrolview [ACK] Seq=1 Ack=6841 Win=64400 Len=0
2588    208.200927    192.168.1.192    192.168.1.26    TCP    1314    [TCP segment of a reassembled PDU]
2590    208.397469    192.168.1.26    192.168.1.192    TCP    54    afs3-fileserver > patrolview [ACK] Seq=1 Ack=8101 Win=63140 Len=0

Похоже, что сейчас я отправляю сообщения быстрее, чем настольный компьютер ACKing. Трафик после графика выше отображается в виде черных полос и выглядит так:

2591    208.399051    192.168.1.192    192.168.1.26    TCP    1422    [TCP Previous segment lost] [TCP segment of a reassembled PDU]
2592    208.399136    192.168.1.26    192.168.1.192    TCP    54    [TCP Dup ACK 2590#1] afs3-fileserver > patrolview [ACK] Seq=1 Ack=8101 Win=63140 Len=0
2593    208.400208    192.168.1.192    192.168.1.26    Gryphon    1422   
2594    208.400285    192.168.1.26    192.168.1.192    TCP    54    [TCP Dup ACK 2590#2] afs3-fileserver > patrolview [ACK] Seq=1 Ack=8101 Win=63140 Len=0
2595    208.401361    192.168.1.192    192.168.1.26    Gryphon    1422    - Invalid -
2596    208.401445    192.168.1.26    192.168.1.192    TCP    54    [TCP Dup ACK 2590#3] afs3-fileserver > patrolview [ACK] Seq=1 Ack=8101 Win=63140 Len=0
2597    208.402425    192.168.1.192    192.168.1.26    Gryphon    1314   
2598    208.402516    192.168.1.26    192.168.1.192    TCP    54    [TCP Dup ACK 2590#4] afs3-fileserver > patrolview [ACK] Seq=1 Ack=8101 Win=63140 Len=0
2599    208.403588    192.168.1.192    192.168.1.26    Gryphon    1422    [TCP Fast Retransmission] Command response
2600    208.403685    192.168.1.26    192.168.1.192    TCP    54    afs3-fileserver > patrolview [ACK] Seq=1 Ack=14833 Win=64400 Len=0
2605    209.992237    192.168.1.192    192.168.1.26    Gryphon    1422    - Invalid -
2607    210.200219    192.168.1.26    192.168.1.192    TCP    54    afs3-fileserver > patrolview [ACK] Seq=1 Ack=16201 Win=63032 Len=0
2608    210.201819    192.168.1.192    192.168.1.26    Gryphon    1422    [TCP Previous segment lost] - Invalid -
2609    210.201903    192.168.1.26    192.168.1.192    TCP    54    [TCP Dup ACK 2607#1] afs3-fileserver > patrolview [ACK] Seq=1 Ack=16201 Win=63032 Len=0
2609    210.201903    192.168.1.26    192.168.1.192    TCP    54    [TCP Dup ACK 2607#1] afs3-fileserver > patrolview [ACK] Seq=1 Ack=16201 Win=63032 Len=0
2611    210.203070    192.168.1.26    192.168.1.192    TCP    54    [TCP Dup ACK 2607#2] afs3-fileserver > patrolview [ACK] Seq=1 Ack=16201 Win=63032 Len=0
2955    345.001223    192.168.1.192    192.168.1.26    Gryphon    1422    [TCP Retransmission]

Теперь, после этого момента, есть огромная задержка, которую я не могу объяснить. Следующие пакеты прибывают через 345 секунд, разница в 135 секунд. (хотя в большинстве случаев он был немного меньше, но все же слишком высок) Он начинается следующим образом:

2955    345.001223    192.168.1.192    192.168.1.26    Gryphon    1422    [TCP Retransmission]
2958    345.001707    192.168.1.26    192.168.1.192    TCP    54    afs3-fileserver > patrolview [ACK] Seq=1 Ack=20305 Win=64400 Len=0
2959    345.003336    192.168.1.192    192.168.1.26    TCP    1422    [TCP segment of a reassembled PDU]
2960    345.004395    192.168.1.192    192.168.1.26    TCP    1314    [TCP segment of a reassembled PDU]
2961    345.004494    192.168.1.26    192.168.1.192    TCP    54    afs3-fileserver > patrolview [ACK] Seq=1 Ack=22933 Win=64400 Len=0

и т.п.

Позже возникают аналогичные проблемы, хотя указанная задержка короче. Мой вопрос: как я могу решить проблему медленной отправки с моей платформы и как мне настроить мои настройки lwIP, чтобы ожидать достойных / хороших результатов? Я хочу отправлять данные на высокой скорости. (моя сеть способна на 100 Мбит / с, чем ближе, тем лучше) Я думаю, что в настоящее время полностью испортил свои настройки, но я не уверен, как настроить их для своих нужд. Вот некоторые (надеюсь) соответствующие настройки из моего lwipopts.h

файл:

#define MEM_SIZE                        65000
#define PBUF_POOL_SIZE                  1024
#define IP_FRAG_USES_STATIC_BUF         0
#define TCP_WND                         65535
#define TCP_MSS                         1400
#define TCP_SND_BUF                     65535
#define PBUF_POOL_BUFSIZE               LWIP_MEM_ALIGN_SIZE(1528)
#define LWIP_TCP_KEEPALIVE              1
#define LWIP_SO_RCVTIMEO                1

person Arnold4107176    schedule 24.05.2012    source источник
comment
Есть ли где-то между этими хостами сеть Wi-Fi?   -  person This    schedule 24.05.2012
comment
Между ними нет сети Wi-Fi. Система lwIP подключена к коммутатору, к которому подключены два других компьютера. (стандартные рабочие столы с окнами) Один из них - мой собственный, который используется для приема и отправки данных в систему lwIP.   -  person Arnold4107176    schedule 24.05.2012


Ответы (1)


Я столкнулся с аналогичными проблемами, используя beaglebone и следующую настройку

#define MEM_SIZE                        (1024 * 1024) /* 1MiB */
#define MEMP_NUM_PBUF                   1024
#define MEMP_NUM_TCP_PCB                32
#define PBUF_POOL_SIZE                  1024
#define TCP_MSS                         1460
#define TCP_WND                         (4*TCP_MSS)
#define TCP_SND_BUF                     65535
#define TCP_OVERSIZE                    TCP_MSS
#define TCP_SND_QUEUELEN                512
#define MEMP_NUM_TCP_SEG                512

Используя функцию опроса tcp_sent, я в основном проверил, сколько байтов у меня есть в буфере, и сразу же заполнил их в самой функции опроса другими образцами. Это было для проверки всего

Я был очень удивлен, что Wire Shark показывал пакеты пакетов примерно в течение нескольких миллисекунд, а затем 700 мс ничего.

Заглянув глубоко в стек, я обнаружил, что это происходит точно в тот момент, когда отправлено 65535 байт (или примерно так).

Все это решило ОТКЛЮЧЕНИЕ ПРОВЕРКИ ВЕРСИЯ ПАМЯТИ

Посмотрите в своем lwipopts.h, случайно ли вы где-то не определяете:

#define MEMP_SANITY_CHECK 1

Если да, удалите эту строку или установите ее на ноль. Таким образом, моя производительность отправки пакетов не увеличилась (у меня все еще около 11 Мбит при передаче данных на максимальной скорости), но общая пропускная способность значительно увеличилась, поскольку время между двумя отправленными пакетами теперь постоянно и занимает примерно 100 мкс.

Следует отметить, что это все еще не решает проблему наличия только 11 МБит на линии 100 МБит, полностью выделенной только для этого оборудования.

person David Belohrad    schedule 21.03.2013