Медианная фильтрация с AVX AVX2 и OpenMP - PullRequest
0 голосов
/ 29 ноября 2018

Я работаю над медианным фильтром, используя инструкции avx avx2 и OpenMP.Ввод изображения 4K.Время от времени алгоритм работает с одним цветовым компонентом пикселя, взятым из входных данных.

Мой размер фильтра равен 5*5 = 25.Для медианного фильтра я должен отсортировать эти unsigned char числа, а затем взять среднее.Я использую метод слияния Odd-Even от Batcher, и он работает нормально.

Я нахожусь в той точке, где мне нужно максимально ускорить алгоритм.Я тестировал программу несколько раз и в среднем получил результат 3,08 секунды

Визуализация алгоритма сортировки: как видите, весь процесс сортировки можно разбить на 15 меньших шагов.Visualization of the sorting algorithm


У меня есть функция верхнего уровня, которую я вызываю из main с именем MedianFiltering, которая берет всю информацию, необходимую для фильтрации, и записывает ее обратно с помощью указателя.Когда эта функция вызывается, она создает все необходимые векторы управления для следующих двух функций:

_mm256_blendv_epi8() и _mm256_permute2f128_si256()

Создание всех необходимых векторов управления

Iесть 40 следующей строки (все названы по-разному)

__m256i vectorControl= _mm256_lddqu_si256((__m256i *)controlArray);

что-то вроде:

__m256i vmaskBlendControlFromMinMaxandWorkingOn4 = _mm256_lddqu_si256((__m256i *)maskBlendControlFromMinMaxandWorkingOn4);

__m256i vmaskBlendControlFromMinandMax5 = _mm256_lddqu_si256((__m256i *)maskBlendControlFromMinandMax5);
__m256i vmaskBlendControlFromMinMaxandWorkingOn5 = _mm256_lddqu_si256((__m256i *)maskBlendControlFromMinMaxandWorkingOn5);

__m256i vmaskBlendControlFromMinandMax6 = _mm256_lddqu_si256((__m256i *)maskBlendControlFromMinandMax6);

__m256i vmaskBlendControlFromMinandMax7 = _mm256_lddqu_si256((__m256i *)maskBlendControlFromMinandMax7);
__m256i vmaskBlendControlFromMinMaxandWorkingOn7 = _mm256_lddqu_si256((__m256i *)maskBlendControlFromMinMaxandWorkingOn7);

Я думаю, мне не нужно публиковать все это, вы получите идею.

Алгоритм

затем процесс сортировки:

//stepping on every row
for (int row = 0; row < imgHeight; row++)
{
    stepping on every column of the picture

    for (int col = 0; col < imgWidth; col++)
    {
        OneColorChanelWidth calculatedMedians[3] = { 0 };
        //calculating each color of a single pixel
        for (int rgba = 0; rgba < 3; rgba++)
        {
            OneColorChanelWidth calcMedian[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255 };
            for (int fy = 0; fy < FILTER_W; fy++)
            {
                for (int fx = 0; fx < FILTER_H; fx++)
                {
                    calcMedian[fy * 5 + fx] = *(imgSrcExt + (row + fy)*imgWidthF * 3 + (col + fx) * 3 + rgba);
                }
            }
            __m256i vinput = _mm256_lddqu_si256((__m256i *)calcMedian);


              *Sorting the calcMedian array all the 15 steps are here the result is stored in workingOn*



            *(imgDstMedian + row*imgWidth * 3 + col * 3 + rgba) = workingOn.m256i_u8[12];
        }
    }
}

Точка зрения с высоты птичьего полета:

void MedianFiltering(arguments)
{

   Creating all the required control vectors

   Algorithm

   return;
}

Поскольку я могу использовать OpenMP, распараллеливаниеможет быть хорошо, чтобы улучшить скорость обработки.Я поставил #pragma omp parallel for перед циклом for, который считается по строкам, но ничего не изменилось.Затем я поставил его перед тем, который считает по строкам, без увеличения скорости.

После этого я думаю о том, может быть, проблема в том, что все потоки, которые начинают работать, используют одни и те же векторы управления (все они читаютсяпожалуйста, скажите мне, может ли это привести к тому, что распараллеливание не может иметь никакого значения.

Я провел эксперимент: я поместил эту прагму распараллеливания в разные места кода и запускаю тесты, но, к сожалению, нииз экспериментов показали высокую скорость улучшения. На самом деле 3,08 секунды были самым низким временем, которое я получил, но это может быть достигнуто без какого-либо параллелизата.

Есть ли способ использовать распараллеливание для улучшения моего времени обработки? ДругойЭто может привести к повторному процессу сортировки, но в данный момент я не заинтересован в этом.

...