реклама на сайте
подробности

 
 
> Вопрос по LwIP, Скорость отправки
Petr_
сообщение Mar 15 2016, 18:12
Сообщение #1





Группа: Участник
Сообщений: 14
Регистрация: 15-03-16
Пользователь №: 90 876



Передаю большой файл.
Использую цепочку колбеков, как и задумано в lwIP.
Но заполняю буфер передачи не полностью(узнаю из tcp_sndbuf(pcb); ).
Далее вызываю tcp_write(pcb, Data_Bf, wMaxPut, 0); и завершаю функцию.
Скорость никакущая.
Смотрю что идет по сетке - FTP клиент не посылает ACK добрых 0,3 сек.
Крепко думаю - доходит, что размер окна равен 2, а пакет уходит 1.
Рою сеть.
Нахожу вариант:
Код:
Код
    pcb->flags |= TF_NODELAY;                                   //отключаем  Nagle
    tcp_write(pcb, Data_Bf, wMaxPut >> 2, 1);                   //первый пакет
    tcp_output(pcb);                                            //передать что влезло
    //второй пакет
    tcp_write(pcb, &Data_Bf[wMaxPut >> 2], wMaxPut-(wMaxPut >> 2), 1);
    tcp_output(pcb);                                            //передать что влезло (опционально)

ACK сразу вываливаются на каждую пару пакетов и скорость вырастает в сотни раз. Здорово...
Только решение кривое.
Можно конечно набивать буфер под завязку
(как криво и не полностью сделано в WEB сервере ST).
Но это крайне неудобно.
Бить данные всегда на 2 куска - тоже левизна.

Кто то знает нормальное решение?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
romas2010
сообщение Mar 15 2016, 19:50
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 63
Регистрация: 25-11-11
Пользователь №: 68 515



Цитата(Petr_ @ Mar 15 2016, 21:12) *
Передаю большой файл.
Использую цепочку колбеков, как и задумано в lwIP.
Но заполняю буфер передачи не полностью(узнаю из tcp_sndbuf(pcb); ).
Далее вызываю tcp_write(pcb, Data_Bf, wMaxPut, 0); и завершаю функцию.
Скорость никакущая.
.....
Кто то знает нормальное решение?


Ну насколько я понял из написанного,то вы сами и предложили нормальное решение,отключив алгоритм Нейгла(был такой перец,который предложил специально задерживать данные для увеличения пропускной способности сети.При этом подразумевается,что данные небольшого размера не передаются сразу в сеть,а накапливаются в буфере,и передаются только тогда,когда буфер полон)
Go to the top of the page
 
+Quote Post
Petr_
сообщение Mar 15 2016, 20:11
Сообщение #3





Группа: Участник
Сообщений: 14
Регистрация: 15-03-16
Пользователь №: 90 876



Цитата(romas2010 @ Mar 15 2016, 19:50) *
Ну насколько я понял из написанного,то вы сами и предложили нормальное решение,отключив алгоритм Нейгла(был такой перец,который предложил специально задерживать данные для увеличения пропускной способности сети.При этом подразумевается,что данные небольшого размера не передаются сразу в сеть,а накапливаются в буфере,и передаются только тогда,когда буфер полон)


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

Установили соединение - вызвался SENT, готовим данные.
Если забить буфер полностью (в настройках стека это (1500-40)*2 байт)
то LwIP пошлет 2 пакета в окне равном 2 пакета.
И любая реализация TCP (пробовал в форточках и Android)
сгенерирует ACK в конце ОКНА (т.е. после второго пакета сразу)
Он будет обработан LwIP и вызовется моя SENT для подготовки новых данных.
Но если забить буфер скажем на 2000 байт или на 500 байт,
то уйдет ОДИН пакет(а окно по прежнему - 2 пакета). И на приемной стороне ACK
будет сформирован только по истечении таймаута 0.2-0.3сек.
Скажем я делаю modbus - у меня паузы будут после каждого пакета.
И забивать буфер полностью мне просто нечем.
Тупо потому, что lwIP не умеет настраивать размер окна(есть в доке).
А если применить финт с биением данных на 2 пакета принудительно (для первого отключаем ожидание ACK, второй нормальный)
то получаем ACK немедленно и скорость обмена доходит до
10-25 тыс. туда/обратно в секунду.

Просто решение корявое, хотя и рабочее. Потому спрашиваю.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Mar 15 2016, 20:32
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Petr_ @ Mar 15 2016, 23:11) *
для первого отключаем ожидание ACK, второй нормальный

В вашем примере Nagle отключается не только для первого пакета, а вообще для данного соединения.
Go to the top of the page
 
+Quote Post
Petr_
сообщение Mar 15 2016, 20:54
Сообщение #5





Группа: Участник
Сообщений: 14
Регистрация: 15-03-16
Пользователь №: 90 876



Цитата(aaarrr @ Mar 15 2016, 20:32) *
В вашем примере Nagle отключается не только для первого пакета, а вообще для данного соединения.


Это не так в реале!
ACK ожидается для 2-го пакета. Это вариант из Сети.
Я посмотрел исходники. Это имнно так - флаг убирается для новых пакетов (согласно дефолтным установкам)
Есть еще вариант - допилить lwIP на предмет работы с окнами.
Но тогда станет невозможным легкий апгрейд, если он когда то выйдет...
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Mar 15 2016, 21:09
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Petr_ @ Mar 15 2016, 23:54) *
Я посмотрел исходники. Это имнно так - флаг убирается для новых пакетов (согласно дефолтным установкам)

Где именно он убирается?
Go to the top of the page
 
+Quote Post
Petr_
сообщение Mar 16 2016, 07:57
Сообщение #7





Группа: Участник
Сообщений: 14
Регистрация: 15-03-16
Пользователь №: 90 876



Цитата(aaarrr @ Mar 15 2016, 21:09) *
Где именно он убирается?


Возможно Вы и правы. Я не нашел снова этого места.
Но наблюдения за сетью не оставляют вариантов!
Стек действительно ждет ACK после второго пакета в моем примере и
только после этого вызывает снова sent.

Если написать так:
Код
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 кБ/сек (в тысячу раз выше!)
на тех же самых малых пакетах.

Так что проблема видна четко и явно.
Решение как то мне не нравится. Хотя видимо хорошо, что есть и такое.
Обновление стека не было с 12-го года...

Сообщение отредактировал Petr_ - Mar 16 2016, 07:59
Go to the top of the page
 
+Quote Post
AleksBak
сообщение Mar 16 2016, 18:01
Сообщение #8


Частый гость
**

Группа: Участник
Сообщений: 132
Регистрация: 6-02-16
Из: г. Баку
Пользователь №: 90 364



Цитата(Petr_ @ Mar 16 2016, 11:57) *
...
Так что проблема видна четко и явно.
Решение как то мне не нравится. Хотя видимо хорошо, что есть и такое.
Обновление стека не было с 12-го года...

А здесь есть как отключать этот алгоритм Нейгла - вызовом функций:
Код
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

посмотрите там. Вроде там тоже самое, что Вы и делали и делается. Похоже на самом деле, что-то продолжается в этом lwip исправляться и пр. Я склонировал себе и надо бы сравнить как-нибудь. Похоже, что реально бардак, иначе не скажешь, с доками и сайтами у этого lwip. Есть wiki и вроде официальная, а там последняя версия 1.3.0 (?) Ссылка на один сайт (похоже ихний шведский какой-то) вообще уже не работает. sm.gif) Бесплатный сыр он такой. Еще нашел пару ссылок про упоминание lwip + Nagle (можете тоже сами найти если нужно, но там ничего такого).
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Petr_   Вопрос по LwIP   Mar 15 2016, 18:12
|- - alag57   Цитата(Petr_ @ Mar 16 2016, 12:57) Обновл...   Mar 16 2016, 14:14
||- - Petr_   Цитата(alag57 @ Mar 16 2016, 14:14) git c...   Mar 17 2016, 06:56
|- - scifi   Цитата(AleksBak @ Mar 16 2016, 21:01) Пох...   Mar 16 2016, 18:12
- - AleksBak   Вот, вчера это пропустил - еще там есть по этой те...   Mar 17 2016, 07:13
|- - Petr_   Цитата(AleksBak @ Mar 17 2016, 07:13) Вот...   Mar 17 2016, 11:04
|- - AleksBak   Цитата(Petr_ @ Mar 17 2016, 15:04) Спасиб...   Mar 17 2016, 11:33
|- - Petr_   Цитата(AleksBak @ Mar 17 2016, 11:33) Вы ...   Mar 17 2016, 11:55
|- - Petr_   Решил свои проблемы с LwIP и делюсь результатом(мо...   Mar 22 2016, 06:59
- - AleksBak   Спасибо большое, что отписались! Я вот тоже не...   Mar 22 2016, 15:55
- - Petr_   Цитата(AleksBak @ Mar 22 2016, 15:55) Спа...   Mar 22 2016, 18:13


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 24th July 2025 - 12:07
Рейтинг@Mail.ru


Страница сгенерированна за 0.01459 секунд с 7
ELECTRONIX ©2004-2016