Предел скрученной пропускной способности уменьшается - PullRequest
4 голосов
/ 20 августа 2011

Я занимаюсь разработкой программы, которая позволяет моделировать сети на одной машине. Для этого я использую Twisted для асинхронного ввода-вывода, так как наличие потока для каждого «соединения» может быть немного много. (Я также реализовал аналогичную программу на Java, используя их NIO). Однако по мере увеличения размера эмулируемой сети пропускная способность Twisted уменьшается. При сравнении этого с реализацией Java при том же размере сети пропускная способность Java продолжает расти. (Темпы роста замедляются, но все равно увеличиваются). Например. (Узлы Python 100 = 58 МБ Общая пропускная способность, 300 узлов = 45 МБ, Java 100 узлов = 24 МБ, 300 узлов = 56 МБ).

Мне интересно, есть ли у кого-нибудь предложения о том, почему это может происходить?

Единственная причина, по которой я могу придумать, состоит в том, что в Java каждый «пир» работает в своем собственном потоке (который содержит свой собственный селектор, который контролирует одноранговые соединения). В версии Python все зарегистрировано в реакторе (и впоследствии один селектор). По мере того, как Python One расширяется, один селектор не может реагировать так быстро. Однако это всего лишь предположение, что если у кого-то есть конкретная информация, она будет оценена.

EDIT: Я провел некоторое тестирование, как предложил Жан-Поль Кальдероне, результаты опубликованы на imgur . Для тех, кому может быть интересно, для тестов сообщалось о средней пропускной способности. (Профилирование было выполнено с помощью cProfile, тесты выполнялись в течение 60 секунд)

Реактор Эполла: 100 пиров: 20,34 МБ, 200 пиров: 18,84 МБ, 300 пиров: 17,4 МБ

Выбор реактора: 100 пиров: 18,86 МБ, 200 пиров: 19,08 МБ, 300 пиров: 16,732 МБ

Пару вещей, которые, казалось, пошли вверх и вниз с заявленной пропускной способностью, были вызовы, сделанные к main.py:48(send), но эта проверка не является на самом деле сюрпризом, поскольку именно здесь данные отправляются.

Для обоих реакторов время, проведенное в функции отправки на сокете (ах), увеличилось с уменьшением пропускной способности, а также уменьшилось количество вызовов функции отправки с уменьшением пропускной способности. (То есть: больше времени было потрачено на отправку в сокет, с меньшим количеством вызовов для отправки в сокет.) Например. 2,5 секунды для epoll {метод 'send' объектов '_socket.socket'} на 100 пиров для 413600 вызовов, до 5,5 секунд для epoll на 300 пиров для 354300 вызовов.

Чтобы попытаться ответить на первоначальный вопрос, кажется ли, что эти данные указывают на то, что селектор является ограничивающим фактором? Время, проведенное в Селекторе, кажется, уменьшается с увеличением числа пиров (если селектор все замедлял, разве нельзя ожидать, что время, потраченное внутри, увеличится?) Есть ли что-то еще, что может замедлить объем передаваемых данных? ? (Отправка данных - это всего лишь одна функция для каждого партнера, который снова и снова регистрируется в реакторе.calllater. Это main.py:49 (отправка))

1 Ответ

1 голос
/ 20 августа 2011

Попробуйте профилировать приложение на разных уровнях параллелизма и посмотрите, какие вещи становятся медленнее, когда вы добавляете больше соединений.

select является вероятным кандидатом; если вы обнаружите, что при добавлении соединений заметно больше и больше времени, попробуйте , используя poll или epoll реактор .

...