Я передаю данные между двумя серверами Ubuntu (12.04) через iperf в локальной сети 1 Гб.
iperf -s <-> iperf -c <addr> -n2G
TCP speed = 925 Mbits/sec
iperf -su <-> iperf -uc<addr> -b1G -n2G
UDP speed = 810 Mbits/sec
Jitter = 0.016 ms
Lost = 0 .. 0.01%
Я ожидал, что UDP намного быстрее TCP. Может ли кто-нибудь объяснить, почему UDP медленнее, чем TCP на сервере Ubuntu?
Как сказано выше, iperf ограничивает себя дизайном. В src/Client.cpp
, метод
void Client::Run( void )
звонки
ReportPacket( mSettings->reporthdr, reportstruct );
после записи каждой дейтаграммы UDP.
ReportPacket()
довольно медленный, и он замедляет все это.
В iperf3 для UDP введена пакетная запись, вы можете указать количество пакетных записей в -b
параметр командной строки, например -b 10240M/2000
в противном случае вы можете использовать netperf с -t UDP_STREAM
.
При отправке каждый кадр проходит через несколько буферов: буфер приложения, буфер протокола, буфер программного интерфейса и буфер аппаратного интерфейса. Когда вы начнете загружать стек, отправив высокоскоростные данные, вы заполните эти буферы и либо заблокируете, либо потеряете данные. У вас также есть стратегии своевременности и опроса, которые могут повлиять на вашу производительность. Например, используя больший буфер и реже опрашивая, вы можете получить гораздо лучшую производительность, жертвуя при этом задержкой.
TCP оптимизирован для высокоскоростной массовой передачи, а UDP оптимизирован для низкой задержки в ядре Linux. Это влияет на размер буфера, а также на то, как данные опрашиваются и передаются. В дополнение к этому у вас часто бывает разгрузка оборудования для TCP. Я ожидал, что TCP будет работать лучше, чем UDP.
Обратите внимание, что отправка высокоскоростных данных по UDP обычно является плохой идеей, если вы не реализуете собственный контроль перегрузки. TCP защищает вашу сеть от перегрузок. Используйте UDP, если у вас небольшие объемы данных или высокие требования к своевременности.
Проблема внутри самого iperf. Когда вы отправляете поток UDP, iperf будет вести внутренний учет для каждой дейтаграммы в потоке. С другой стороны, когда вы отправляете поток TCP, iperf ведет учет только один раз для каждого потока. В моих измерениях выяснилось, что iperf-UDP тратит много времени на измерения для каждой датаграммы, что снижает производительность.
Если вы действительно хотите сравнить производительность TCP и UDP, лучше написать собственную тестовую программу. и убедитесь, что объем вычислений одинаков в обоих случаях.