C ++ omp нет значительного улучшения - PullRequest
0 голосов
/ 19 февраля 2020

Я нахожусь на MSV C 2019 с компилятором по умолчанию. Код, над которым я работаю, представляет собой изображение Мандельброта. Соответствующие фрагменты моего кода выглядят так:

#pragma omp parallel for
for (int y = 0; y < HEIGHT; y++)
    {
       for (int x = 0; x < WIDTH; x++)
           {  
               unsigned int retVal = mandel(x_val + x_incr * x, y_val + y_incr * y);
               mtest.setPixels(x, y,
                        static_cast<unsigned char>(retVal / 6),
                        static_cast<unsigned char>(retVal / 5),
                        static_cast<unsigned char>(retVal / 4));

           } 
     }

Все переменные вне l oop являются constexpr, исключая любые зависимости. Функция Манделя делает около 1000 итераций с каждым вызовом. Я ожидал бы, что внешний l oop будет работать в нескольких потоках, но каждый мой msv c записывает каждый запуск примерно по 5-6 секунд с или без директивы omp.

Edit (функция mandel):

unsigned int mandel(long double x, long double y)
{
    long double z_x = 0;
    long double z_y = 0;

    for (int i = 0; i < ITER; i++)
    {
        long double temp = z_x;
        z_x = (z_x * z_x) - (z_y * z_y) + x;
        z_y = 2 * temp * z_y + y;

        if ((z_x * z_x + z_y * z_y) > 4)
            return i;
    }
    return ITER; //ITER is a #define macro
}

Ответы [ 2 ]

1 голос
/ 19 февраля 2020

Ваша функция Манделя имеет очень разные затраты времени выполнения в зависимости от того, было ли выполнено условие if в пределах l oop. В результате каждая итерация вашего l oop будет выполняться в разное время. По умолчанию omp использует stati c планирование (т.е. разбивает l oop на N разделов) . Это довольно плохо, потому что у вас нет рабочей нагрузки, подходящей для планирования по расписанию. Посмотрите, что происходит, когда вы используете динамическое планирование c.

#pragma omp parallel for schedule(dynamic, 1)
for (int y = 0; y < HEIGHT; y++)
    {
       for (int x = 0; x < WIDTH; x++)
           {  
               unsigned int retVal = mandel(x_val + x_incr * x, y_val + y_incr * y);
               mtest.setPixels(x, y,
                        static_cast<unsigned char>(retVal / 6),
                        static_cast<unsigned char>(retVal / 5),
                        static_cast<unsigned char>(retVal / 4));

           } 
     }

Также пришло время исключить действительно глупые вещи .....

  1. Вы хотя бы раз включили omp.h в свою программу?
  2. Вы включили omp в настройках проекта?

IIR C, если вы не сделали эти две вещи, omp будет отключен под MSV C.

0 голосов
/ 19 февраля 2020

Это не ответ, но, пожалуйста, сделайте следующее:

unsigned int mandel(long double x, long double y)
{
    long double z_x = 0;
    long double z_y = 0;
    long double z_x_squared = 0;
    long double z_y_squared = 0;

    for (int i = 0; i < ITER; i++)
    {
        long double temp = z_x;
        z_x = z_x_squared - z_y_squared + x;
        z_y = 2 * temp * z_y + y;

        z_x_squared = z_x * z_x;
        z_y_squared = z_y * z_u;

        if ((z_x_squared + z_y_squared) > 4)
            return i;
    }
    return ITER; //ITER is a #define macro
}

Также попробуйте инвертировать порядок ваших двух for петель.

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