Здравствуйте!
Я обнаружил, что процедура compress2 из zlib в рабочей программе на Qt работает в 4-6 раз
медленее, чем в тестовой на C. Есть поток jpg с веб-камеры, в программе на Qt кадры
декодируются в QImage в RGB32, это 4 байта на пиксел. Если сохранить jpg на диск,
программой display преобразовать его в bmp, то в тестовой программе на C он сжимается
за 19 ms. display сохраняет с тремя байтами на пиксел. Если в Gimp преобразовать этот jpg
в bmp с четырьмя байтами на пиксел, то тестовая программа сжимает его за 25 ms, а в рабочей
программе на Qt объект QImage сжимается за 100 - 120ms. Время засекалось командой times,
в программе на Qt сжатие вынесено в отдельный поток, процессор Intel, четырёхядерный.
Степень сжатия везде была наименьшей - 1.
В чём причина такой большой разницы?
Пётр.
zlib in Qt and in C
при компиляции оптимизацию включить не забыли?
для чистоты эксперимента время лучше засекать так: Как вычислить время операции...
ну или минимально демонстрирующий код и результаты time'а в студию...
ну или стандартное объяснение: Qt это C++ с кучей обвески...
Оптимизация была включена и в программе на Qt и на C.
Мне требовалось реальное время, поэтому я пользовался программой times.
Понятно, что в реальной программе, тем более на Qt, будет замедление,
но не в 5 же раз. Там в главной программе создавалось два потока - один для
веб-камеры, другой для сжатия.
Пётр.
без кода дальше только на кофейной гуще гадать...
ещё есть способ узнать кто-где и сколько висит: valgrind.
для подробных данных нужна ещё отладочная информация к библиотекам...
Там ничего особенного:
int m;
clock_t cl1,cl2;
struct tms tm1;
...
cl1=times(&tm1);m=compress2(...);cl2=times(&tm1);
Вот разность cl2-cl1 в программе на Qt в 5 раз больше, чем в тестовой на C.
valgrind я когда-то попробовал воспользоваться только один раз, чтобы посмотреть, что это такое.
Попробую, но позже, сейчас не могу. Вообще я надеялся, что кто-нибудь уже сталкивался с этим.
Пётр.
cl1=times(&tm1);m=compress2(...);cl2=times(&tm1);
до man 2 times я так и не дошёл =)))
Вот разность cl2-cl1 в программе на Qt в 5 раз больше, чем в тестовой на C.
секундочку... в Qt код точно такой же? или аналогичный?
valgrind я когда-то попробовал воспользоваться только один раз, чтобы посмотреть, что это такое.
зря... must-use для чего-то относительно большого...
для профилирования я его тоже только один-два раза использовал... так что из того что помню... там надо будет собрать с оптимизацией и с отладочной информацией(-g) и запустить в режиме профилировщика... на выходе будет файл с информацией о функциях - его надо какой-то там гуйнёй открыть сторонней, ЕМНИП есть под кеды... это если всё ручками делать...
а можно в qt-creator'е - там всё достаточно просто...
Не заметил, что там такого особенного в man, но и по результатам работы программы на Qt видно,
что показания times соответствуют действительности.
В Qt код точно такой же, иначе что бы я сравнивал. Единственно, что потоку для сжатия указатель
на несжатые данные передаётся из главной программы, а в тестовой всё вместе.
Qt-Creator никогда не использовал.
Пётр.
Не заметил, что там такого особенного в man
я в man times заглянул и подумал, что извращаетесь с утилиткой...
В Qt код точно такой же, иначе что бы я сравнивал. Единственно, что потоку для сжатия указательна несжатые данные передаётся из главной программы, а в тестовой всё вместе.
мм... я подумал, что через qt'шные средства какие-то, мало ли в qt есть свои биндинги почти для всего.
тогда всё ещё более странно... даже не знаю... а если попробовать второй поток остановить на это время?
и дело это на многопроцессорной машинке происходит?
Я и сказал, что процессор - Intel четырёхядерный, 2.4GHz, либо 2.0GHz.
В Qt есть свои qCompress/qUncompress, я с них и начал, но с ними не удалось добиться
правильного восстановления изображения, у меня здесь была тема с этим вопросом,
а непосредственно с zlib удалось. Но, возможно, я недостаточно пытался с qCompress.
Остановить второй, а в действительности 1-й поток нельзя, т.к. именно он получает
от веб-камеры кадры, которые декодируются и потом сжимаются compress2.
Пётр.
Остановить второй, а в действительности 1-й поток нельзя, т.к. именно он получаетот веб-камеры кадры, которые декодируются и потом сжимаются compress2.
я предлагаю не остановить и так оставить, а просто посмотреть "а что получится"... если проблему это не решит, то собака скорей всего зарыта где-то в самом кьюте или кривом вызове compress2()... иначе что-то не так с распараллеливанием... один QMutex не так сложно добавить...
[quote="Peter"]Остановить второй, а в действительности 1-й поток нельзя, т.к. именно он получаетот веб-камеры кадры, которые декодируются и потом сжимаются compress2.
я предлагаю не остановить и так оставить, а просто посмотреть "а что получится"... если проблему это не решит, то собака скорей всего зарыта где-то в самом кьюте или кривом вызове compress2()... иначе что-то не так с распараллеливанием... один QMutex не так сложно добавить...[/quote]
Всё равно не понял, что смотреть, т.к. 2-й поток без 1-го работать не может.
1-й принимает jpg и декодирует их в объект QImage, он объявлен в главной программе.
Затем главная даёт команду 2-му на сжатие этого объекта, 2-му передаётся его адрес.
QMutex там ни к чему, т.к. там нет конкуренции. Сначала заполняется QImage, потом сжимается и т.д.
Т.е. там главная программа и два потока на четырёхядерном процессоре.
Ещё одно наблюдение - в одной и той же версии Qt, скомпилированной в 64- и в 32-разрядной Ubuntu,
декодирование jpg подпрограммой из Qt выполняется в 1.5 раза быстрее, чем в 32-разрядной.
Моя подпрограмма декодирования тоже ускоряется при переходе на 64-разрядную систему, но гораздо меньше,
и с прямым вычислением и с оптимизироваанным.
Пётр.
Ещё одно наблюдение - в одной и той же версии Qt, скомпилированной в 64- и в 32-разрядной Ubuntu,декодирование jpg подпрограммой из Qt выполняется в 1.5 раза быстрее, чем в 32-разрядной.
это не сложно объяснить... Qt обычно (зависит от сборки) сам работает через libjpeg. На x86 сейчас популярна реализация media-libs/libjpeg-turbo, которая сильно зависит от архетектуры под которую её собирают... если для i386, то понятно почему медленно работает... также есть общая реализация: http://jpegclub.org/ что именно в бубунте предположить не возьмусь...
Всё равно не понял, что смотреть, т.к. 2-й поток без 1-го работать не может.1-й принимает jpg и декодирует их в объект QImage, он объявлен в главной программе.Затем главная даёт команду 2-му на сжатие этого объекта, 2-му передаётся его адрес.
ладно, я окончательно запутался... мне всегда сложно было ваши посты и ход мыслей воспринимать...
[quote="Peter"]Ещё одно наблюдение - в одной и той же версии Qt, скомпилированной в 64- и в 32-разрядной Ubuntu,декодирование jpg подпрограммой из Qt выполняется в 1.5 раза быстрее, чем в 32-разрядной.
это не сложно объяснить... Qt обычно (зависит от сборки) сам работает через libjpeg. На x86 сейчас популярна реализация media-libs/libjpeg-turbo, которая сильно зависит от архетектуры под которую её собирают... если для i386, то понятно почему медленно работает... также есть общая реализация: http://jpegclub.org/ что именно в бубунте предположить не возьмусь...
[/quote]
Насколько я помню, в обоих случаях я компилировал Qt со своей libjpeg: -qt-libjpeg. Версия 4.7.2.
Пётр.