Как использовать встроенные функции AVX для ускорения размытия по Гауссу на изображении pgm в оттенках серого (C ++) - PullRequest
0 голосов
/ 04 апреля 2020

Цель

  • Мне нужно написать реализацию, использующую встроенные функции AVX / AVX2 для оптимизации процедуры размытия по Гауссу.
  • Любые параллельные части должны быть полностью векторизация.
  • инструкции с высокой задержкой, такие как hasd, не должны использоваться
  • Массивы не должны превышать своих границ
  • в каждой итерации должно быть вычислено более одного выходного пикселя
  • Нужно использовать данное 5x5 Ядро
    {2,4,5,4,2},
    {4,9,12,9,4},
    {5,12,15,12,5}

Функция для оптимизации:

    short int row, col, rowOffset, colOffset;
    short int newPixel;


    for (row = 2; row < N - 2; row++) {
        for (col = 2; col < M - 2; col++) {
            newPixel = 0;
            for (rowOffset = -2; rowOffset <= 2; rowOffset++) {
                for (colOffset = -2; colOffset <= 2; colOffset++) {

                    newPixel += in_image[row + rowOffset][col + colOffset] * gaussianMask[2 + rowOffset][2 + colOffset];
                }
            }
            filt_image[row][col] = newPixel / 159;
        }
    }

Что я знаю до сих пор

  • Изображение PGM имеет размер 1024x1024 пикселей
  • Оно представлено в виде короткого целого изображения без знака [N] [M]
  • Пиксели шириной 16 бит
  • Я могу использовать разделяемое ядро, которое делит на произведение двух гауссианов 1D (то же самое можно сделать для вертикального и горизонтального прохода)

Функция, используемая для сравнения исходной функции с оптимизированной

bool compare_Gaussian_images() {

    int row, col, rowOffset, colOffset;
    int newPixel;

    for (row = 2; row < N - 2; row++) {
        for (col = 2; col < M -2; col++) {
            newPixel = 0;
            for (rowOffset = -2; rowOffset <= 2; rowOffset++) {
                for (colOffset = -2; colOffset <= 2; colOffset++) {

                    newPixel += in_image[row + rowOffset][col + colOffset] * gaussianMask[2 + rowOffset][2 + colOffset];
                }
            }
            newPixel = newPixel / 159;
            if (newPixel != filt_image[row][col]) {
                //printf("\n %d %d - %d %d\n", row, col, newPixel, filt_image[row][col]);
                return false;
            }
        }
    }

    return true;

}

Я пытался посмотреть на реализацию Intel , но они используют rgba и число с плавающей точкой

Любые советы или информация будет принята с благодарностью:)

...