Подтвердить что ты не робот

Каково фактическое воздействие вызова socket.recv с bufsize, который не является силой 2?

Для чтения данных из сокета в python вы вызываете socket.recv, у которого есть эта подпись:

socket.recv(bufsize[, flags])

документы python для socket.recv неопределенно:

Примечание.. Для обеспечения наилучшего соответствия аппаратным и сетевым реалиям значение bufsize должен быть относительно небольшим мощность 2, например, 4096.

Вопрос. Что означает "наилучшее соответствие аппаратным и сетевым реалиям"? Каково фактическое влияние настройки bufsize на не-два-два?

Я видел много другие , чтобы прочитать это значение 2. Я также хорошо осведомлен о причинах, когда часто бывает полезно иметь длины массивов как полномочия двух (операции бит-сдвига/маскировки по длине, оптимальный массив FFT размер и т.д.), но они зависят от приложения. Я просто не вижу общей причины для этого с socket.recv. Разумеется, это не соответствует конкретной рекомендации в документации на python. Я также не вижу никаких оптимизаций в два раза в лежащем в основе кода python, чтобы сделать его рекомендацией для python

Например... если у вас есть протокол, в котором длина входящего пакета точно известна, очевидно, что лучше всего читать только "не более", что необходимо для пакета, с которым вы имеете дело, иначе вы могли бы следующий пакет, и это будет раздражать. Если в пакете, который я сейчас обрабатываю, осталось только 42 байта, я собираюсь установить bufsize на 42.

Что мне не хватает? Когда мне приходится выбирать произвольный размер буфера/массива, я обычно (всегда?) Делает длину равной двум, на всякий случай. Это всего лишь привычка, разработанная на протяжении многих лет. Являются ли документы python просто жертвой привычки?

Это не эксклюзивно для python, но поскольку я специально ссылаюсь на документы python, я помечаю его как таковой.


UPDATE. Я просто проверил размер буфера на уровне ядра в моей системе (или, по крайней мере, я думаю, что сделал... я сделал cat /proc/sys/net/core/rmem_default), и это было 124928. Не сила двух. rmem_max был 131071, также явно не сила двух.

В этом я больше не вижу никакой пользы от двух рекомендаций (рекомендаций). Я уже готов назвать это фиктивной рекомендацией...

Я также добавил теги tcp и C, так как они также актуальны.

4b9b3361

Ответ 1

Я почти уверен, что совет "власти 2" основан на ошибке в редактировании и не должен восприниматься как требование.

Этот конкретный совет был добавлен в документацию Python 2.5обратился к Python 2.4.3 docs), в ответ на проблема с Python # 756104. Репортер использовал неоправданно большой размер буфера для socket.recv(), который вызвал обновление.

Именно Тим Петерс представил концепцию "власти 2":

Я ожидаю, что вы единственный человек в истории, который попытается передать такие большое значение для recv() - даже если это сработало, вы почти конечно, нехватка памяти, пытаясь выделить буферное пространство для 1.9GB. сокеты - это низкоуровневые объекты, а пропускают относительно небольшую мощность 2 (для наилучшего соответствия с аппаратные и сетевые реалии).

(Смелый акцент мой). Я работал с Тимом, и у него огромный опыт работы с сетевым программированием и аппаратным обеспечением, поэтому, вообще говоря, я бы взял его на слово, сделав такое замечание. Он особенно "любил" стек Windows 95, он назвал его своей канарейкой в ​​угольной шахте, чтобы ее способность терпеть неудачу под стрессом. Но обратите внимание, что он говорит, что это обычный, а не то, что требуется использовать мощность 2.

Именно такая формулировка привела к обновлению документации:

Это ошибка документации; что-то должно быть "предупредил" о.

Это поймало меня однажды, и два разных человека спросили о это в #python, так что, возможно, нам стоит положить что-то вроде следуя в документах recv().

""
Для наилучшего соответствия аппаратным и сетевым реалиям, значение "буфера" должно быть относительно небольшой мощностью 2,
например, 4096.
""

Если вы считаете правильную формулировку, просто назначьте ошибку меня, я позабочусь об этом.

Никто не оспаривал утверждение "сила 2" здесь, но редактор, перемещенный из него, обычно должен находиться в нескольких ответах.

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

Но хотя вполне может быть эзотерический стек, в котором еще важны буферы с размером, который имеет значение 2, я сомневаюсь, что Тим Петерс когда-либо имел в виду его опыт (это обычная практика) одетые термины. Просто игнорируйте его, если другой размер буфера имеет больше смысла для ваших конкретных случаев использования.

Ответ 2

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

Это может быть предпочтительным для разработчика приложений, но, вероятно, неэффективно для базового сетевого стека. Во-первых, он связывает пространство буфера сокета, которое может использоваться для дополнительных сетевых операций ввода-вывода. Во-вторых, каждый recv(), который вы делаете, означает погружение в системный вызов/пространство ядра, и для перехода есть ограничение производительности. Всегда желательно получать как можно больше данных из пространства ядра и в пространство пользователя с максимально возможными системными вызовами и выполнять синтаксический анализ вашего сообщения. Это повышает сложность кода приложения и обработки сообщений, но, вероятно, является наиболее эффективным.

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

Я не уверен в силе 2 рекомендаций от приложения для пользовательского пространства. Я видел эти типы требований для драйверов из-за проблем с выравниванием и размерами страниц и т.д., Но неясно, какое влияние это оказывает на пользовательское пространство, если оно каким-то образом не помогает копировать данные из буферов ядра в пользовательские буферы. Может быть, кто-то, у кого больше знаний о развитии ОС, мог бы прокомментировать.