LINUX.ORG.RU

C++, Qt, QTimer, производительность, 1/2000 сек.


0

2

Запускаю 2-3 таймера, у каждого период 1/1000 сек. Ну я не думаю, что Qt main loop все эти таймеры в 1 потоке дёргает - это какой-то умный должен быть менеджер таймеров. Скажем, создал я таймеры с периодом 5 и 3 секунды. Это какой должен быть умный менеджер, чтобы запланировать программу срабатываний 3...5...6...9...10...12...15...18.... Так что проще думать про разные потоки... хотя может и не так сложно, алгоритм можно сочинить. Но это неважно.

Важно то, что 2-3 таймера с интервалом 1/1000 сек (согласен, что килогерц в секунду - это дохрена и это странное использование таймера), подключенные к слоту, в котором написано «return;» и больше ничего, выжирают одно ядро core i5 2500K на 100%.

Я просто хочу спросить - так и должно быть или они многовато у меня жрут?

Вообще я тут анимацию затеял, заюзал интервал 1000/60 - т.е. 60 fps в миллисекундах. 2 таких таймера выжрали 10% проца. Чё-то много. Причём один хрен - есть там анимация в слоте или «return;» написано. Анимация делается через update() данного виджета (т.е. опосредованное дёргание paintEvent). Суть анимации в перерисовке положения некоторых линий - реализация чего-то типа табов броузера хром, когда ты его оттаскиваешь в сторону, отпускаешь и он плавно подъезжает на своё место, сбавляя скорость при подлёте к месту базирования.

qt animation framework не предлагать - не вижу, что это мне даст, там те же таймеры внутри, а по-сути мне всё равно paintEvent виджета хотелось бы дёграть.

Не должна быть такая высокая загрузка... Какая версия Qt? ОС? Версия ОС? DE?

А с одним таймером какая загрузка?

И вообще, что значит 1/1000 сек? Я знаю секунды, миллисекунды, микросекунды...

Далее, советую применить профилировщик perf - сразу поймешь где программа думает:

perf record -g -s ./my_program

а потом штатно выходишь из программы и смотришь, выполняешь в том же каталоге:

perf report -g

Если sudo добавить перед этими двумя командами - будешь видеть символы ядра. Главное отладочные символы для всех библиотек интересующих поставить и для ядра.

I-Love-Microsoft ★★★★★ ()

Это какой должен быть умный менеджер, чтобы запланировать программу срабатываний 3...5...6...9...10...12...15...18.... Так что проще думать про разные потоки... хотя может и не так сложно, алгоритм можно сочинить. Но это неважно.

Если что, таймеры хранятся в связном списке, отсортированном по возрастанию времени срабатывания.

Если упрощенно, QEventDispatcherUNIX смотрит время следующего срабатывания таймера и устанавливает соответствующий timeout для select().

sjinks ★★★ ()

подключенные к слоту, в котором написано «return;»

Связка QObject::startTimer() + QObject::killTimer() + QObject::timerEvent() может оказаться более производительной.

sjinks ★★★ ()
#include <QtCore/QCoreApplication>
#include <QtCore/QTimer>

class MyApplication : public QCoreApplication {
        Q_OBJECT
public:
        MyApplication(int& argc, char** argv) : QCoreApplication(argc, argv) {}
        int exec(void)
        {
                for (int i=0; i<10; ++i) {
                        QTimer* timer = new QTimer(this);
                        timer->setInterval(1);
                        timer->setSingleShot(false);
                        QObject::connect(timer, SIGNAL(timeout()), this, SLOT(timerSlot()));
                        timer->start();
                }

                return QCoreApplication::exec();
        }

private Q_SLOTS:
        void timerSlot(void)
        {
                return;
        }
};


int main(int argc, char** argv)
{
        MyApplication app(argc, argv);
        return app.exec();
}

Даже с 10 таймерами ест не более 4% процессорного времени.

sjinks ★★★ ()

Сигнал-слоты из Qt4 мало пригодны для очень частого использования (от тысячи раз в секунду и более). Это обусловлено тем, что при каждом вызове сигнала идёт сравнение строк и вызывается соответствующий слот.

В Qt5 есть сигнал-слоты (старые тоже есть), которые работают по другому принципу (таблицы связей сигналов и слотов генерируются в compile-time), и в runtime будет гораздо меньший оверхед.

Вот есть бенчмарк: http://pokecraft.first-world.info/wiki/Benchmark_for_conception (хотя там ещё Qt5 alpha)

Хотя я просто рекомендую в этом конкретном случае выкинуть QTimer, взять QBasicTimer и имплементировать timerEvent(). Подробнее здесь https://qt-project.org/doc/qt-4.8/timers.html

Chaser_Andrey ★★★★★ ()

Выкини все эти костыли.

Запили анимацию на javascript и css,вставь все в вебкит-и будет летать в сотни раз быстрее чем с вашими таймерами,и вообще таймеры не понадобятся-потомучто таймеры это костыли для калькуляторов,современные фреймворкам можно указывать пути перемещений и векторную анимацию,и вебкит идеален для этого,даже можешь svg анимацию юзать.

anonymous ()
Ответ на: комментарий от auto12884839

Ты зачем боян выкопал?

Единственный коммент по теме. Остальных комментаторов предлагаю забанить.

anonymous ()

export QT_NO_GLIB=1

anonymous ()

Юзай QAbstractAnimation и не трахай себе мозг, или хотя бы загляни туда и посмотри как они добились плавности.

Gorthauer ★★★★★ ()

килогерц в секунду

anonymous ()
Ответ на: комментарий от anonymous

килогерц в секунду

да, это сильно, единица измерения гиперпространства 8)

I-Love-Microsoft ★★★★★ ()
Ответ на: комментарий от anonymous

килогерц в секунду

Процессор за время между тиками успеет сделать не больше миллиона операций на каждом из ядер.

anonymous ()

1/2000 сек

Вообще-то ядро не более 1000 прерываний по аппаратному таймеру может делать в секунду. А раньше x86 linux kernel HZ был вообще = 100.
Так что таймеры с частотой выше 1000Гц не имеют смысла.

nerdogeek ()

Обсчет анимации произодится обычно перед рендерингом очередного кадра, т.е. с частотой FPS. А еще есть такая вещь как интерполяция и экстраполяция.

nerdogeek ()

Еще можно взять профайлер. Или на худой конец поподключаться gdb к процессу раз 20 и посмотреть по стеку, где он молотит.

ratatosk ()

А в самом ведре есть какие-нибудь расширения для этого? Нужно же как-то делать realtime?

stevejobs ★★★☆☆ ()
Ответ на: комментарий от stevejobs

для ядра пилят патчи для мягкого rt, есть чего-то для попыток жесткого.

arkhnchul ★★ ()
Ответ на: комментарий от Chaser_Andrey

Сее чувствовалось где-то на уровне жопного интуитивного рецептора )

kiverattes ★☆ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.