Skip to content

ArtemkaSheremetev/simd-threadpool-image-processing

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SIMD ThreadPool Image Processing

О проекте

Проект сравнивает производительность нескольких реализаций обработки PNG-изображений на C++.

Реализованы две задачи:

  • вычисление суммы абсолютных разностей между соседними пикселями;
  • преобразование изображения из RGB(A) в YUV.

Для каждой задачи есть три варианта реализации:

  • наивный;
  • векторизованный с использованием AVX2-интринсиков;
  • многопоточный на основе собственного ThreadPool.

Для измерения производительности используется google/benchmark.

Пример входного изображения:

Пример входного изображения

Структура проекта

  • main.cpp собирает список PNG-файлов, регистрирует бенчмарки и запускает их.
  • inc/task.h, src/task.cpp содержат загрузку PNG и реализации simple8, intrinsic8, threads8, simple11, intrinsic11, threads11.
  • inc/threadpool.h, src/threadpool.cpp содержат реализацию пула потоков.
  • images/ содержит входные изображения.
  • scripts/plot_benchmarks.py строит графики по build/results.json.
  • scripts/run_benchmarks.sh использует существующий build/results.json для построения графиков, а если файла нет, сначала запускает бенчмарк.

Как работает программа

  1. Программа получает путь к папке с PNG-файлами.
  2. Для каждого изображения регистрируются бенчмарки для всех реализаций.
  3. Для многопоточных реализаций параметр n меняется от 2 до 6.
  4. google/benchmark измеряет время выполнения и пропускную способность.
  5. Результаты можно сохранить в JSON и затем построить по ним графики.

Требования

Для сборки нужны:

  • компилятор C++ с поддержкой C++17;
  • cmake 3.14 или новее;
  • libpng;
  • git;
  • доступ в интернет при первой сборке, так как google benchmark загружается через FetchContent;
  • процессор с поддержкой AVX2.

Для построения графиков нужны Python-библиотеки:

  • pandas;
  • matplotlib;
  • numpy.

Пример установки зависимостей на Ubuntu/Debian:

sudo apt update
sudo apt install build-essential cmake libpng-dev git python3 python3-pip python3-venv

Настройка Python-окружения

Рекомендуется создать виртуальное окружение:

python3 -m venv .venv
source .venv/bin/activate
pip install pandas matplotlib numpy

Скрипты scripts/run_benchmarks.sh и scripts/plot_benchmarks.py автоматически пытаются использовать .venv или venv, если такое окружение есть в корне проекта.

Сборка

Из корня проекта:

cmake -S . -B build
cmake --build build

Исполняемый файл:

./build/lab

Запуск бенчмарка

Запуск на тестовых изображениях:

./build/lab ./images

Запуск с сохранением результатов:

./build/lab ./images --benchmark_out=build/results.json --benchmark_out_format=json --benchmark_time_unit=ms

Если папка не существует или в ней нет PNG-файлов, программа завершится с ошибкой.

Построение графиков

Если build/results.json уже существует и он корректный:

python3 scripts/plot_benchmarks.py build/results.json

Скрипт:

  • нормализует время в миллисекунды;
  • автоматически делит изображения на группы small и large;
  • сохраняет графики времени и пропускной способности в корень проекта.

Создаются файлы:

  • time_8_small.png
  • time_8_large.png
  • time_11_small.png
  • time_11_large.png
  • throughput_8_small.png
  • throughput_8_large.png
  • throughput_11_small.png
  • throughput_11_large.png

Если build/results.json поврежден или обрезан, скрипт сообщит об этом и попросит пересоздать файл.

Скрипт run_benchmarks.sh

Команда:

bash scripts/run_benchmarks.sh

Поведение:

  • если build/results.json уже есть и он валидный, скрипт только строит графики;
  • если build/results.json нет, скрипт ожидает путь к папке с PNG и сначала запускает бенчмарк;
  • если build/results.json поврежден, скрипт завершится с сообщением об ошибке.

Запуск с автоматическим созданием results.json, если его нет:

bash scripts/run_benchmarks.sh ./images

Реализованные алгоритмы

Задача 1

simple8() последовательно считает сумму абсолютных разностей по RGB-каналам:

  • между соседними пикселями по горизонтали;
  • между соседними пикселями по вертикали.

intrinsic8() выполняет те же вычисления с помощью AVX2.

threads8() делит изображение на части по строкам и распределяет вычисления через ThreadPool.

Задача 2

simple11() поэлементно преобразует каждый пиксель из RGB в YUV.

intrinsic11() выполняет ту же операцию векторно с использованием AVX2.

threads11() делит массив пикселей на части и выполняет преобразование параллельно.

Дополнительно

  • PNG-файлы загружаются через libpng и приводятся к формату RGBA.
  • Размер пула потоков выбирается автоматически по числу доступных аппаратных потоков, но не более 6.
  • Бенчмарки используют bytes_per_second и real_time, которые затем читаются Python-скриптом.

Быстрый сценарий

cmake -S . -B build
cmake --build build
python3 -m venv .venv
source .venv/bin/activate
pip install pandas matplotlib numpy
./build/lab ./images --benchmark_out=build/results.json --benchmark_out_format=json --benchmark_time_unit=ms
python3 scripts/plot_benchmarks.py build/results.json

About

C++ project for benchmarking simple, AVX2, and multithreaded PNG image processing algorithms.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors