• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Как заставить google chrome давать ack не через 0.2 сек для стека http на esp8266?

pvvx

Активный участник сообщества
Дык к теме то это не имеет никакого отношения. И к скорости TCP тоже :)
Счас у меня 1.2 Мегабайта в секунду в IE и прочих, кроме Chrome. Предложите как сделать больше.
Первый попавшийся замер из темы "свалки": http://esp8266.ru/forum/attachments/1mbsec-gif.66/
Цель начатой мной дискуссии не замеры скорости, а факт если стек LWIP разрешает определенный размер буфера отправки, а мы его не заполняем полностью, при следующей отправке разрешенный размер буфера будет сокращаться.
Пакеты Lwip формирует сам. Ему можно помочь, задавая кратность к текущему размеру mss, что и вписано в исходниках "свалки" :)
Буфер - это "стек" и он ограничен 4 mss, при пару одновременных соединений, из-за общего ограничения размера всех буферов у Lwip, по причине "мало памяти в чипе".
За раз передается пакет с предельным размером в mss (- минус на всякие time...). Т.е. максимальный "стек" = 4 пакета длиной mss. Если сразу на них не придет подтверждений о приеме со стороны Chrome, то Lwip и другие не имеют права сбрасывать этот буфер, т.к. в TCP возможны перезапросы из этого "стека", пока не будет подтверждено о его приеме. Но Chrom дает его через 0.1 секунду после приема!

В TCP-UART, из-за сложности синхронизации, вообще данные складываются в буфера “стека” Lwip-у по прерываниям в беспорядке при большой скорости UART. То один байт, то тысячу. Но Lwip всегда отправляет пакет размером в mss. Всё зависит от скорости набора буфера и опроса Lwip-ом соединения.

Скорость WiFi у нас 54Мбита/сек. Реализованное в "свалке" дает 1.2 Мбайта по TCP. Для большей скорости надо оптимизировать (выкинуть всё что понаписал Espressif) и увеличить скорость CPU ESP8266. Тогда получите +20% :) Это теоретический предел реализации TCP на данном модуле по его архитектуре и компонентам.
 
Последнее редактирование:

d946

New member
Для тех кто будет реализовывать свой HTTP сервер, и столкнется с маленькой скорость загрузки в Chrome.
Решение ниже, описание в комментариях:

Код:
void onSend(...) {
  maxbufsize=tcp_sndbuf(pcb);
  ...
  buflen=os_sprintf(buf,".....",......);
  buflen+=os_sprintf(buf,".....",......);
  ...
  tcp_write(pcb, buf, buflen, 0);
  //если (buflen<maxbufsize) то в Chrome будет
  // десятикратное падение скорости,
  // но если buflen==maxbufsize  , то скорость в Chrome будет такая же
  // как в других браузерах (IE и других ), и качалках (DownloadMaster)
  // данное поведение замечено как на файлы передаваемые
  // с Content-Length, так и Transfer-encoding: chunked.
 
}
При добавлении строчки
os_printf("sndbuf = %u %u", maxbufsize , buflen);
мы можем наблюдать разрешенный размер буфера передаваемых данных, и увидим следующую картину:

1) Crome , (buflen<maxbufsize)
sndbuf= 2920 2860
sndbuf= 1756 1750
...
sndbuf= 1576 1550
sndbuf= 1742 1735
...
sndbuf= 1576 568

2) Crome , (buflen ==maxbufsize) и все другие браузеры

sndbuf= 2920 2920
sndbuf= 2920 2920
...
sndbuf= 2920 2920
sndbuf= 2920 2920
...
sndbuf= 2920 782
 

pvvx

Активный участник сообщества
Для тех кто будет реализовывать свой HTTP сервер, и столкнется с маленькой скорость загрузки в Chrome.
Измените размер передаваемого "окна" стека в TCP. И так понятно, что Chrom ждет полного прихода, всего WIN стека, хоть 100 пакетами... Ему лень подтверждать столько, сколько пришло и он чего-то ждет, т.е. "тупит". Плохой алгоритм, т.к. при потерях пакетов он будет дополнительно тормозить.
 

pvvx

Активный участник сообщества
d946 - tcp_write(pcb, buf, buflen, 0) не есть команда передать :) Это всего-то положить данные в буфер LwIP.
 

d946

New member
и если это буфер заполнить не полностью, то LWIP или клиент( в лице Crome) начинает тупить.
Для проверки можете проделать на своем компе и последней свалке следующую последовательность.
1) Загрузить максимально возможный статический файл который выдается с Content-Length(я проверял на gif файле с включенной отладкой "sndbuf")
2) Загрузите его через IE
3) Загрузите его через Crome

У меня скорости загрузки во 2) и 3) пункте равны, но как только я запрашиваю файл /ram.bin скорость падает до 6-7 килобайт.
 

pvvx

Активный участник сообщества
и если это буфер заполнить не полностью, то LWIP или клиент( в лице Crome) начинает тупить.
Для проверки можете проделать на своем компе и последней свалке следующую последовательность.
1) Загрузить максимально возможный статический файл который выдается с Content-Length(я проверял на gif файле с включенной отладкой "sndbuf")
2) Загрузите его через IE
3) Загрузите его через Crome

У меня скорости загрузки во 2) и 3) пункте равны, но как только я запрашиваю файл /ram.bin скорость падает до 6-7 килобайт.
Это известно почему. Первый блок передается не полностью равный 2*TCP_MSS и LwIP не умеет слать по два пакета, даже если у него буфер заполнен на 1,5 MSS. Только при заполнении 2*MSS он шлет 2 пакета.
В результате передача далее не идет по "хромому". Хром использует этот хромой алго:
http://esp8266.ru/forum/threads/kak...2-sek-dlja-steka-http-na-esp8266.12/#post-897
Счас уточню... заставлю LwIP слать по 2 пакета невзирая ни на что :) ...
 
Последнее редактирование:

pvvx

Активный участник сообщества
Вот - тупо и принудительно опциями в LwIP к pcb бью на 2 пакета любую передачу блока:
Chrome2.gif
В Wireshark:
Chrome2_.gif
Код:
        pcb->flags |= TF_NODELAY;
        err = tcp_write(pcb, psent, len>>2, 0);
        tcp_output(pcb); // передать что влезло
        err = tcp_write(pcb, &psent[len>>2], len-(len>>2), 0);
        tcp_output(pcb); // передать что влезло
Китайцы включили nagle LwIP-у по умолчанию...
В моем WEB всё решилось одной командой pcb->flags |= TF_NODELAY в нужном месте :)
 
Последнее редактирование:
Сверху Снизу