Задача OpenMP не работает - PullRequest
0 голосов
/ 04 июня 2018

В следующем коде я создал параллельную область, используя #pragma omp parallel.

Внутри параллельной области есть участок кода, который должен выполняться только одним потоком, что достигаетсяиспользуя #pragma omp single nowait.

Внутри, последовательная область их представляет собой цикл FOR, который можно распараллелить, и я использую #pragma omp taskloop для достижения этого.

После завершения цикла у меня естьиспользуется #pragma omp taskwait, чтобы убедиться, что остальная часть кода выполняется только одним потоком.Тем не менее, кажется, что ведет себя не так, как я ожидаю.Несколько потоков обращаются к разделу кода после #pragma omp taskwait, который объявлен в области, определенной как #pragma omp single nowait.

  std::vector<std::unordered_map<int, int>> veg_ht(n_comp + 1);
  vec_ht[0].insert({root_comp_id, root_comp_node});

  #pragma omp parallel
    {
        #pragma omp single
        {
            int nthreads = omp_get_num_threads();
            for (int l = 0; l < n_comp; ++l) {
                    int bucket_count = vec_ht[l].bucket_count();

                    #pragma omp taskloop 
                    for (int bucket_id = 0; bucket_id < bucket_count; ++bucket_id) {
                        if (vec_ht[l].bucket_size(bucket_id) == 0) { continue; }
                        int thread_id = omp_get_thread_num();
                        for (auto it_vec_ht = vec_ht[l].begin(bucket_id); it_vec_ht != vec_ht[l].end(bucket_id); ++it_vec_ht) {
                            // some operation --code removed for minimality
                        } // for it_vec_ht[l]  
                    } // for bucket_id taskloop

                    #pragma omp taskwait 

                    // Expected that henceforth all code will be accessed by one thread only
                    for (int tid = 0; tid < nthreads; ++tid) {
                      // some operation --code removed for minimality
                    } // for tid
            } // for l
        } // pragma omp single nowait
    } // pragma parallel

1 Ответ

0 голосов
/ 04 июня 2018

Не похоже, что вам обязательно нужно использовать параллельную / одиночную / Taskloop-оболочку.Если вы не собираетесь указывать количество потоков, то ваша система должна по умолчанию использовать максимальное количество доступных потоков.Вы можете получить это значение вне конструкции OMP, используя omp_get_max_threads()'. Then you can use just the taskloop structure, or just replace it with a # pragma omp parallel for`.

Я думаю, что проблема с вашим кодом - строка #pragma omp taskwait.Один поток должен разбиться на множество потоков, когда он попадет в конструкцию taskloop, а затем свернуть обратно в один поток.Я думаю, что вы, возможно, запускаете совершенно новое разветвление своего отдельного потока командой #pragma omp taskwait.Альтернатива #pragma omp taskwait, которая определенно не запускает разветвление потока, - #pragma omp barrier.Я думаю, что выполнение этой замены заставит ваш код работать в его текущей форме.

...