2013-11-21 2 views
4

Например, я отправляю 100000 UDP-пакетов в Windows. Для каждого пакета мне нужно позвонить WSASendTo() один раз, так что, вероятно, появится много служебных издержек системного вызова. Есть ли способ сделать массовую отправку и уменьшить накладные расходы? Я не мог найти решение для Windows после поиска в Google. Кроме того, я хотел бы знать, возможно ли это в Linux. Благодарю.Как уменьшить системные вызовы при отправке большого количества UDP-пакетов? (и Windows и Linux)

+0

OK. В Linux я могу использовать 'sendmmsg()'. Тогда этот вопрос касается только Windows. – Chen

+0

'WSASendMsg()' кажется эквивалентом Windows 'sendmmsg()', но [документ MSDN] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms741693 (v = vs.85) .aspx) явно не говорит, что эта функция отправляет разные буферы в виде разных пакетов. – Chen

+1

Нет, это не эквивалент 'sendmmsg' (и не работает' WSARecvFrom'). Вы можете предоставить более одного буфера и использовать разброс/сборку, да. Но у вас есть только одно значение для байтов для отправки/получения и одно единственное возвращаемое значение для байтов, полученных/отправленных. Это работает для одного потока TCP, но не для датаграмм UDP, где вам нужны N размеров для отправки и N размеров, отправленных (или успех/сбой) для N датаграмм. Насколько мне известно, Windows не имеет такой возможности для сокетов. – Damon

ответ

2

В Windows вы можете использовать новый Windows I/O API (RIO) на сервере 2012 и Windows 8 и более поздних версиях.

Я написал довольно много об этом here и провел несколько сравнений производительности с предыдущими API, которые доступны в Windows. Тесты производительности можно найти here.

Вкратце: «Зарегистрированные сетевые расширения ввода-вывода, RIO, это новый API, который был добавлен в Winsock для поддержки высокоскоростных сетей для повышения производительности сети с более низкой задержкой и джиттером. для серверных приложений и использования предварительно зарегистрированных буферов данных и очередей завершения для повышения производительности. Повышенная производительность возникает из-за того, что не нужно блокировать страницы памяти и копировать структуры в пространстве ядра при выдаче отдельных запросов, вместо этого полагаясь на блокированные буферы, фиксированные очереди завершения, необязательное уведомление о событиях при завершении и возможность возвращать несколько завершений из пространства ядра в пространство пользователя за один раз ».

Результаты моих тестов производительности, похоже, подразумевают, что они работают.

+1

Отличный учебник по RIO! – Chen

+0

Подождите. Параметр 'DataBufferCount'' RIOSend() 'в настоящее время может быть только 1 или 0, поэтому моя проблема все еще не решена:/Hope MS позволит нам указать ture' DataBufferCount' в будущих версиях Windows. – Chen

+0

Ох. Возможно, я могу вызвать 'RIOSend()' с 'RIO_MSG_DEFER', чтобы отправить запросы отправки в очередь и в конечном итоге указать' RIO_MSG_COMMIT_ONLY', чтобы выполнить фактическую работу. Нужен бенчмаркинг, чтобы узнать, действительно ли это происходит быстрее. – Chen

0

Используйте TransmitPackets() в Windows.

Смежные вопросы