LinuxForum.Fans
Тема

zlib in Qt and in C

Автор: Peter 13 сообщений 2105 просмотров
#265328

Здравствуйте!

Я обнаружил, что процедура 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.
В чём причина такой большой разницы?

Пётр.

#265375

при компиляции оптимизацию включить не забыли?
для чистоты эксперимента время лучше засекать так: Как вычислить время операции...
ну или минимально демонстрирующий код и результаты time'а в студию...

ну или стандартное объяснение: Qt это C++ с кучей обвески...

#265403

Оптимизация была включена и в программе на Qt и на C.
Мне требовалось реальное время, поэтому я пользовался программой times.
Понятно, что в реальной программе, тем более на Qt, будет замедление,
но не в 5 же раз. Там в главной программе создавалось два потока - один для
веб-камеры, другой для сжатия.

Пётр.

#265426

без кода дальше только на кофейной гуще гадать...

ещё есть способ узнать кто-где и сколько висит: valgrind.
для подробных данных нужна ещё отладочная информация к библиотекам...

#265439

Там ничего особенного:

text

int m;
clock_t cl1,cl2;
struct tms tm1;
...

cl1=times(&tm1);m=compress2(...);cl2=times(&tm1);

Вот разность cl2-cl1 в программе на Qt в 5 раз больше, чем в тестовой на C.
valgrind я когда-то попробовал воспользоваться только один раз, чтобы посмотреть, что это такое.
Попробую, но позже, сейчас не могу. Вообще я надеялся, что кто-нибудь уже сталкивался с этим.

Пётр.

#265459
"Peter" написал:
cl1=times(&tm1);m=compress2(...);cl2=times(&tm1);

до man 2 times я так и не дошёл =)))

"Peter" написал:
Вот разность cl2-cl1 в программе на Qt в 5 раз больше, чем в тестовой на C.

секундочку... в Qt код точно такой же? или аналогичный?

"Peter" написал:
valgrind я когда-то попробовал воспользоваться только один раз, чтобы посмотреть, что это такое.

зря... must-use для чего-то относительно большого...
для профилирования я его тоже только один-два раза использовал... так что из того что помню... там надо будет собрать с оптимизацией и с отладочной информацией(-g) и запустить в режиме профилировщика... на выходе будет файл с информацией о функциях - его надо какой-то там гуйнёй открыть сторонней, ЕМНИП есть под кеды... это если всё ручками делать...
а можно в qt-creator'е - там всё достаточно просто...

#265462

Не заметил, что там такого особенного в man, но и по результатам работы программы на Qt видно,
что показания times соответствуют действительности.
В Qt код точно такой же, иначе что бы я сравнивал. Единственно, что потоку для сжатия указатель
на несжатые данные передаётся из главной программы, а в тестовой всё вместе.
Qt-Creator никогда не использовал.

Пётр.

#265472
"Peter" написал:
Не заметил, что там такого особенного в man

я в man times заглянул и подумал, что извращаетесь с утилиткой...

"Peter" написал:
В Qt код точно такой же, иначе что бы я сравнивал. Единственно, что потоку для сжатия указательна несжатые данные передаётся из главной программы, а в тестовой всё вместе.

мм... я подумал, что через qt'шные средства какие-то, мало ли в qt есть свои биндинги почти для всего.
тогда всё ещё более странно... даже не знаю... а если попробовать второй поток остановить на это время?

и дело это на многопроцессорной машинке происходит?

#265488

Я и сказал, что процессор - Intel четырёхядерный, 2.4GHz, либо 2.0GHz.
В Qt есть свои qCompress/qUncompress, я с них и начал, но с ними не удалось добиться
правильного восстановления изображения, у меня здесь была тема с этим вопросом,
а непосредственно с zlib удалось. Но, возможно, я недостаточно пытался с qCompress.

Остановить второй, а в действительности 1-й поток нельзя, т.к. именно он получает
от веб-камеры кадры, которые декодируются и потом сжимаются compress2.

Пётр.

#265628
"Peter" написал:
Остановить второй, а в действительности 1-й поток нельзя, т.к. именно он получаетот веб-камеры кадры, которые декодируются и потом сжимаются compress2.

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

#265629
Fat-Zer написал:
[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-разрядную систему, но гораздо меньше,
и с прямым вычислением и с оптимизироваанным.

Пётр.

#265664
"Peter" написал:
Ещё одно наблюдение - в одной и той же версии Qt, скомпилированной в 64- и в 32-разрядной Ubuntu,декодирование jpg подпрограммой из Qt выполняется в 1.5 раза быстрее, чем в 32-разрядной.

это не сложно объяснить... Qt обычно (зависит от сборки) сам работает через libjpeg. На x86 сейчас популярна реализация media-libs/libjpeg-turbo, которая сильно зависит от архетектуры под которую её собирают... если для i386, то понятно почему медленно работает... также есть общая реализация: http://jpegclub.org/ что именно в бубунте предположить не возьмусь...

"Peter" написал:
Всё равно не понял, что смотреть, т.к. 2-й поток без 1-го работать не может.1-й принимает jpg и декодирует их в объект QImage, он объявлен в главной программе.Затем главная даёт команду 2-му на сжатие этого объекта, 2-му передаётся его адрес.

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

#265677
Fat-Zer написал:
[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.

Пётр.

Войдите или зарегистрируйтесь, чтобы ответить.