09.08.2015

Немного статистики

Покопался немного в своей программке сжатия. Выяснил, что никакой ошибки в работе с динамической памятью у меня не было.
Похоже, это любо глюк Delphi, либо Windows. Или, наоборот, это фича такая?

При многократном рендеринге в битмап возникает "тихая" ошибка. Точнее, с какой-то итерации рендеринг прекращается, ошибки не возникает, а исходный битмап не меняется. Рендеринг, это на самом деле BitBlt с десктопа. Идея была в том, что бы не создавать на каждой итерации TBitmap, а просто рендерить в один раз созданный. Естественно, ради производительности. Но, похоже, издержки по создания TBitmap не так уж высоки, поэтому пока отложил этот вопрос куда-то в неопределенное будущее.

Параллельно посмотрел статистику, какие же операции наиболее затратные при сжатии видео. У меня были некие идеи о том, какие операции будут наиболее медленным. Но я их вообще не угадал. )))


Процесс Время, с % от общего времени
Screen copy 14.724 11.60%
Color conversation 13.649 10.75%
Wavelet conversation 57.431 45.24%
Data loss reduction 23.41 18.44%
RLE reduction 13.087 10.31%
Haffman coding 4.65 3.66%

Совершенно неожиданно, больше всего заняло wavelet-преобразование, несмотря на его простоту. Соответственно, можно ожидать и большого эффекта от оптимизации этого кода.

Планирую использовать два подхода при оптимизации. Первый - это SIMD, так как wavelet-преобразование производится на каждой точке изображения. Теоретически, в зависимости от используемого набора команд SSE, следует ожидать 4-х или 8-ми кратного прироста производительности. На практике, для таких команд надо еще подготовить данные, а потом их разобрать. Поэтому прирост окажется скромнее, но все равно должен быть значительным.

Второй подход состоит в том, что 2, 3 и 4 пункты можно объединить и выполнять в одной процедуре. Каждая из этих процедур обрабатывает целиком все внутреннее представление изображения, которое занимает достаточно солидный объем. Выигрыш здесь потенциально состоит в том, что данные чаще будут попадать в кэш, это снизит нагрузку на подсистему памяти и повысит производительность. Но будет ли существенный эффект от этого?
С другой стороны, наличие большого количества этапов сжатия позволит организовать длинный конвейер в случае многопоточного варианта сжатия. Это также может поднять производительность, но несколько противоречит второму подходу. Поэтому пока раздумываю, нужно ли это.

Также можно примерно оценить и то, сколько можно снять копий экрана в секунду, при максимальной загрузке одного ядра и использовании операции BitBlt. По результатам статистики, если убрать все остальные операции, это даст примерно 9 кадров в секунду. С учетом того, что ядро в текущем варианте загружено в среднем на 30-40 процентов, можно ожидать съема до 20-30 кадров в секунду.

2 комментария:

  1. Любите Вы ассемблер :)

    Интересно бы посмотреть на сколько современные C/C++ компиляторы умеют применять SIMD там где можно. Хотя бы для простых случаев, а сложные разработчик приведет к простым :) Всяко понятнее должно быть чем ассемблер.

    ОтветитьУдалить
  2. Ага, есть такое дело. Чисто развлекуха...

    Да, интересный момент насчет компиляторов. По моим наивным представлениям - не могут. Скорее всего, просто под SIMD оптимизированы функции обработки массивов, и, при ее вызове,в зависимости от версии процессора, подставляется тот или иной оптимизированный вариант.
    Хотя, скорее всего не прав. SIMD уже в обед сто лет, еще старенькие крэи умели такое делать, может, оптимизаторы компиляторов весьма интеллектуальные и умеют такое вытворять с любыми циклами, написанными человеком. )

    ОтветитьУдалить