Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Стоит ли оптимизировать обработку изображений на С при помощи SIMD?

Anna | 24.06.2014 | нет комментариев
Обработка изображений (тут мы осмысленно ограничиваем в себя только растровыми картинками и спускаем широкий класс векторных изображений), как правило, представляет собой комплект примитивных операций, которые используются к всякой точке изображения. Если учесть, что цветовые каналы, из которых состоит точка изображения (пиксель) традиционно представлены в виде целых чисел маленький размерности, то обработка изображения сводится к большому числу однотипных операций над 1-2 байтными целыми числами.
image

Выполнение сходственных операций при помощи процессорных команд всеобщего назначения не вовсе результативно, так как они оптимизированы для обработки 4-8 байтных чисел. Реально при работе с 1 байтными числами их результативность будет падать в 4—8 раз. Изготовители процессоров теснее давным-давно предложили довольно результативное решение, для увеличения продуктивности при работе с такими данными – SIMD (Single instruction, multiple data) – комплекты векторных инструкций, которые разрешают обрабатывать огромное число данных за одну операцию. Если рассматривать платформу x86, то на ней существует огромное число SIMD-растяжений: MMX, 3DNow!, SSE, SSE2, SSE3, SSEE3, SSE4.1, SSE4.2, AVX и AVX2. Множество из этих растяжений предуготовлены для векторной обработки вещественных чисел. Если касаться векторных целочисленных инструкций, то дозволено выделить комплекты команд MMX, SSE2 и AVX2, которые соответственно содержат операции для работы с 8, 16 и 32-байтовыми векторами. Растяжение MMX впервой возникло в процессоре Pentium MMX в 1997 году и в реальное время представляет скорее исторический интерес, так как все современные x86 процессоры поддерживают больше идеальный комплект команд SSE2, тот, что был впервой представлен в процессоре Intel Pentium 4, вышедшем в 2000 году. Впрочем жизнь не стоит на месте, и в 2013 году вышло семейство процессоров iCore 4-го поколения с помощью инструкций AVX2, которые в скором грядущем получат широкое распространение.И так, у нас есть какой-нибудь алгорифм, написанный на С , осуществляющий обработку изображения, скорость которого критична для данного приложения (такие алгорифмы Почаще каждого встречаются при обработке видео). Рассматривая присутствие SIMD растяжений процессора, которые разрешают в допустимо ускорить скорость выполнения алгорифма в 10 и больше раз, логичным будет попытаться их каким-либо образом задействовать. И так встает вопрос на сколько это легко сделать? Ниже я постараюсь на него ответить, детально перечислив все плюсы и минусы, с которым придется столкнуться разработчику в процессе задействования SIMD растяжений процессоров в своем плане

Плюсы

  1. Использование SIMD инструкций разрешает осуществить одновременную обработку сразу над несколькими комплектами начальных данных, тем самым гораздо уменьшив всеобщее время работы алгорифма.
  2. Расширенные комплекты инструкций содержат специализированные команды (скажем нахождение среднего либо максимального числа для пары чисел, сложение либо вычитание с насыщением), которые заменяют собой несколько инструкций всеобщего назначения. Использование этих комманд может дать добавочный крайне существенный выигрыш в скорости исполнения.
  3. Для того, что бы задействовать SIMD растяжения процессора, против распространенному заблуждению, вовсе не непременно применять ассемблер. Все современные компиляторы C поддерживают так называемые intrinsic – функции, которые компилятор напрямую транслирует в команды для CPU. Потому при задействовании SIMD, дозволено всецело оставаться в рамках синтаксиса С/С в привычной IDE.

Минусы

  1. Потеря универсальности кода, тот, что задействует растяжения процессора. Подлинно, существует огромное число процессорных архитектур, всякая из которых может содержать (а может и нет), свой личный комплект векторных инструкций. Потому либо нам доводится ограничивать применимость нашей программы какой-либо определенной архитектурой, либо писать несколько реализаций алгорифма для всякой из требуемых нам архитектур.
  2. Входные и выходные данные обязаны лежать в памяти упорядоченно (желанно ступенчато, правда допустимо довольно результативное извлечение всякого второго либо всякого четвертого элемента). Чем плотнее лежат входные и выходные данные, тем поменьше операций по их переупорядочиванию нам придется выполнить и тем результативнее будет наш алгорифм. Указанное требование принуждает пересматривать методы хранения данных, например, беречь цветное изображение в виде комплекта отдельных цветовых плоскостей, а не в цельной плоскости с чередованием цветовых каналов для всякой точки (как в BGR-24).
  3. Желанно, что бы входные и выходные данные данные были выровнены в памяти (по 16 байтной границе для SSE2, по 32 байтной границе для AVX2), так ка чтение и сохранение выровненных данных происходит гораздо стремительней. В случае, если мы контролируем создание входных и выходных данных, то их выравнивание достигается использованием особых аллокаторов памяти. В отвратном случае, мы обязаны либо смириться с потерей скорости работы алгорифмов, либо писать две версии алгорифма для случая выровненных либо не выровненных данных.
  4. Если при обработке изображений в регистрах всеобщего назначения, задача переполнения чисел в процессе вычислений фактически не встречается (мы легко используем типовой тип int, тот, что вряд ли переполнится при работе с 8 битными данными), то при обработке с поддержкой векторных инструкций эту задачу необходимо непрерывно удерживать под контролем. Если, скажем, в алгорифме допустимо переполнение 8-битных данных в процессе расчета, то мы обязаны их преобразовать их в 16-битные, исполнить расчет и сделать обратное реформирование. Безусловно для этого существуют особые векторные инструкции паковки и распаковки векторов, но все это замедляет алгорифм, равно как и то, что векторные инструкции над 16-битными данными обрабатывают в два раза поменьше данных за 1 раз, по сопоставлению с 8-битными.
  5. При обработке векторных инструкций, отсутствует вероятность условного исполнения команд для всякого элемента. В некоторых случаях условные переходы дозволено эмулировать, для чего доводится исполнять обе ветки кода, а после этого объединять итоги их работы. Это обычным образом сказывается на продуктивности алгорифма и если код интенсивен условными переходами, то толк в SIMD оптимизации теряется.
  6. При обработке изображения точки, которые располагаются на границах, как правило обрабатываются специальным образом. Для векторных инструкций дело осложняется тем, что в граничном блоке точек часть точек обрабатывается по всеобщему алгорифму, а часть по алгорифму для граничных точек, что гораздо усложняет разработку.
  7. Ширина изображения не неизменно бывает кратной размеру вектора. Потому для обработки изображений с произвольной шириной нужно специальным образом обрабатывать конечный блок в строке, тот, что может быть заполненным лишь Отчасти.
  8. Не все математические операции, которые доступны для скалярных регистров имеют свои аналоги для векторных инструкций. Скажем, отсутствует целочисленное деление. В этих случаях доводится либо отказываться от векторизации, либо пытаться эмулировать их при помощи имеющихся инструкций, что приводит к снижению результативности и усложенению кода.
  9. Читаемость кода, содержащего векторные инструкции, как правило гораздо уступает читабельности скалярного кода.
  10. Отладка кода, содержащего векторные инструкции гораздо труднее, так как программисту доводится отслеживать корректность не отдельных скалярных значений, а целых векторов. А современные IDE, не смотря на существенный прогресс в этой области, отображают векторные данные гораздо дрянней скалярных.
  11. Навык показывает, что написание правильно работающего алгорифма использующего векторные инструкции фактически не допустимо, без наличия юнит тестов, которые покрывают все характерные случаи, в которых он будет применяться.

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

Послесловие

Автор данной статьи, по роду своей деятельности (разработка алгорифмов для видео аналитики) посвятил достаточно огромное время процессу оптимизации алгорифмов обработки изображений на C при помощи разных векторных инструкций (в основном это SSE2 и AVX2). В частности, итогом этой работы стала библиотека алгорифмов обработки изображений на С с открытым начальным кодом, которая имеется в открытом доступе. Если читатели сочтут эту тему увлекательной, то я готов написать несколько статей, которые будут описывать особенности оптимизации на определенных примерах.

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB