Comments 15
еще накину идей для статей на будущее :)
ресайзинг картинок на GPU: AMD/OpenCL, NVidia/OpenCL, NVidia/CUDA… можно будет добавить Vulkan и DX12
а OpenCL(возможно и Vulkan) можно еще и на CPU протестить, взяв SDK от Intel и от AMD
Результаты Pillow-SIMD 3.4 на одном ядре с AVX2 для той же операции с бикубическим фильтром — 175 операций/секунду. Сопоставимый по стоимости процессор для выбранной видеокарты будет 4-ядерный i5, то есть на всех ядрах теоретически будет 700 операций/секунду. На практике может быть немного поменьше: ресайз на двух ядрах дает двухкратный прирост, а вот для четырех ядер надо проверять.
Другое дело, что на видеокарте можно сделать не только ресайз, а что-то еще интересное. Самый шик был бы делать на видеокарте декодирование из JPEG и других графических форматов, тогда было бы пофиг на скорость шины. Но что-то пока нет открытых кодеков популярных форматов. И даже те, что есть, требуют специально подготовленных джипегов, с рестарт-маркерами. С остальными форматами все еще хуже.
Для улучшения качества ресайза при уменьшении изображения можно было считать интегральное изображение, затем его уменьшать теми же сплайнами, затем дифференцировать его обратно. Т.е. делать это за 3 операции: интегрирование ->
ресайз -> дифференцирование. Каждая из этих операций разделяема по направлениям. Если использовать эту схему, то количество семплов, приходящихся на каждый пиксель выходной картинки, никак не будет зависеть от коэффициента масштабирования. Алиасинг полностью исчезнет.
Кроме того, можно делать свёртки в фазовом домене, сразу после декодирования VLC, не проводя iDCT преобразование — это если пользоваться софтверным декодером JPEG.
Померил на реальном железе с i5-4430:
Текущая версия Pillow-SIMD 4.1.0
2560×1600 → 26x16 bic 1002 op/s
2560×1600 → 320x200 bic 630 op/s
2560×1600 → 2048x1280 bic 153 op/s
2560×1600 → 5478x3424 bic 40 op/s
Pillow-SIMD с улучшениями, которые пока не вошли ни в одну версию:
2560×1600 → 26x16 bic 1028 op/s
2560×1600 → 320x200 bic 730 op/s
2560×1600 → 2048x1280 bic 242 op/s
2560×1600 → 5478x3424 bic 59 op/s
Теоретический максимум по шине PCIe 3.0 16x
2560×1600 → 26x16 bic 671 op/s
2560×1600 → 320x200 bic 661 op/s
2560×1600 → 2048x1280 bic 409 op/s
2560×1600 → 5478x3424 bic 120 op/s
Числа с плавающей точкой Хранят приблизительное значение с определенной точностью
кхм, а это как?
по мне так в пз хранится не приблизительное а вполне определенное число, кратное 2^m.
Сравнить достаточно просто: скорее всего даже самая простая реализация в лоб на самой медленной карте последнего поколения (GF 1050) будет упираться только в шину. Скорость 16x PCIe 3.0 примерно 11 Гб/c. Для ресайза 2560*1600 → 320*200 по шине нужно прокачать примерно 16 Мб данных. Это будет примерно 690 операций/секунду.
Можно совместить копирования и вычисления с помощью CUDA Streams, тогда теоретический потолок пропускной способности поднимется в два раза, хотя на практике так быстро пока не получается. К тому же, очень часто алгоритм ресайза находится не в самом начале общей схемы обработки изображений и все данные уже находятся в памяти видеокарты, т.е. их никуда не нужно копировать. Поэтому мы для тестов производительности измеряем время работы алгоритма на GPU без учёта копирований.
Для проверки производительности алгоритма мы используем два теста: сжатие изображений 2К и 4К в 2 раза по каждой оси и уменьшение размеров изображения на 1 пиксел по ширине и по высоте. Во втором тесте размер данных почти не изменяется и для оценки производительности вычислений такой подход кажется более оправданным.
Другое дело, что на видеокарте можно сделать не только ресайз, а что-то еще интересное. Самый шик был бы делать на видеокарте декодирование из JPEG и других графических форматов, тогда было бы пофиг на скорость шины. Но что-то пока нет открытых кодеков популярных форматов.
Мы именно так и делаем, т.е. вся обработка изображений выполняется на видеокарте. Получается очень быстро и можно делать ресайз джипегов на лету, задавая индивидуальные параметры ресайза для каждой картинки. При этом скорость декодирования джипегов у нас чуть ниже, чем скорость ресайза. Здесь можно посмотреть наши бенчмарки для ресайза и декодирования.
И даже те, что есть, требуют специально подготовленных джипегов, с рестарт-маркерами. С остальными форматами все еще хуже.
Да, без рестарт-маркеров не получается параллельное декодирование джипегов (декодирование по Хаффману). Но можно без потери качества добавить рестарт-маркеры самостоятельно с помощью утилиты jpegtran. Рестарт-маркеры являются частью стандарта JPEG, так что это разумный и вполне официальный подход для решения задач быстрого декодирования.
Как я сделал самый быстрый ресайз изображений. Часть 3, числа с фиксированной точкой