[英]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.