Карты и параллельная диспетчеризация openMP

Я пытаюсь распараллелить часть кода, но есть некоторые проблемы, критическая часть для вставки в общую карту создает узкое место в моем исполнении. Есть способ распараллелить вставку?

Вторая проблема касается того, как выполнять итерацию с openMP на картах заданное количество раз. Вот код, я использую g++-5 на Clion.

else if (PERF_ROWS <= MAX_ROWS && function_switch == false)
{
    int array_dist_perf[PERF_ROWS];
    int array_dist[MAX_ROWS];

    multimap<float, int> temp_map;

    #pragma omp parallel for schedule(dynamic) private(array_dist_perf) shared(temp_map)
    for (int i = 0; i < MAX_COLUMNS; i++)
    {
        if (i % PERF_CLMN == 1) continue;

        for (int j = 0; j < PERF_ROWS; j++) //truncation perforation
        {
            array_dist_perf[j] = abs(input[j] - input_matrix[j][i]);
        }

        float av = mean(PERF_ROWS, array_dist_perf);

        float temp_score = score_func(av);

        #pragma omp critical(map_update)
        temp_map.insert({temp_score, i});
    }

    map<float,int>::reverse_iterator rit;

    int iter = 0;

    #pragma omp parallel for schedule(dynamic) private(array_dist) shared(iter)
    for (rit=temp_map.rbegin(); rit!=temp_map.rend(); rit++)
    {
        int s = rit->second;

        for (int k = 0; k < MAX_ROWS; k++)
        {
            array_dist[k] = abs(input[k] - input_matrix[k][s]);
        }

        float av_real = mean(MAX_ROWS, array_dist);

        float score_real = score_func(av_real);

        rank_function(score_real, s);

        #pragma omp atomic
        iter++;

        if (iter == THRESHOLD_NUM)

            break;
    }
}

person CIVI89    schedule 14.04.2016    source источник
comment
Почему вы используете schedule(dynamic)? Ваши итерационные рабочие нагрузки не кажутся мне сильно различающимися.   -  person Klaas van Gend    schedule 14.04.2016
comment
Кроме того: вы выполняете «ранний выход» (break). Вы должны использовать механизм cancel и cancellation_point OpenMP4 - в противном случае поведение вашего кода не определено.   -  person Klaas van Gend    schedule 14.04.2016
comment
Я использую расписание (динамическое) для продолжения, что заставляет меня пропускать некоторые итерации. Я использую break, потому что не знаю, как перебирать карту произвольное количество раз, а не от начала до конца.   -  person CIVI89    schedule 14.04.2016
comment
Но вы правы, @KlaasvanGend в цикле карты можно избежать использования динамического ... но что вы подразумеваете под точкой отмены / отмены? Извините, это мой первый день openmp.   -  person CIVI89    schedule 14.04.2016
comment
@CIV89 См., например. software.intel.com/en-us/node/524512 . В omp есть специальное предложение cancel, которое вызывает досрочный выход. Чтобы другие потоки следовали за выходом, вы определяете точки отмены, см. software.intel.com /ru-ru/узел/524513 .   -  person Klaas van Gend    schedule 19.04.2016


Ответы (1)


В Open MP 4 (который должен поддерживаться g++5) можно определить собственное сокращение. Я не хочу делать ненужное дублирование, поэтому посмотрите на этот ответ: C++ OpenMP Parallel For Loop – альтернативы std::vector

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

person Mehno    schedule 14.04.2016
comment
Проблема в том, что я должен использовать упорядоченную карту, а не вектор. Похоже, что OpenMP не может параллельно отправлять вставки в упорядоченную множественную карту, если только я не отмечу эту операцию как критическую. Я могу использовать то же сокращение и для карты? В любом случае спасибо за ваш ответ. - person CIVI89; 14.04.2016
comment
Хорошо, я понимаю концепцию, но я практически не знаю, как объявить сокращение для вставки в карту. Что касается второй части, я не имел в виду количество итераций на поток, я просто имел в виду общее количество итераций на карте, чтобы избежать разрыва. - person CIVI89; 14.04.2016
comment
Я не пробовал сейчас, потому что сейчас использую MVSC, но почему в примере невозможно изменить std::vector с вашей картой?? - person Mehno; 14.04.2016
comment
Я не знаю, как выполнить это сокращение #pragma omp declare (merge : std::multimap‹float, int›:.....) - person CIVI89; 14.04.2016
comment
после этого идет операция, которую вы хотите уменьшить, в вашем случае вставка. Куда вы хотите что-то вставить? В вашем выводе. Итак, напишите omp_out.insert(omp_in.begin(),omp_in.end()) - person Mehno; 14.04.2016
comment
Хорошо, кажется, работает, мне нужно оставить temp_map.insert({temp_score, i}) и удалить критическую часть, верно? Извините, это мой первый день openmp =) - person CIVI89; 14.04.2016
comment
Все в порядке. Да, точно. Просто продолжайте учиться ;) Этот маленький трюк с сокращением иногда очень полезен. Я многому научился на: computing.llnl.gov/tutorials/openMP. не распространяется, потому что это новое в OpenMP 4 - person Mehno; 14.04.2016