Предел скрученной пропускной способности уменьшается

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

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

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

РЕДАКТИРОВАТЬ: Я провел некоторое тестирование по предложению Жан-Поля Кальдероне, результаты размещены на imgur. Для тех, кому может быть интересно, для тестов сообщалось о следующей пропускной способности Avg. (Профилирование было выполнено с помощью 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 ответ

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

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

Другие вопросы по тегам