
- •Оптимизация и доработка цифрового фильтра масштабирования видеоданных
- •Содержание
- •Введение
- •Технологияdirectshow
- •Обзор технологии
- •Фильтр видео масштабирования компании Элекард в контексте технологииDirectShow
- •Методы масштабирования цифровых изображений, применяемые в фильтре компании элекард
- •Метод Ланцоша
- •Способы оптимизации программы на языке си
- •Выбор оптимального алгоритма
- •Вычислительная сложность
- •Выбор команд
- •Зависимость по данным и параллелизм команд
- •Оптимизация имеющейся программной реализации алгоритма
- •Оптимизация циклов
- •Оптимизация проверки условий
- •Оптимизация медленных команд
- •Оптимизация работы с памятью
- •ТехнологияSimd
- •Общее описание
- •Основные особенности применения технологии
- •Использование многопоточности
- •Общие принципы многопоточности
- •Способы программной организации многопоточности
- •Основные аспекты оптимизации многопоточности
- •Постановка задачи
- •Ход выполнения практики
- •Заключение
- •Список использованных источников
ТехнологияSimd
Общее описание
Данная технология предоставляет возможность выполнить одно действие над несколькими единицами однотипных данных, используя всего одну команду Ассемблера.
Начало реализации данного направления было положено с появлением технологии MMX™ [5]. В рамках данной технологии регистры процессора были дополнены восемью 64-разрядных регистров и новыми командами для работы с ними. В связи с этим появилось понятиеупакованного и скалярного режимов. В упакованном режиме операция применяется к отдельным элементам данных, упакованным в операндах источника и приемника. В скалярном же режиме операция применяется только к младшему элементу данных источника и приемника [5].
С появлением процессоров PentiumIIIпоявилось развитие технологииSIMDв видеSSE-команд. Затем были добавлены наборы командSSE2,SSE3 иSSE4. В набор регистров процессора были добавлены 128-битные регистры, позволяющие обрабатывать данные как целого, так и вещественного типов в упакованном и скалярном режимах.
В настоящее время, в зависимости от компилятора, существует до четырех способов применения данных команд [5]:
библиотеки классов С++;
внутренние команды компилятора;
ассемблер (подставляемый и непосредственный);
автоматическая векторизация.
Наиболее интересными с точки зрения программиста представляются два последних способа.
Использование автоматической векторизации существенно облегчает разработку прикладных программ. Исходный код программы, написанной на языке Си, не нужно изменять, что сохраняет простоту отладки и понимания кода. Ответственность за использование всей полноты преимуществ технологии SIMDи всех ее нововведений возлагается на компилятор. Очевидно, такой подход усложняет разработку компилятора, и он оказывается не всегда способным выделитьSIMD-команды из последовательного кода [5].
Применение непосредственного ассемблера позволяет использовать весь набор команд процессора. Кроме того, существую компиляторы ассемблера (например, NASM), позволяющие создавать кроссплатформенный код (в отличие от подстановочного ассемблера). Функции, написанные на ассемблере, легко интегрируются в программу на языке Си.
Стоит отметить, что процедуру на ассемблере труднее отладить и понять. Еще одним недостатком является и то, что с появлением новых наборов команд, код придется частично или полностью переписывать с целью получения преимуществ нововведений. Учитывая эти недостатки, непосредственное применение ассемблера оправдано только в приложениях, где требования к производительности максимально высоки и автоматическая векторизация не оказывается достаточно эффективной.
Основные особенности применения технологии
Технология SIMDпредусматривает несколько аспектов, призванных обеспечить максимально эффективное ее использование.
Прежде всего, это выравнивание данных. Для семейства команд, начиная с SSE, данные должны быть выровнены на 16-байтную границу [5]. Это существенно повышает скорость выполнения команд. Существуют и эквивалентные команды, позволяющие работать с данными без предварительного выравнивания, однако обычно их латентность существенно больше. Для объявления выровненных данных в некоторых компиляторах (в частности,MSVC) предусмотрена специальная директива:__declspec(align(база, смещение)). Например, объявление выровненного на 16-байтную границу массива целых чисел можно представить следующим образом:
__declspec(align(16)) int a[N];
Для независимости от компилятора можно обеспечить выравнивание простыми средствами языка Си. Например, память под 128 целочисленных элементов можно выделить следующим образом [5]:
Int *pBuf, *pBufOrig;
pBufOrig = (int *) malloc (128*sizeof(int) + 15);
pBuf = (int*)(((int)pBufOrig + 15) & ~0x0f);
В данном примере сначала выделяется память под массив pBufOrigбез выравнивания. Затем значение указателя на выделенную область памяти выравнивается и заносится в новый указатель. При этом следует учитывать, что при окончании использования массива необходимо освобождать память для указателяpBufOrig, в противном случае произойдет утечка памяти.
Следующим важным аспектом является организация данных, позволяющая максимально использовать упакованный режим в технологии SIMD.
Рассмотрим задачу скалярного перемножения восьми векторов, каждый из которых состоит из четырех вещественных чисел одинарной точности:
__declspec(align(16)) float A[4], B[4], C[4], D[4], W[4], X[4], Y[4], Z[4];
__declspec(align(16)) float Res[4];
for(int i=0; i<4; i++)
{
Res[0] += A[i]*W[i];
Res[1] += B[i]*X[i];
Res[2] += C[i]*Y[i];
Res[3] += D[i]*Z[i];
}
В данном примере нам потребуется выполнить 16 операций умножения, и 16 операций сложения.
В технологии SIMDможно легко поместить сразу один вектор в регистр, а также перемножить два вектора между собой, но возникает сложность при получении суммы вычисленных произведений. Для устранения этой проблемы, данные лучше реорганизовать так, чтобы векторAсостоял только из элементовA[0],B[0],C[0],D[0], векторBсостоял только из элементовA[1],B[1],C[1],D[1], векторCсостоял только из элементовA[2],B[2],C[2],D[2] и, наконец, векторDдолжен состоять из элементовA[3],B[3],C[3],D[3]. Аналогичным же образом нужно переупорядочить и элементы векторовW,X, Y, Z. В результате преобразований получим новые векторыAM,BM,CM,DM,WM,XM,YMиZM. Теперь мы сможем за 4 операции умножения и 4 операции сложения получить искомый результат. Приведем пример реализации на Ассемблере:
movaps xmm0, AM
movaps xmm1, WM
mulps xmm0, xmm1
movaps xmm1, BM
movaps xmm2, XM
mulps xmm1, xmm2
movaps xmm2, CM
addps xmm0, xmm1
movaps xmm1, YM
mulps xmm2, xmm1
movaps xmm1, DM
addps xmm0, xmm2
movaps xmm2, ZM
mulps xmm1, xmm2
addps xmm0, xmm1
movaps Res, xmm0
В итоге в массиве Resмы получили результат произведения каждого из исходных векторов. В данном фрагменте мы постарались обойтись минимальным количеством регистров, а также учесть пропускную способность команд и чередовать различные команды, независимые по данным.
Помимо правильной организации данных, необходимо еще и правильно выбрать тип данных. К примеру, если бы мы в предыдущем примере работали с вещественными числами двойной точности, то таким же количеством команд мы бы смогли обработать только два вектора из двух элементов. Таким образом, выбор минимального по размеру типа данных (который удовлетворяет условиям и ограничениям задачи) обеспечивает максимально возможный параллелизм [5].
Может возникнуть такая ситуация, когда переход на тип данных меньшего размера снижает качество (точность) вычислений. При этом степень ухудшения качества бывает сложно оценить теоретически. В этом случае может быть целесообразной реализация двух вариантов процедуры и выбор оптимальной по критериям «параллелизм» и «качество результата» уже в результате непосредственного тестирования.
В заключение необходимо отметить, что не всегда применение технологии SIMDудается применить максимально эффективно, как это получилось в нашем примере. Иногда поставленная задача не допускает возможности реорганизации структуры данных, а также изменения их типов без серьезных изменений в алгоритме. Некоторые алгоритмы в принципе плохо поддаются распараллеливанию. Все это, а также пренебрежение освещенными ранее способами оптимизации снижает рост производительности.