У меня есть функция, определенная Intel IPP для работы с изображением/регионом изображения.
Входными данными для изображения являются указатель на изображение, параметры для определения размера для обработки и параметры фильтра.
Функция IPP является однопоточной.
Теперь у меня есть изображение размером M x N.
Я хочу применить к нему фильтр параллельно.
Основная идея проста: разбить изображение на 4 части изображения, которые не зависят друг от друга.< br> Примените фильтр к каждому подизображению и запишите результат в подблок пустого изображения, где каждый поток записывает в отдельный набор пикселей.
Это действительно похоже на обработку 4 изображений, каждое на своем собственном ядре.
Это программа, с которой я это делаю:
void OpenMpTest()
{
const int width = 1920;
const int height = 1080;
Ipp32f input_image[width * height];
Ipp32f output_image[width * height];
IppiSize size = { width, height };
int step = width * sizeof(Ipp32f);
/* Splitting the image */
IppiSize section_size = { width / 2, height / 2};
Ipp32f* input_upper_left = input_image;
Ipp32f* input_upper_right = input_image + width / 2;
Ipp32f* input_lower_left = input_image + (height / 2) * width;
Ipp32f* input_lower_right = input_image + (height / 2) * width + width / 2;
Ipp32f* output_upper_left = input_image;
Ipp32f* output_upper_right = input_image + width / 2;
Ipp32f* output_lower_left = input_image + (height / 2) * width;
Ipp32f* output_lower_right = input_image + (height / 2) * width + width / 2;
Ipp32f* input_sections[4] = { input_upper_left, input_upper_right, input_lower_left, input_lower_right };
Ipp32f* output_sections[4] = { output_upper_left, output_upper_right, output_lower_left, output_lower_right };
/* Filter Params */
Ipp32f pKernel[7] = { 1, 2, 3, 4, 3, 2, 1 };
omp_set_num_threads(4);
#pragma omp parallel for
for (int i = 0; i < 4; i++)
ippiFilterRow_32f_C1R(
input_sections[i], step,
output_sections[i], step,
section_size, pKernel, 7, 3);
}
Теперь проблема в том, что я не вижу никакой выгоды по сравнению с работой в однопоточном режиме для всего изображения.
Я пытался изменить размер изображения или размер фильтра, но ничего не изменило изображение.
Максимум, что я мог получить, это ничего существенного. (10-20%).
Я подумал, что это может быть как-то связано с тем, что я не могу «обещать» каждому потоку, что зона, которую он получил, «только для чтения».
Более того, чтобы сообщить ему, что ячейка памяти, в которую он записывает, также принадлежит только ему.
Я читал об определении переменных как частных и общих, но не смог найти руководства по работе с массивами и указателями.
Как правильно работать с указателями и подмассивами в OpenMP?