|
Вопрос по LwIP, Скорость отправки |
|
|
|
Mar 15 2016, 18:12
|
Группа: Участник
Сообщений: 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 куска - тоже левизна. Кто то знает нормальное решение?
|
|
|
|
|
 |
Ответов
|
Mar 15 2016, 19:50
|
Участник

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

|
Цитата(Petr_ @ Mar 15 2016, 21:12)  Передаю большой файл. Использую цепочку колбеков, как и задумано в lwIP. Но заполняю буфер передачи не полностью(узнаю из tcp_sndbuf(pcb); ). Далее вызываю tcp_write(pcb, Data_Bf, wMaxPut, 0); и завершаю функцию. Скорость никакущая. ..... Кто то знает нормальное решение? Ну насколько я понял из написанного,то вы сами и предложили нормальное решение,отключив алгоритм Нейгла(был такой перец,который предложил специально задерживать данные для увеличения пропускной способности сети.При этом подразумевается,что данные небольшого размера не передаются сразу в сеть,а накапливаются в буфере,и передаются только тогда,когда буфер полон)
|
|
|
|
|
Mar 15 2016, 20:11
|
Группа: Участник
Сообщений: 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 тыс. туда/обратно в секунду. Просто решение корявое, хотя и рабочее. Потому спрашиваю.
|
|
|
|
|
Mar 15 2016, 20:54
|
Группа: Участник
Сообщений: 14
Регистрация: 15-03-16
Пользователь №: 90 876

|
Цитата(aaarrr @ Mar 15 2016, 20:32)  В вашем примере Nagle отключается не только для первого пакета, а вообще для данного соединения. Это не так в реале! ACK ожидается для 2-го пакета. Это вариант из Сети. Я посмотрел исходники. Это имнно так - флаг убирается для новых пакетов (согласно дефолтным установкам) Есть еще вариант - допилить lwIP на предмет работы с окнами. Но тогда станет невозможным легкий апгрейд, если он когда то выйдет...
|
|
|
|
|
Mar 16 2016, 07:57
|
Группа: Участник
Сообщений: 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
|
|
|
|
|
Mar 16 2016, 18:01
|
Частый гость
 
Группа: Участник
Сообщений: 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 (?) Ссылка на один сайт (похоже ихний шведский какой-то) вообще уже не работает.  ) Бесплатный сыр он такой. Еще нашел пару ссылок про упоминание lwip + Nagle (можете тоже сами найти если нужно, но там ничего такого).
|
|
|
|
Сообщений в этой теме
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
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|