簡體   English   中英

如何通過循環將OpenMP線程拆分為子團隊

[英]How to split OpenMP threads into subteams over a loop

假設我有一個以下函數,它在內部使用#pragma omp parallel

void do_heavy_work(double * input_array);

我現在想do_heavy_work許多input_arrays這樣的:

void do_many_heavy_work(double ** input_arrays, int num_arrays)
{
    for (int i = 0; i < num_arrays; ++i)
    {
        do_heavy_work(input_arrays[i]);
    }
}

假設我有N硬件線程。 上面的實施將導致num_arrays的調用do_heavy_work發生以串行方式,每次使用都N線程內部做它想要的任何東西平行。

現在假設當num_arrays > 1 ,在這個外部循環上並行化比在do_heavy_work內部並行化更有效。 我現在有以下選擇。

  • #pragma omp parallel for放在外部循環上並設置OMP_NESTED=1 但是,通過設置OMP_NUM_THREADS=N我將最終產生大量的線程( N*num_arrays )。
  • 如上所述,但關閉嵌套並行性。 num_arrays < N時,這會浪費可用內核。

理想情況下,我希望OpenMP將其OMP_NUM_THREADS線程團隊分成num_arrays子團隊,然后每個do_heavy_work可以通過其分配的子團隊進行線程化。

實現這一目標的最簡單方法是什么?

(出於本討論的目的,我們假設num_arrays是事先已知的,而且我也不能在do_heavy_work本身中更改代碼。代碼應該在許多機器上工作,因此N應該是可以自由指定的。)

OMP_NUM_THREADS可以設置為列表,從而指定每個嵌套級別的線程數。 例如, OMP_NUM_THREADS=10,4將告訴OpenMP運行時執行具有10個線程的外部並行區域,並且每個嵌套區域將使用4個線程執行,總共最多40個同時運行的線程。

或者,您可以使用與此類似的代碼使程序自適應:

void do_many_heavy_work(double ** input_arrays, int num_arrays)
{
    #pragma omp parallel num_threads(num_arrays)
    {
        int nested_team_size = omp_get_max_threads() / num_arrays;
        omp_set_num_threads(nested_team_size);

        #pragma omp for
        for (int i = 0; i < num_arrays; ++i)
        {
            do_heavy_work(input_arrays[i]);
        }
    }
}

如果OMP_NUM_THREADS的值不能被num_arrays整除,則此代碼不會使用所有可用線程。 如果每個嵌套區域具有不同數量的線程就可以了(它可能導致某些數組的處理速度比其他數組快),想出如何分配線程並nested_team_size在每個線程中設置nested_team_size 從並行區域內調用omp_set_num_threads()僅影響由調用線程啟動的嵌套區域,因此您可以擁有不同的嵌套團隊大小。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM