Название: QUdpSocket + пакеты большого размера. Отправлено: eugene.n от Апрель 28, 2014, 15:23 Есть сеть 10 Гбит/с (комп-комп). Nuttcp показывает максимальную скорость 1 Гбит/с при пакетах размером 1000 байт. При паккетах 8000 байт - скорость 6-7 Гбит/с. В настройках сетевой карты включена функция jumboframe (разрешено отправлять пакеты большого размера (<9000) без фрагментации IP-пакета).
C:\>ping 192.168.13.1 -f -l 8000 Обмен пакетами с 192.168.13.1 по с 8000 байтами данных: Ответ от 192.168.13.1: число байт=8000 время<1мс TTL=128 Ответ от 192.168.13.1: число байт=8000 время<1мс TTL=128 Ответ от 192.168.13.1: число байт=8000 время<1мс TTL=128 Ответ от 192.168.13.1: число байт=8000 время<1мс TTL=128 Статистика Ping для 192.168.13.1: Пакетов: отправлено = 4, получено = 4, потеряно = 0 (0% потерь) Приблизительное время приема-передачи в мс: Минимальное = 0мсек, Максимальное = 0 мсек, Среднее = 0 мсек Видно что IP-пакеты не фрагментированы. То есть, тратиться время на фрагментацию не должно. Пробуем послать пакеты такого же размера с помощью QUdpSocket. Код: QByteArray packet; При размере пакета 1000 байт получаем скорость 1 Гбит, но при размере пакета 8000 байт - скорость падает до 300 Мбит/с. В описании функции writeDatagram() говорится, что пакеты по 8000 байт шлются без проблем, нужно лишь убедиться в том, что не будут фрагментированы ip-пакеты. Так в чем же проблема? Почему writeDatagram() работает так медленно с большими пакетами или почему я не могу достичь скорости хотя бы 6 Гб/с (даже при пакетах маленького размера)? Название: Re: QUdpSocket + пакеты большого размера. Отправлено: LisandreL от Апрель 28, 2014, 23:01 Цитировать QByteArray packet; Может побольше кусок кода дадите?QUdpSocket *udpSocket = new QUdpSocket(this); while(udpSocket->writeDatagram(packet.data(), packet.size(), QHostAddress("192.168.13.1"), 3333) == -1); В принципе вполне возможно, что из цикла вываливаетесь и что дальше происходит - не понятно. Ну и кроме QHostAddress("192.168.13.1") - заменить на константу / переменную. Иначе каждый раз разбор адреса происходит из сторки. А packet.data() => packet.constData() - так быстрее. Или вообще в пользу массива char посмотреть. В общем советую по профилировать - совсем не факт, что тормозит именно сокет. P.S. Может быть стоит вызывать waitForBytesWritten, а может наоборот хуже сделает, не знаю. Название: Re: QUdpSocket + пакеты большого размера. Отправлено: eugene.n от Апрель 29, 2014, 08:58 А packet.data() => packet.constData() - так быстрее. Или вообще в пользу массива char посмотреть. Не помогло :( Код:
Дело в том, что на пакетах маленького размера (1000-2000 байт) программа показывает скорость чуть больше 1 Гб/с, а на больших пакетах (5000 - 8000) скорость падает. в 3 -4 раза (Сторонние программы показывают пропускную способность канала до 7 - 7,5 Гб/с). P.S. Может быть стоит вызывать waitForBytesWritten, а может наоборот хуже сделает, не знаю. Кажется, это работает на сокетах с соединением. У меня без соединения.Название: Re: QUdpSocket + пакеты большого размера. Отправлено: Old от Апрель 29, 2014, 09:02 Посмотрите снифером, что реально отправляется в каждом из случаев.
Название: Re: QUdpSocket + пакеты большого размера. Отправлено: eugene.n от Апрель 29, 2014, 09:10 Посмотрите снифером, что реально отправляется в каждом из случаев. Смотрел wireshark'ом. Всё ок. Пакеты не фрагментированы и данные целые (и со стороны клиента и со стороны сервера). Название: Re: QUdpSocket + пакеты большого размера. Отправлено: Old от Апрель 29, 2014, 09:14 Смотрел wireshark'ом. Всё ок. Пакеты не фрагментированы и данные целые (и со стороны клиента и со стороны сервера). Хм, чудеса. Попробуйте сокету делать flush.Название: Re: QUdpSocket + пакеты большого размера. Отправлено: eugene.n от Апрель 29, 2014, 09:18 Смотрел wireshark'ом. Всё ок. Пакеты не фрагментированы и данные целые (и со стороны клиента и со стороны сервера). Хм, чудеса. Попробуйте сокету делать flush.Тот же результат :( Название: Re: QUdpSocket + пакеты большого размера. Отправлено: Old от Апрель 29, 2014, 09:35 Посмотрел исходники, каких то тяжёлый операций не нашел, быстренько вызывается sendto. ???
Странно. Название: Re: QUdpSocket + пакеты большого размера. Отправлено: LisandreL от Апрель 29, 2014, 09:36 Код: quint64 t1 = curTime.elapsed(); Название: Re: QUdpSocket + пакеты большого размера. Отправлено: eugene.n от Апрель 29, 2014, 09:40 Код: quint64 t1 = curTime.elapsed(); Да, потерял. Спасибо. Исправил. Но не в этом дело) Название: Re: QUdpSocket + пакеты большого размера. Отправлено: eugene.n от Апрель 29, 2014, 10:23 Немного переформулировал вопрос. Почему я не могу достичь скорости хотя бы 6 Гб/с? ??? ??? ???
Название: Re: QUdpSocket + пакеты большого размера. Отправлено: Old от Апрель 29, 2014, 10:29 Немного переформулировал вопрос. Почему я не могу достичь скорости хотя бы 6 Гб/с? ??? ??? ??? Стоп. Я думал у вас есть программа, которая умеет отправлять датаграммы быстрее, чем такая же на Qt и вы хотите разобраться почему. Или вы просто предполагали, что с увеличением размера данных возрастет и скорость?Название: Re: QUdpSocket + пакеты большого размера. Отправлено: eugene.n от Апрель 29, 2014, 10:34 Немного переформулировал вопрос. Почему я не могу достичь скорости хотя бы 6 Гб/с? ??? ??? ??? Стоп. Я думал у вас есть программа, которая умеет отправлять датаграммы быстрее, чем такая же на Qt и вы хотите разобраться почему. Или вы просто предполагали, что с увеличением размера данных возрастет и скорость?Да, есть. В первом посте я писал что тестировал сеть с помощью nuttcp и получил скорость 1 Гб при пакетах ~1000Б. У моей программы выходит такая же скорость. У nuttcp при размере пакетов 8000Б получается скорость 6-7 Гб/с, а у моей программы она получается даже ниже чем 1 Гб/с при таких пакетах (8000Б). А с увеличением размера пакетов скорость растет так как 10 Гбитная сетевая карточка лучше справляется с отправкой больших сегментов, нежели маленьких (при которых она сильно грузится). Название: Re: QUdpSocket + пакеты большого размера. Отправлено: Old от Апрель 29, 2014, 10:57 Попробуйте посмотреть с помощью strace , как отправляет и как настраивает сокет nuttcp.
А потом сравните со своей, может что-то прояснимся. Может они срочные сообщения отправляют или открывают сокет в неблокирующем режиме? Название: Re: QUdpSocket + пакеты большого размера. Отправлено: Bepec от Апрель 29, 2014, 11:46 Или расширяют буфер на принимающей стороне...
Название: Re: QUdpSocket + пакеты большого размера. Отправлено: eugene.n от Апрель 29, 2014, 11:59 Или расширяют буфер на принимающей стороне... так моя программа даже не подозревает о существовании сервера, т.к. сокет без соединения. То есть, практически, мы измеряем не пропускную способность сети, а сколько байт может отправить клиент за 1 с. Название: Re: QUdpSocket + пакеты большого размера. Отправлено: Bepec от Апрель 29, 2014, 13:37 Тогда я вас не понимаю. Как можно измерить количество отправляемой информации за 1 секунду, если эту информацию никто не принимает? :) Никак. Ведь на отправляющей стороне вы в стороне от самого процесса отправки.
А вот если будет принимающая сторона, то она как раз и измеряет количество принятой информации. И если буфер маленький, часть (большая) пакета будет теряться. Название: Re: QUdpSocket + пакеты большого размера. Отправлено: eugene.n от Апрель 29, 2014, 14:00 Тогда я вас не понимаю. Как можно измерить количество отправляемой информации за 1 секунду, если эту информацию никто не принимает? :) Никак. Ведь на отправляющей стороне вы в стороне от самого процесса отправки. А вот если будет принимающая сторона, то она как раз и измеряет количество принятой информации. И если буфер маленький, часть (большая) пакета будет теряться. Принимающая сторона есть. И там можно посмотреть что все данные пришли. Но клиент то не знает о принимающей стороне ничего, так что скорость отправки сообщений ни как не может зависеть от размера буфера приемника. Главный вопрос, почему writeDatagram() работает так медленно, когда у него в распоряжении канал в 10 Гбит/с. ps. Согласен, что у меня измеряется не сама скорость передачи, а скорее (размер пакета) * (количество удачных завершений writeDatagram()). Принимающая сторона показывает такую же скорость (~1 Гбит/с). Ниже прикрепил график изменения скорости при изменении размера пакетов. Название: Re: QUdpSocket + пакеты большого размера. Отправлено: Bepec от Апрель 29, 2014, 14:36 Да, кстати буфер и на отправляющей стороне как бы увеличить можно, насколько я помню )
Ммм.. разовью мысль. Что будет если у сокета будет переполнен буфер отправки? Мб он будет ждать его освобождения и до того момента он заблокирует передачу иных пакетов? PS немного сумбурно, но попробовать стоит :D Название: Re: QUdpSocket + пакеты большого размера. Отправлено: eugene.n от Апрель 29, 2014, 14:40 Да, кстати буфер и на отправляющей стороне как бы увеличить можно, насколько я помню ) Ммм.. разовью мысль. Что будет если у сокета будет переполнен буфер отправки? Мб он будет ждать его освобождения и до того момента он заблокирует передачу иных пакетов? PS немного сумбурно, но попробовать стоит :D Пробовал. Не помогло :( Код: int bufferSize = 64 * 1024; // до 4 * 1024 *1024 |