Re[3]: Чтение из сети и обработка
От: qaz77  
Дата: 14.02.22 10:38
Оценка:
Здравствуйте, tryAnother, Вы писали:
A>    while(true)
A>    {
A>        const int packet_awailable = get_pending_count(sock);
A>        for (int i = 0; i < packet_awailable; ++i)
A>        {
A>            int nRead = recvfrom(sock, packet, PACKET_LEN, 0, NULL, NULL);
A>            _ASSERT(nRead == PACKET_LEN);
A>            stat.OnPacket(packet);
A>        }
A>        Sleep(20);
A>    }


Идея со Sleep(20) — так себе.
Поток не пробуждается сразу же по приходу хотя бы одного пакета.
Представьте, что пакет приходит в первую мс слипа, а мы все равно спим еще 19 мс.
Лучше для ожидания поступления данных использовать select.

Вторая проблема, если за время слипа придет слишком много пакетов, то возможна их потеря.
Т.к. у сокета внутренний буфер конечного размера.
Re[4]: Чтение из сети и обработка
От: tryAnother  
Дата: 14.02.22 10:49
Оценка:
Здравствуйте, qaz77, Вы писали:

Q>Идея со Sleep(20) — так себе.

Q>Поток не пробуждается сразу же по приходу хотя бы одного пакета.
Q>Представьте, что пакет приходит в первую мс слипа, а мы все равно спим еще 19 мс.
Q>Лучше для ожидания поступления данных использовать select.

такая актуальность и не требуется, обработка всех собранных за "такт" пакетов происходит пачкой, поток не прыгает в сон и не пробуждается без надобности
в случае обработки по приходу поток бы постоянно дергался (пакеты идут 20 К в секунду) полюсов не видно.

Q>Вторая проблема, если за время слипа придет слишком много пакетов, то возможна их потеря.

Q>Т.к. у сокета внутренний буфер конечного размера.

конечно, но с существенным запасом,
при потоке 20К в секунду за 20 мс придет 400 пакетов, а буфер у меня на ~4000
Отредактировано 14.02.2022 13:03 tryAnother . Предыдущая версия .
Re[5]: Чтение из сети и обработка
От: qaz77  
Дата: 14.02.22 15:23
Оценка:
Здравствуйте, tryAnother, Вы писали:
A>такая актуальность и не требуется, обработка всех собранных за "такт" пакетов происходит пачкой, поток не прыгает в сон и не пробуждается без надобности
A>в случае обработки по приходу поток бы постоянно дергался (пакеты идут 20 К в секунду) полюсов не видно.

Если много датаграм приходит в единицу времени, то ожидание по select не приведет к лишним пробуждениям потока.
Когда пробудились кушаем все, пока очередь пакетов не пустая.
На практике надо замерять производительность со Sleep и select.

Все-таки смущает хардкод константы 20 мс.
Допустим софт будет крутится на слабенькой машине и время манипуляции с принятым пакетом будет сильно больше...

Если это не массовый софт, а написанный для конкретной железки, то наверное и так норм.
Я вот пишу коробочный и даже сейчас в 2022 еще пентиум 3 у клиентов бывает.
Re[3]: Чтение из сети и обработка
От: Умака Кумакаки Ниоткуда  
Дата: 20.02.22 03:25
Оценка:
Здравствуйте, tryAnother, Вы писали:

вот это:

boost::bind(&async_server::handle_receive_from, this,
                ba::placeholders::error,
                ba::placeholders::bytes_transferred)
            );

надо сделать один раз, например в конструкторе, хендлер один и тот же, зачем он аллоцируется каждый раз?
нормально делай — нормально будет
Re[3]: Чтение из сети и обработка
От: Умака Кумакаки Ниоткуда  
Дата: 20.02.22 19:15
Оценка:
Здравствуйте, tryAnother, Вы писали:

A> ++seq_;

A> if(seq_ != seq)
A> printf("Sequence broken, recv %d expect %d, dif %d\n", seq, seq_, seq-seq_);


блэт, слона то я и не заметил, это UDP, алло, откуда здесь гарантия последовательности пакетов? и откуда гарантия последовательного вызова хендлеров в азио?
нормально делай — нормально будет
Re[4]: Чтение из сети и обработка
От: tryAnother  
Дата: 22.02.22 09:18
Оценка:
Здравствуйте, Умака Кумакаки, Вы писали:

УК>Здравствуйте, tryAnother, Вы писали:


УК>вот это:


УК>
УК>boost::bind(&async_server::handle_receive_from, this,
УК>                ba::placeholders::error,
УК>                ba::placeholders::bytes_transferred)
УК>            );
УК>

УК>надо сделать один раз, например в конструкторе, хендлер один и тот же, зачем он аллоцируется каждый раз?

допускаю что тут лишние аллокации, которых можно избежать, но 20К аллокаций в секунду не большая нагрузка
и синхронная версия по потерям ведет себя аналогично асинхронной, то есть дело не в этом.

а можно ли посмотреть на код где "асио не напрягаясь может хендлить на одном ядре на порядок больше пакетов" и интересно какой там pps и общая скорость.
Re[4]: Чтение из сети и обработка
От: tryAnother  
Дата: 22.02.22 09:23
Оценка:
Здравствуйте, Умака Кумакаки, Вы писали:

УК>Здравствуйте, tryAnother, Вы писали:


A>> ++seq_;

A>> if(seq_ != seq)
A>> printf("Sequence broken, recv %d expect %d, dif %d\n", seq, seq_, seq-seq_);


УК>блэт, слона то я и не заметил, это UDP, алло, откуда здесь гарантия последовательности пакетов? и откуда гарантия последовательного вызова хендлеров в азио?


гарантий никто и не обещал, это понятно, но сеть там точка точка, никого кроме железки и принимающей машины нет, и она работает хорошо, пакетам там теряться некуда.
вопрос в сравнении подходов к чтению:
— синхронный и асинхроный asio теряют пачки по единицам — десяткам пакетов от единиц до десятков в час в зависимости от загрузки машины,
— подход с чтением через sleep теряет единицы пакетов в сутки
Re[5]: Чтение из сети и обработка
От: Умака Кумакаки Ниоткуда  
Дата: 23.02.22 22:41
Оценка:
Здравствуйте, tryAnother, Вы писали:

A>гарантий никто и не обещал, это понятно, но сеть там точка точка, никого кроме железки и принимающей машины нет, и она работает хорошо, пакетам там теряться некуда.

рация работает на бронепоезде? речь не о потерях, а о порядке пакетов

A>вопрос в сравнении подходов к чтению:

A>- синхронный и асинхроный asio теряют пачки по единицам — десяткам пакетов от единиц до десятков в час в зависимости от загрузки машины,
A>- подход с чтением через sleep теряет единицы пакетов в сутки

ещё раз, текущий тест "потери пакетов" невалиден, инкремент счётчика тут не канает, если надо посчитать количество принятых пакетов — заведи vector<bool> например на миллион элементов, и засовывай ему по индексу, который равен id пришедшего пакета true, после отправки миллиона пакетов выждать паузу и посчитать, сколько в векторе true значений, если меньше миллиона, то есть потери.
нормально делай — нормально будет
Re[6]: Чтение из сети и обработка
От: tryAnother  
Дата: 24.02.22 09:45
Оценка: +1
Здравствуйте, Умака Кумакаки, Вы писали:

УК>Здравствуйте, tryAnother, Вы писали:


A>>гарантий никто и не обещал, это понятно, но сеть там точка точка, никого кроме железки и принимающей машины нет, и она работает хорошо, пакетам там теряться некуда.

УК>рация работает на бронепоезде? речь не о потерях, а о порядке пакетов

рация конечно на танке, но тест результаты теста показывают не перетасовку пакетов, а именно потерю
    Sequence broken, recv 15463 expect 15448, dif 15
    Sequence broken, recv 15490 expect 15472, dif 18
    Sequence broken, recv 15503 expect 15499, dif 4
    Sequence broken, recv 15516 expect 15512, dif 4
    Sequence broken, recv 15528 expect 15525, dif 3
    Sequence broken, recv 15744 expect 15723, dif 21


если бы проблемы была в потере порядка, то сообщения изобиловали как положительными так и отрицательными dif

A>>вопрос в сравнении подходов к чтению:

A>>- синхронный и асинхроный asio теряют пачки по единицам — десяткам пакетов от единиц до десятков в час в зависимости от загрузки машины,
A>>- подход с чтением через sleep теряет единицы пакетов в сутки

УК>ещё раз, текущий тест "потери пакетов" невалиден, инкремент счётчика тут не канает, если надо посчитать количество принятых пакетов — заведи vector<bool> например на миллион элементов, и засовывай ему по индексу, который равен id пришедшего пакета true, после отправки миллиона пакетов выждать паузу и посчитать, сколько в векторе true значений, если меньше миллиона, то есть потери.


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

еще какие предположения по невалидности теста? и почему он проходит в режиме с задержкой
Re[7]: Чтение из сети и обработка
От: Умака Кумакаки Ниоткуда  
Дата: 24.02.22 11:10
Оценка:
Здравствуйте, tryAnother, Вы писали:

A>еще какие предположения по невалидности теста? и почему он проходит в режиме с задержкой


я бы всё таки убрал аллокацию, возможно после тысяч аллокаций аллокатор решает компактифицировать кучу, или ещё какую оптимизацию провести, и на этот момент попадает передача пакета. Убери вообще класс calcstat, сделай просто свободную функцию OnPacket(const boost::system::error_code& error, std::size_t bytes_transferre), внутри неё статическую переменную int seq_ и передавай этот хендлер просто как есть, без оборачивания в функтор через bind
нормально делай — нормально будет
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.