Название: Накладные расходы слот-сигнал Отправлено: Igors от Октябрь 25, 2014, 14:42 Добрый день
Понятно что тема эта жевалась еще много лет назад, но поиском по форуму не пользовался. Начну сомневаться, перепроверять, в итоге не хватит времени и заглохнет на неопределенный срок. Поэтому как есть. При каком конкретно времени исполнения слота (вкупе с частотой сигналов) эти расходы становятся ощутимыми? Конечно результат зависит от машины, платформы и версии Qt. Для данных ниже; скромный Хeon 2.66, 4 ядра, Qt 4.7.4, OSX 10.7.5 и даже Debug build. Что и как меряем Сначала вызываем тело слота (нагрузку) напрямую и засекаем сколько раз оно выполнилось в секунду. Затем испускаем такое же кол-во сигналов (неск способами) в секунду и смотрим сколько раз сработал слот в секунду. Отношение этих 2 замеров и даст оверхед. Понятно что если нагрузка достаточно велика - никакого оверхеда вообще не увидим. Поэтому тестировались 2 задачи а) "min Job" (холостой ход) тело слота почти пустое. Ну ++ к паре счетчиков, if (раз в 10К) и печать раз в секунду. Ну плюс деструктор аргумента QStringList (сводится к имплисит шаре) b) "1K Job" то же что "a" но добавлено изменения QStringList (100 строк по 10 символов), теперь он уже будет реально скопирован и удален. Результаты холостого хода Цитировать --------- Test min Job ------------ Тут ничего особенного, Понятно что DirectConnection чего-то весит, QueuedConnection еще большеTest 1 direct call: received/sec 13424576.0 received/sec 13580420.0 received/sec 13573427.0 received/sec 13577423.0 total received = 54210000 Test 2 direct signal: received/sec 1644355.6 received/sec 1664335.6 received/sec 1664335.6 received/sec 1664335.6 total received = 6644000 Test 3 queued signal: received/sec 90367.4 received/sec 95378.6 received/sec 104685.9 received/sec 110889.1 total received = 404000 Цитировать Test 4 queued signal multi-sender: А вот тут уже интереснее. То же число сигналов посылается не одной. а 3-мя нитками. Ядер хватает, но скорость резко упала, ведь за мутекс дерутся уже не 2 а 4 нитки. Что будет дальше (при большем числе "испускающих") - не проверял received/sec 9442.9 received/sec 9624.6 received/sec 9182.7 received/sec 10018.2 total received = 41000 Результаты небольшой нагрузки Цитировать --------- Test 1K Job ------------ Вполне ожидаемо - чем больше нагрузка, тем стабильнее. Разница Direct/Queued уже невелика, но проседание на последнем тесте все еще вдвое. Хотя кто знает, может это я где-то ошибсяTest 1 direct call: received/sec 21526.4 received/sec 21442.5 received/sec 21442.5 received/sec 21421.6 total received = 88000 Test 2 direct signal: received/sec 21317.8 received/sec 21153.8 received/sec 21174.2 received/sec 21153.8 total received = 88000 Test 3 queued signal: received/sec 19802.0 received/sec 19665.7 received/sec 19120.5 received/sec 19743.3 total received = 80000 Test 4 queued signal multi-sender: received/sec 9132.4 received/sec 9242.1 received/sec 9311.0 received/sec 9389.7 total received = 40000 Остальное см в прилагаемых исходниках. Ну вот, я кажется начал писать блоги :'( Название: Re: Накладные расходы слот-сигнал Отправлено: kuzulis от Октябрь 27, 2014, 11:30 А ты в development (или interest) рассылку кинь это все. Мож там что-то конкретное ответят про проседание и прочее. А то тут много всяких "комментаторов" сейчас понабежит. :)
Название: Re: Накладные расходы слот-сигнал Отправлено: qate от Октябрь 27, 2014, 12:37 если гдето ответят - отпишись тут )
а если завести 4 qeventloop-a и в каждом бросать сигналы и ловить слоты - может ядра загрузятся ? Название: Re: Накладные расходы слот-сигнал Отправлено: vulko от Октябрь 27, 2014, 13:08 А вот тут уже интереснее. То же число сигналов посылается не одной. а 3-мя нитками. Ядер хватает, но скорость резко упала, ведь за мутекс дерутся уже не 2 а 4 нитки. Что будет дальше (при большем числе "испускающих") - не проверял Это вот эта глобальная (ахтунг!) переменная - мьютекс, то?))) Код: QSemaphore theSemaphore; Да и вообще непонятно что тут замеряется и в чем вопрос? Разница между DirectConnection и QueuedConnection ровно в том что, первое выполнит слот в потоке в котором был сигнал, а второе выполнит слот в потоке где живет объект, у которого он вызывается. Вызов через event loop и соотв. отсюда и разница во времени выполнения. А "проседания", которые вовсе не проседания, а разные типы выполнения слотов, сильно зависят от кода. В данном случае он такой, в другом случае другие цифры будут. Название: Re: Накладные расходы слот-сигнал Отправлено: xokc от Октябрь 27, 2014, 13:14 Да и вообще непонятно что тут замеряется и в чем вопрос? Что замеряется понятно, а вот в чем вопрос, действительно, не понятно. :)Название: Re: Накладные расходы слот-сигнал Отправлено: vulko от Октябрь 27, 2014, 14:22 Да и вообще непонятно что тут замеряется и в чем вопрос? Что замеряется понятно, а вот в чем вопрос, действительно, не понятно. :)Понятно?) Точно?) Цитировать А вот тут уже интереснее. То же число сигналов посылается не одной. а 3-мя нитками. Ядер хватает, но скорость резко упала, ведь за мутекс дерутся уже не 2 а 4 нитки. Что будет дальше (при большем числе "испускающих") - не проверял Откуда 2-а? NUM_SENDER = 1 в исходниках. Небольшой тизер... Код: void CReceiver::SlotGet( QStringList lst ) Тут весь проект сделан через не то место. Нормальные замеры делают так - 1 000 000 вызовов directcall, 1 000 000 queuedconnection. Замеряется время затраченное в первом и во втором случае. Далее 1 000 000 вызовов делится на количество секунд, и получается количество вызовов в секунду. А тут что? А когда потоков сендеров >1 тут вообще полный писец. И что же в итоге замеряется? Как полное отсутсвие хоть сколь-нибудь продуманной архитектуры сказывается на производительности? Название: Re: Накладные расходы слот-сигнал Отправлено: Пантер от Октябрь 27, 2014, 15:19 Может, я что-то не понял, но директ коннекшн транслируется в прямой вызов. Накидал очень быструю тестовую прогу, все норм:
31742 - прямой вызов 32637 - direct 34128 - queue Это затраченное время в мс на 1000000 итераций. Название: Re: Накладные расходы слот-сигнал Отправлено: vulko от Октябрь 27, 2014, 15:30 Может, я что-то не понял, но директ коннекшн транслируется в прямой вызов. Накидал очень быструю тестовую прогу, все норм: 31742 - прямой вызов 32637 - direct 34128 - queue Это затраченное время в мс на 1000000 итераций. Это не совсем корректно. Лучше делать замеры между вызовом emit signal и непосредственным вызовом slot'а. Название: Re: Накладные расходы слот-сигнал Отправлено: Пантер от Октябрь 27, 2014, 15:32 Может, я что-то не понял, но директ коннекшн транслируется в прямой вызов. Накидал очень быструю тестовую прогу, все норм: 31742 - прямой вызов 32637 - direct 34128 - queue Это затраченное время в мс на 1000000 итераций. Это не совсем корректно. Лучше делать замеры между вызовом emit signal и непосредственным вызовом slot'а. Название: Re: Накладные расходы слот-сигнал Отправлено: Пантер от Октябрь 27, 2014, 15:46 Вопщем, я к тому, что у DirectConnection будет незначительная просадка, по отношению к прямому вызову. QueueConnection будет значительно им уступать, но тут все логично.
Название: Re: Накладные расходы слот-сигнал Отправлено: xokc от Октябрь 27, 2014, 19:35 Если речь идет об одном потоке писателе и одном читателе - тут всё понятно. Интереснее вопрос насколько успешно система сигнал/слотов разрулит ситуацию с несколькими (многими) писателями и несколькими (многими) читателями. А также то, насколько она в этом смысле эффективнее (или не эффективнее), например, очереди на QAtomic или неблокирующей очереди из liblfds.org. Или очереди на ZeroMQ. И так далее.
Название: Re: Накладные расходы слот-сигнал Отправлено: qate от Октябрь 28, 2014, 08:24 А также то, насколько она в этом смысле эффективнее (или не эффективнее), например, очереди на QAtomic или неблокирующей очереди из liblfds.org. Или очереди на ZeroMQ. И так далее. чтобы внедрять "другие" очереди в проект на qt - это надо действительно иметь причину (не баг) для этого о таких случаях я нигде не читал (не говорю что читал многое) Название: Re: Накладные расходы слот-сигнал Отправлено: vulko от Октябрь 28, 2014, 09:22 Если речь идет об одном потоке писателе и одном читателе - тут всё понятно. Интереснее вопрос насколько успешно система сигнал/слотов разрулит ситуацию с несколькими (многими) писателями и несколькими (многими) читателями. А также то, насколько она в этом смысле эффективнее (или не эффективнее), например, очереди на QAtomic или неблокирующей очереди из liblfds.org. Или очереди на ZeroMQ. И так далее. Сигнал-слоты это не производительное решение, т.к. queuedconnection не подразумевает быстрого отклика, а direct connection вообще не подходит для многопоточного использования. В этом контексте мне непонятно о какой эффективности ты говоришь. Название: Re: Накладные расходы слот-сигнал Отправлено: vulko от Октябрь 28, 2014, 09:25 Вопщем, я к тому, что у DirectConnection будет незначительная просадка, по отношению к прямому вызову. QueueConnection будет значительно им уступать, но тут все логично. Именно. При этом direct и queued connection'ы - это абсолютно разные вещи. Один для однопотока, второй для многопотока. Название: Re: Накладные расходы слот-сигнал Отправлено: Igors от Октябрь 28, 2014, 10:45 По поводу измерений. "Давайте вызовем мульен напрямую а потом мульен слот-сигнал, вот и все". Это не годится для queued. Непрерывно помещая сигнал (фактически событие) в очередь, мы постоянно/часто блокируем мутекс очереди, и обработчику трудно извлечь событие. В результате увидим гораздо больший оверхед, который сами же и создали. Поэтому посылается то число сигналов которое обработчик может переварить (получено прямым вызовом), и не все сразу а равномерно (порциями).
Тут одна неточность - для queued меряем только время приема, но ведь есть еще и посылка (которая сейчас в др нитке/ядре) Как этим пользоваться. Запустить и посмотреть оверхед queued c небольшой нагрузкой. Напр вижу он не больше 10%, меня устраивает. Если нет - подкрутить константу NUM_STR (нагрузка больше/меньше). Имеем число обработок в секунду, напр 20K. Это можно считать пропускной способностью очереди, (немного завышенной). Т.е. если мы будем шмалять такие сигналы с частотой 20К/sec, то очередь будет расти и, возможно, переполнится. А вот если 10K (или даже 15K) то нам ничего не грозит, и затраты на слот/сигнал не превышают 10% от полезной работы. Теперь осталось засечь число срабатываний слота в проекте. Пример (с которого все началось). Человек спросил какие проблемы могут быть если на частоте сотни в секунду в теле слота выполняется помещение а контейнер. Эту операцию нет смысла даже мерять - "холостой ход". Да, 90% оверхед, или даже больше. Но при такой ничтожной частоте и потери-то с гулькин нос. Т.е. затратили напр 1 секунду (за неск часов работы приложения). Мы могли сделать то же за 0.1 секунды (в 10 раз быстрее), но зачем? Если речь идет об одном потоке писателе и одном читателе - тут всё понятно. Интереснее вопрос насколько успешно система сигнал/слотов разрулит ситуацию с несколькими (многими) писателями и несколькими (многими) читателями. А также то, насколько она в этом смысле эффективнее (или не эффективнее), например, очереди на QAtomic или неблокирующей очереди из liblfds.org. Или очереди на ZeroMQ. И так далее. С удовольствием приму участие в обсуждении. Но начинать надо "от печки", т.е. с выяснения той частоты где появляется нужда в чем-то более интеллектуальном чем вязка слот-сигнал веников :)а если завести 4 qeventloop-a и в каждом бросать сигналы и ловить слоты - может ядра загрузятся ? У каждой нитки свой (и только один) qeventloop, поэтому не вижу как создать ситуацию "много читателей" (из того же ведра). "Много писателей" - см последний тест, да, пагубно влияет. если гдето ответят - отпишись тут ) Да я, собственно, ничего и не спрашивал :)Название: Re: Накладные расходы слот-сигнал Отправлено: vulko от Октябрь 28, 2014, 11:34 Человек спросил какие проблемы могут быть если на частоте сотни в секунду в теле слота выполняется помещение а контейнер. Наговнокодил кривой пример и продолжает из себя эксперта строить... ;D Я понимаю что у автора руки из жопы растут, но все же, только полный идиот будет делать помещение в контейнер не по ссылке, а копированием, когда речь идет о десятках тысячах таких операций в секунду. Название: Re: Накладные расходы слот-сигнал Отправлено: xokc от Октябрь 28, 2014, 16:23 Но начинать надо "от печки", т.е. с выяснения той частоты где появляется нужда в чем-то более интеллектуальном чем вязка слот-сигнал веников :) Полностью согласен. Кто готов выяснить значение частоты? :)Название: Re: Накладные расходы слот-сигнал Отправлено: Igors от Октябрь 29, 2014, 09:20 Полностью согласен. Кто готов выяснить значение частоты? :) Так его уже выяснили. Напр если тело слота исполняется 20K/сек, то при работе с частотой 15K все хорошо, оверхед невелик. При меньшем времени исполнения слота оверхед будет расти и наоборот.Понятно что если мы помещаем в очередь больше событий чем обработчик успевает прожевать, то очередь будет неуклонно расти, это неизбежно, оверхед слот/сигнала здесь ни при чем. Да, и Qt очередь использует стандартную схему (Q)WaitCondition. По поводу "столкновения на мутексе" - неоднократно замечал что чем больше ниток конкурируют за него, тем хуже скорость, причем значительно. Поэтому и добавил этот тест. Предлагаю такой вывод: основанием для отказа от (удобного) обмена с помощью слот/сигнал могут служить: - высокие требования к пропускной способности очереди (типа 30-40К/сек) - перекосы в планировании типа 10 пишут - 1 читает, также при приличной частоте И то и другое не так уж просто получить :) Напр для первого напрашивается вопрос: а чего такую мелкоту гнать через очередь в таком количестве? Название: Re: Накладные расходы слот-сигнал Отправлено: xokc от Октябрь 29, 2014, 22:32 Переформулирую и конкретизирую вопрос. Частота наполнения очереди - 10 раз в секунду, размер каждого элемента от 128 до 256 кБайт, частота чтения из неё - от 10 до 80 раз в секунду, потоков-писателей 8 шт., читатели (X шт.) объединены в пулы, пусть их количество (пулов в смысле) равно 16. Продолжительность обработки каждого элемента очереди каждым читателем - 1 мс, процессор 24-х ядерный. Чему равно Xmax при требуемой общей загруженности CPU в среднем не более 50%? Без реального моделирования это можно оценить?
Название: Re: Накладные расходы слот-сигнал Отправлено: Igors от Октябрь 30, 2014, 09:23 Переформулирую и конкретизирую вопрос. Частота наполнения очереди - 10 раз в секунду, размер каждого элемента от 128 до 256 кБайт, частота чтения из неё - от 10 до 80 раз в секунду, потоков-писателей 8 шт., читатели (X шт.) объединены в пулы, пусть их количество (пулов в смысле) равно 16. Продолжительность обработки каждого элемента очереди каждым читателем - 1 мс, процессор 24-х ядерный. Чему равно Xmax при требуемой общей загруженности CPU в среднем не более 50%? Без реального моделирования это можно оценить? При конкретно 16 читателях - полагаю ровным счетом ничего не грозит, частота слишком мала. Наверное Вы говорите об обычной/стандартной очереди на (Q)WaitCondition - в случае слот/сигнал не вижу как сделать "много читателей". Если не так понял - поправьте. Сколько ниток-читателей выдержит? Здесь не скажу, надо проверять. Но в любом случае плодить нитки "на каждого" плохо. Не совсем ясно что здесь "пул". |