MyTetra Share
Делитесь знаниями!
Время создания: 12.02.2020 16:09
Текстовые метки: lwip
Раздел: Electronics - Microcontrollers - LWIP

Алгоритм Нейгла (был такой перец, который предложил специально задерживать данные для увеличения пропускной способности сети. При этом подразумевается, что данные небольшого размера не передаются сразу в сеть, а накапливаются в буфере и передаются только тогда, когда буфер полон).

Поэтому для максимальной пропускной способности его надо отключать. Но...

В LWIP есть следующая падляна - количество пакетов в окне для подтверждения равно 2. И параметр этот не меняется в настройках.


Как это выглядит:

Установили соединение - вызвался SENT, готовим данные.

Если забить буфер полностью (в настройках стека это (1500-40)*2 байт), то LwIP пошлет 2 пакета в окне, равном двум пакетам.

И любая реализация TCP (пробовал в форточках и Android) сгенерирует ACK в конце окна (т.е. после второго пакета сразу). Он будет обработан LwIP и снова вызовется SENT для подготовки новых данных.

Но если забить буфер, скажем, на 1000 байт или на 500 байт, то уйдет одни пакет (а окно по-прежнему 2 пакета). И на приемной стороне ACK будет сформирован только по истечении таймаута 0.2-0.3сек.

В случае реализации modbus у меня паузы после каждого пакета. И забивать буфер полностью просто нечем. Эта шляпа тупо потому, что lwIP не умеет настраивать размер окна (есть в доке).

А если применить финт с биением данных на 2 пакета принудительно (для первого отключаем ожидание ACK, второй нормальный), то получаем ACK немедленно и скорость обмена доходит до

10-25 Mbit/s.



Если написать так:

tcp_write(pcb, DirLLine, WrPntr, 0); //"нормальный" вариант

Скорость на малых пакетах около 300 Б/сек и ожидание ACK

на каждом пакете от Форточек по 0.3 сек.

Если написать так:

pcb->flags |= TF_NODELAY;
tcp_write(pcb, DirLLine, WrPntr, 0);

Скорость на малых пакетах около 600 Б/сек и ожидание ACK

на каждом втором пакете от Форточек по 0.3 сек.

Если же написать так:

pcb->flags |= TF_NODELAY;
tcp_write(pcb, DirLLine1, WrPntr1, 0);
tcp_output(pcb);
tcp_write(pcb, DirLLine2, WrPntr2, 0);

То имеем ACK на каждую пару пакетов мгновенно и вызывается sent строго после получения ACK на вручную сформированное "окно". Скорость 500-700 кБ/сек (в тысячу раз выше!) на тех же самых малых пакетах.


А здесь есть как отключать этот алгоритм Нейгла - вызовом функций:

tcp_nagle_enable ( struct tcp_pcb * aPcb ); // enable the nagle algorithm

tcp_nagle_disable ( struct tcp_pcb * aPcb ); // disable the nagle algorithm

tcp_nagle_disabled ( struct tcp_pcb * aPcb ); // return true if the algorithm is not enabled





Так же в этом разделе:
 
MyTetra Share v.0.53
Яндекс индекс цитирования