четверг, 19 июля 2012 г.

asio performance test

Данное сообщение будет служить для сбора всей информации, что мне удастся собрать по теме производительности Asio. Буду рад видеть в комментариях вопросы/критику/дополнения и результаты/методики тестов читателей.

Для начала выложу самое простое – отчеты профилировщика MS VS 2010. И клиент и сервер работали одновременно на моей домашней машине (причем без отключения прочих приложений вроде uTorrent и MS Outlook):
  • MS Windows 7 Pro x64 SP1 + все обновления на 19.07.2012
  • ASUS P6T Deluxe (LGA 1366)
  • Intel Core i7 920 2.6Hz (4 physical cores), Hyper-threading on (8 logical cores)
  • 12 Gb RAM 1333MHz
  • Boost C++ Libraries 1.50 + все патчи из /asio_samples/build/patches/boost_1_50_0
  • Qt 4.8.2 static build with static C/C++ runtime + патчи из /asio_samples/build/patches/qt_4_8_1_patches: build_static_win32-msvc2010.patch, container_msvc_warn.patch, win_cursors.patch
  • Исходники asio samples из https://asio-samples.svn.sourceforge.net/svnroot/asio-samples/trunk (revision 617)
  • Проект echo_server, собранный в конфигурации Profile/Win32
  • Проект asio_performance_test_client, собранный в конфигурации Profile/Win32

Тестирование echo_server (echo_server120719.vsps).
  • Параметры запуска echo_server (echo_server.psess):
    --port=7 --inactivity_timeout=60 --session_threads=4
  • Параметры запуска asio_performance_test_client:
    127.0.0.1 7 4 4096 10000 600 0

Тестирование asio_performance_test_client (asio_performance_test_client120719.vsps).
  • Параметры запуска asio_performance_test_client (asio_performance_test_client.psess):
    127.0.0.1 7 4 4096 10000 600 0
  • Параметры запуска qt_echo_server (кроме тех, чьи значения по умолчанию не менялись):
    Execution/Session (IO) threads: 4; Session management/Listen backlog: 10000; Session/Inactivity timeout (seconds): 60.

Буду постепенно дописывать данное сообщение. Пока выкладываю результаты как есть.

Немного поколдовал над результатами тестов: для исключения некоторых функций пришлось сделать выгрузку в Excel - echo_server120723.xls и asio_performance_test_client120723.xls (см. столбец "Elapsed Exclusive Time, fixed %").
Думал над функцией [<Unknown>] в отчете по asio_performance_test_client. Похоже, это ConnectEx - именно ее название компилятору неизвестно и именно ее вызывает функция ma::async_connect.

Updated 24.07.2012
Залил конфигурацию сборки проектов echo_server и asio_performance_test_client в SVN.
Обновил результаты тестов.
Добавил скорректированные таблицы результатов работы профилировщика в разрезе функций.

Updated 26.07.2012
Как видно из "скорректированных" таблиц результатов работы профилировщика, большую часть времени и echo_server и asio_performance_test_client проводят в системных функциях ввода-вывода (почему-то в WSASend - видимо, это связано с тем, что и сервер и клиент работали на одной и той же машине и общались через localhost) и демультиплексирования событий. По-моему, это хороший результат.

Думаю, стоит попробовать Intel VTune - интересует работа потоков.

Updated 11.08.2012
Попробовал погонять по сети и измерить VTune-ом (Core2 Duo E7200, Windows 7 x86 SP1 Pro, https://asio-samples.svn.sourceforge.net/svnroot/asio-samples/trunk@660):
Для большей наглядности почти те же данные в виде графиков:

Итоговый график для echo_server

Bottom-up для echo_server

Итоговый график для asio_performance_test_client

Bottom-up для asio_performance_test_client

Результаты, в общем-то, ожидаемо положительные и совпадают с отчетом "студийного" профилировщика. Единственное, что вызывает подозрение, это 2-х ядерный процессор. Я все еще ищу возможность использовать VTune на 8-ядерном процессоре (думаю, еще понадобится несколько n-ядерных машин, чтобы нагрузить такой сервер "под завязку").

8 комментариев:

Кир комментирует...

Я конечно извиняюсь, но что это?? Т.е. я считаю, что тема полезная и нужная, но исполнение меня шокирует. Поясню.

1. непонятно в чём тестирование. Интересно сравнить азио с либэвент или с сырым АПИ, вы же просто профилируете азио. А зачем, вы хотите его ускорить? Оно сейчас тормозит что ли?

2. хочется увидеть реальные цифры, число http запросов в секунду, скорость передачи данных, хоть что-то реальное. А не эксель с VC-шным профилем. Вообще лучше txt использовать.

3. Про тестирование на локальной машине и "не выключая utorrent" я вообще слабо понимаю какой смысл.

Марат Абраров комментирует...

непонятно в чём тестирование. Интересно сравнить азио с либэвент или с сырым АПИ, вы же просто профилируете азио.

Пока просто профилирую. Для начала, хочу посмотреть overhead (он должен быть, особенно при использовании пула потоков с одним экземпляром asio::io_service) и попробовать пару профилировщиков. С libevent и пр. рад бы сравнить, да нет времени. Пробовал сравнить с ProstoServer - результаты невнятные (неустойчивые) - нужно что-то придумать в плане методики теста.


Оно сейчас тормозит что ли?

Да, под Linux жалуются, в т.ч. и на то, что написал я.


хочется увидеть реальные цифры

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


Вообще лучше txt использовать.

Вообще-то сначала был CSV. Но в нем не посчитаешь/не посортируешь и не пофильтруешь, поэтому взял тот табличный процессор, что оказался под рукой. "VC-шный профиль" выложил "просто так": кому-то не нужен – может проходить мимо.


Про тестирование на локальной машине и "не выключая utorrent" я вообще слабо понимаю какой смысл.

Просто описал среду, в которой все проводилось. На локальной машине - потому что дома нет локальной сети. Доступ к локальной сети есть, но в ней нет машин даже с 4-ядерными процессорами. Как раз в эти выходные гоняю в этой сети то же самое но на Intel VTune.

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

Nikki Chumakov комментирует...

Марат,

Меня больше интересует случай linux, просто потому что серверов с виндами вокруг не наблюдается.

Я понимаю, что asio использует для linux и для windows принципиально разную диспетчеризацию i/o, что может (точнее - не может не) повлиять на результаты и характер нагрузки.

Я так же понимаю, что тестирование на двух машинах и на одной дадут разный рисунок в профайлере.

Тем не менее мне кажется тема интресная и нужная. Со своей стороны я продолжу тесты как только позволит время - через 1-2 недели.

Если вам от меня нужны конкретные (какие?) логи профайлеров (каких?), пишите, постараюсь сделать.

Марат Абраров комментирует...

Меня больше интересует случай linux, просто потому что серверов с виндами вокруг не наблюдается

Не сомневался. Учитывая ваше текущее место работы, можно было это и не писать :)


Я понимаю, что asio использует для linux и для windows принципиально разную диспетчеризацию i/o, что может (точнее - не может не) повлиять на результаты и характер нагрузки.

Это, конечно, так. Но вот что удивительно - Windows не главная, а, скорее, "побочная" платформа, для автора Asio. В отличие от Linux. Да и мне не хотелось бы видеть на Asio ярлык "best at Windows" - такие специализированные библиотеки уже есть, и они, скорее всего, за счет своей профильности обгоняют Asio в производительности.


Я так же понимаю, что тестирование на двух машинах и на одной дадут разный рисунок в профайлере.

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


Тем не менее мне кажется тема интресная и нужная.

Да. Давно хотел измерить Asio overhead и поискать Asio bottlenecks. Ваши комментарии к предыдущему моему сообщению несколько ускорили это желание.


Если вам от меня нужны конкретные (какие?) логи профайлеров (каких?), пишите, постараюсь сделать.

Вы хотели попрофилировать VTune-ом echo_server.


P.S. Не отпускает холиварная мысль о том, что идея IOCP все же лучше похожего на костыль epoll. Что-то не получается найти ту статью, где сравниваются Windows IOCP, Solaris I/O CP, epoll, kqueue. В выводе там было что-то наподобие: "Windows IOCP - идеальный в теории вариант, epoll - практичный подход, Solaris I/O CP - где-то между первыми двумя."

Марат Абраров комментирует...

Надо заметить, что, по всей видимости, эффективное использование общего пула потоков для обслуживания всех сокетов сервера невозможно на Linux epoll. И это не проблема Asio. Виновато отсутствие специального планирования потоков исполнения (как в Windows IOCP) - отсутствие LIFO.

Таким образом, получается, что при написании максимально эффективного event based async server на Asio под Linux следует использовать схему io_service-per-working-thread (count of working threads == cpu count). Это пoтребует какого-то (хотя бы тривальные round-robin/fast-random) алгоритма распределения входящих соединений по пулу экземпляров asio::io_service. Кроме того, надо подумать над заменой pthread mutex внутри asio::io_service на комбинацию spin lock + pthread mutex.

Что ж, попробую изменить echo_server так, чтобы схема работы (shared thread pool based on one instance of io_service vs io_service per working thread) задавалась параметром командной строки.

Nikki Chumakov комментирует...

Буду ждать.

Марат Абраров комментирует...

Буду ждать.

Чего уж тут ждать - в лучшем случае получится то же самое что и в mrps.

В общем, смотрите здесь (SVN): https://asio-samples.svn.sourceforge.net/svnroot/asio-samples/trunk@691. Параметр командной строки --demux_per_work_thread. Для Windows по умолчанию 0 (off), для не-Windows по умолчанию 1 (on).

Марат Абраров комментирует...

Кстати, я тут подумал и пришел к выводу, что паттерн reactor без поддержки со стороны подсистемы планирования потоков ОС (такая поддержка есть в Windows для IOCP - это LIFO + прочие нюансы планирования) обречен на использование selector-per-working-thread. Под это "обречен" попадает самая распространённая серверная платформа - Linux. Не сказать, чтобы это было смертельно (сделал же я эту поддержку в echo_server), но это перекладывает (добавляет) на автора сервера балансировку нагрузки (серверных сокетов) по селекторам реактора. Такая балансировка требует доп. учета и, возможно, ведения статистики по нагрузке каждого из селекторов, т.е. усложняет код сервера. Дает ли это какое-то преимущество (IOCP тоже можно использовать в стиле completion port per working thread)? Не знаю. Неужели нет нужды? Хватает epoll или reactor-like API позволяет более тонко подстраивать приложение под нагрузку?