Параллельное преобразование IplImage с использованием OpenMP - PullRequest
3 голосов
/ 17 января 2012

Я хотел бы сделать некоторые преобразования в IplImage, используя OpenMP.Это простая трансформация, которая переворачивает изображение с ног на голову.Код с OpenMP работает так же, как и без.Это не имеет большого значения.

void UpsideDownFilter::filter(IplImage* dstImage) {
uchar temp;
int j;
int i;
#pragma omp parallel shared(dstImage) private(j, i, temp)
{
    //        std::cout << omp_get_thread_num() << std::endl;
#pragma omp for schedule(static, 30) nowait
    for(j = 0; j < dstImage->height / 2; ++j) {

        for(i = 0; i < dstImage->widthStep; ++i) {
            temp = dstImage->imageData[i + j * dstImage->widthStep];

            dstImage->imageData[i + j * dstImage->widthStep] =
                dstImage->imageData[i + (dstImage->height - 1 - j) * 
                                    dstImage->widthStep];

            dstImage->imageData[i + (dstImage->height - 1 - j) * 
                                dstImage->widthStep] = temp;
        }
    }
}
}

Я уже передал #pragma omp для внутреннего цикла.Я сделал все другие магические вещи, которые я обычно делаю, когда не имею понятия, что не так (удалите это, добавьте это).Вот как я вызываю этот метод из своего кода:

for (vector<filter_ptr>::iterator it = filters.begin();
     it != filters.end(); ++it) {

    (*it)->filter(dstImage);
}

Может кто-нибудь сказать мне, что я делаю неправильно?

1 Ответ

3 голосов
/ 18 января 2012

Поскольку я не мог скомпилировать ваш код, я написал свой собственный, который, я думаю, очень похож.Вы сгладили свою 2D-матрицу, и я не мог быть обеспокоен, но я не думаю, что это повлияет на то, что, по моему мнению, идет вам не так.

#include <vector>

typedef std::vector<std::vector<double> > matrix_t;

void flip(matrix_t& A, int const m, int n)
{
    int m_2 = m / 2;
    #pragma omp parallel for
    for (int i = 0; i < m_2; ++i) {
        for (int j = 0; j < n; ++j) {
            std::swap(A[i][j], A[m - (i + 1)][j]);
        }
    }
}

int
main()
{
    int n = 20000;
    matrix_t A (n, std::vector<double>(n, 1.0));
    flip(A, n, n);
    return 0;
}

На четырехъядерной машине я не получаю ускорениену.

> g++ -O2 s18.cc && /usr/bin/time ./a.out && g++ -fopenmp -O2 s18.cc && /usr/bin/time ./a.out 
2.61user 2.18system 0:04.79elapsed 99%CPU (0avgtext+0avgdata 12805936maxresident)k
0inputs+0outputs (0major+800428minor)pagefaults 0swaps
7.67user 2.23system 0:04.71elapsed 210%CPU (0avgtext+0avgdata 12806512maxresident)k
0inputs+0outputs (0major+800481minor)pagefaults 0swaps

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...