Russian Qt Forum
Ноябрь 23, 2024, 08:39 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3   Вниз
  Печать  
Автор Тема: Производительность сигнал/слотов и чем их можно заменить?  (Прочитано 21050 раз)
gidrowolf
Гость
« : Февраль 22, 2012, 22:11 »

Дали мне задания создать высоконагруженный сервер для приема, обработки и отправки информации. Так как я пока что "зеленый" и не имел дела с высоконагруженными серверами, а сделать надо за неделю то по глупости решил положиться на кьютовские сигнал/слоты.
Расчет делается на то что он должен выдерживать 100 000 соединений и каждое соединение раз в секунду шлет данные.
На прием, обработку, отправку(каждая операция производится в отдельном потоке) для одного соединения в лучшем случае составляет 4 междупоточных сигнала, то-есть целых 400 000 сигналов в секунду.
В интернете попытался найти информацию по производительности и наткнулся на статью в которой утверждалось что типа на процессоре i586-500 кьют позволяет отослать 2 000 000 сигналов. Ну успокоившись, этого-то точно должно хватить я решил потестить на своем Athlon 64 X2 4800+ (2.5GHz). И каково же было мое удивление что съев почти одно ядро кьют генерировал всего 80 000 сигналов. От чего так мало?
На какой более производительный аналог кьют сигналов можно наименее безболезненно заменить?
Записан
Bepec
Гость
« Ответ #1 : Февраль 23, 2012, 09:19 »

400000 сигналов в секунду. 400 сигналов в милисекунду...

Интересно, у вас программа сразу загнётся или нет? Показает язык
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #2 : Февраль 23, 2012, 10:21 »

В интернете попытался найти информацию по производительности и наткнулся на статью в которой утверждалось что типа на процессоре i586-500 кьют позволяет отослать 2 000 000 сигналов. Ну успокоившись, этого-то точно должно хватить я решил потестить на своем Athlon 64 X2 4800+ (2.5GHz). И каково же было мое удивление что съев почти одно ядро кьют генерировал всего 80 000 сигналов. От чего так мало?
Генерировать-то он может на вашем проце и значительно больше 2кк сигналов, а если через очередб, то ~800к в секунду (хотя вероятно зависит от аргументов).
А вот обрабатывать их у вас  вряд ли получится с такой скоростью.
Записан
gidrowolf
Гость
« Ответ #3 : Февраль 23, 2012, 12:08 »

400000 сигналов в секунду. 400 сигналов в милисекунду...

Интересно, у вас программа сразу загнётся или нет? Показает язык
Ну прямых вызовов за миллисекунду целых 500 000. Еслиб сигналы были всего-лишь в 100 раз медленнее, то было бы хорошо.

Генерировать-то он может на вашем проце и значительно больше 2кк сигналов, а если через очередб, то ~800к в секунду (хотя вероятно зависит от аргументов).
А вот обрабатывать их у вас  вряд ли получится с такой скоростью.
Ну так я сделал тест: три потока main, loop, sendLoop.
sendLoop после запуска посылает сам себе сигнал process. Функция process делает всего две вещи: посылает сигнал process и nextLoop потоку loop.
Функция nextLoop в loop делает всего одну вещь: инкрементирует счетчик.
main раз в секунду считывает счетчик и обнуляет его.
То-есть в результате sendLoop бесконечно генерирует сигналы и посылает их в loop, а loop тупо инкрементирует счетчик. И происходит это всего 80 000 раз в секунду. Я прям разочаровался, ибо если напрямую делать вызовы то получается от 300 000 000 до 1 000 000 000 (значения скачут сильно) вызовов. То-есть сигналы в среднем в 5 000 раз медленнее прямых вызовов, что печалит. Я надеялся что будет медленнее всего в 100-200 раз.
Записан
Странник
Гость
« Ответ #4 : Февраль 23, 2012, 12:14 »

а давно высоконагруженные сервера на Qt писать стали?
Записан
mutineer
Гость
« Ответ #5 : Февраль 23, 2012, 12:26 »

Я прям разочаровался, ибо если напрямую делать вызовы то получается от 300 000 000 до 1 000 000 000 (значения скачут сильно) вызовов. То-есть сигналы в среднем в 5 000 раз медленнее прямых вызовов, что печалит. Я надеялся что будет медленнее всего в 100-200 раз.

Ну так ты сравниваешь прямой вызов метода (грубо говоря прыжок на адрес) с созданием и передачей объекта-сообщения через QEventLoop. Конечно межпоточные сигналы сильно медленнее получаются
Записан
gidrowolf
Гость
« Ответ #6 : Февраль 23, 2012, 12:28 »

а давно высоконагруженные сервера на Qt писать стали?
А что Вы посоветуете использовать для высоконагруженных серверов? Просто не очень хочется использовать связку прямые вызовы + мьютексы, ибо я их нормально врятли смогу использовать.
Хочется просто информировать другой поток что он должен добавить в очередь выполнения функцию, и чтоб это максимально быстро было.
Было бы неплохо еслиб посоветовали литературу по этой области, ибо я даже не знаю куда копать.
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #7 : Февраль 23, 2012, 12:28 »

То-есть в результате sendLoop бесконечно генерирует сигналы и посылает их в loop, а loop тупо инкрементирует счетчик. И происходит это всего 80 000 раз в секунду. Я прям разочаровался, ибо если напрямую делать вызовы то получается от 300 000 000 до 1 000 000 000 (значения скачут сильно) вызовов. То-есть сигналы в среднем в 5 000 раз медленнее прямых вызовов, что печалит. Я надеялся что будет медленнее всего в 100-200 раз.
Ну если сигнал со слотом так же сконектить напрямую, а не через очередь, то всё тоже будет работать быстрее, только не в том потоке (как и при прямом вызове).
Ну а от очереди сообщений с блокировками вы наврно очень большой произовдительности ожидаете.
Ну а вообще покажите проект, может вы что-то не так делаете.
Записан
gidrowolf
Гость
« Ответ #8 : Февраль 23, 2012, 13:32 »

Ну если сигнал со слотом так же сконектить напрямую, а не через очередь, то всё тоже будет работать быстрее, только не в том потоке (как и при прямом вызове).
Ну а от очереди сообщений с блокировками вы наврно очень большой произовдительности ожидаете.
Ну а вообще покажите проект, может вы что-то не так делаете.
К сожалению проект коммерческий и показать я его не могу. Да и на сервер я еще нагрузку не тестировал(так как программу для тестирования нагрузки писать некогда), пока он обрабатывает до 20 тестовых соединений.
Записан
Странник
Гость
« Ответ #9 : Февраль 23, 2012, 13:53 »

А что Вы посоветуете использовать для высоконагруженных серверов? Просто не очень хочется использовать связку прямые вызовы + мьютексы, ибо я их нормально врятли смогу использовать.
Хочется просто информировать другой поток что он должен добавить в очередь выполнения функцию, и чтоб это максимально быстро было.
Было бы неплохо еслиб посоветовали литературу по этой области, ибо я даже не знаю куда копать.
с Qt вам не избежать проблем производительности, как минимум. в остальном все зависит от специфики задачи и ваших познаний. для распределенного сервера православно будет использовать erlang.
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #10 : Февраль 23, 2012, 14:21 »

К сожалению проект коммерческий и показать я его не могу.
Я думал, что вы пример для теста сделали и с производительностью заткнулись, а если у вас целый проект уже, то можно только гадать где и что у вас тормозит.
Записан
gidrowolf
Гость
« Ответ #11 : Февраль 23, 2012, 14:27 »

К сожалению проект коммерческий и показать я его не могу.
Я думал, что вы пример для теста сделали и с производительностью заткнулись, а если у вас целый проект уже, то можно только гадать где и что у вас тормозит.
Сам сервер щас работает нормально ибо нагрузка на него маленькая. Просто я решил проверить производительность сигналов дабы приблизительно понять их предел. Ибо когда начнет тормозить будет поздно что-то переделывать.
Записан
once_again_abc
Гость
« Ответ #12 : Март 02, 2012, 00:38 »

а давно высоконагруженные сервера на Qt писать стали?

+пицот =)))
Записан
Bepec
Гость
« Ответ #13 : Март 02, 2012, 13:07 »

У меня вон запара сделать хотя бы 20 вызовов в мс, а тут целых 400 Подмигивающий
Записан
gidrowolf
Гость
« Ответ #14 : Март 02, 2012, 13:41 »

У меня вон запара сделать хотя бы 20 вызовов в мс, а тут целых 400 Подмигивающий
Странно, у меня 20 холостых межпоточных вызовов доходят примерно за 0.3 мс. А если сразу по 20 сигналов посылать, то доходят за 0.04 мс.
Я попробовал посылать по 50 сигналов за раз, так производительность поднялась до 500 000 сигналов в секунду. Только толку от этого нету. Я надеюсь что база данных начнет загибаться раньше чем программа упрется в производительность сигналов.
Записан
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.09 секунд. Запросов: 23.