簡體   English   中英

使用 OpenMP 並行化嵌套循環

[英]Parallelize Nested Loops using OpenMP

我嘗試使用 OpenMP 並行化嵌套循環,但我不確定這是否是正確的方法。 這是具有嵌套循環的代碼部分。 這只是一個通用代碼。 我給 noofrecords 為 50k,即使在並行化之后也需要很多時間。 有人可以提出更好的想法來並行化代碼。 我只是在下面的代碼中並行化外循環。

int ctd=0;
#pragma omp parallel for default(none), private(j,k,l), shared(A,B,C,D,ctd)
for(int j=0; j <noofrecords; j++)
{
    for( int k=0; k<noofrecords; k++)
    {
        for( int l=0; l<noofrecords; l++)
        {
            if(condition)
            {
D[ctd].a1=A[i].a1;
ctd++;
              }}}}

您可以使用 collapse 子句,在您的情況下,您有 3 個連續的 for 循環,因此類似於:#pragma omp parallel for default(none), private(j,k,l), shared(A,B,C, D,ctd)崩潰(3)

如果 for 循環是連續的並且代碼在最內層循環中(在您發布的代碼中就是這種情況),它將起作用。 noofrecords 比您的最大線程數大得多,加速不會令人印象深刻。 如果即使並行也很慢,則可能意味着瓶頸不是您的處理能力(更可能是內存已經在 100% 下工作)。

另外,我不太確定你真的想要那個 private(j,k,l)...

  1. 創建一個D.a1類型的a1臨時數組,其元素數等於ctd預期最大值。
  2. 為每個線程創建一個a1的臨時數組a2
  3. 並行填充a2 ,用ctd2統計a2的大小
  4. a2按順序填充數組a1並將ctd2添加到ctd
  5. 從 a1 並行寫入 D.a1

像這樣的東西

int ctd=0;
double *a1 = malloc(sizeof *a1 * N);                       //Step 1
#pragma omp parallel
{
  int ctd2 = 0;
  double *a2 = malloc(sizeof *a2 * N);                     //step 2

  #pragma omp for nowait
  for(int j=0; j<noofrecords; j++)
  for(int k=0; k<noofrecords; k++)
  for(int l=0; l<noofrecords; l++)
    if(condition) a2[ctd2++] = A[i].a1;                    //step 3

  #pragma omp for schedule(static) ordered
  for(int i=0; i<omp_get_num_threads(); i++)
    #pragma omp ordered
    memcpy(&a1[ctd], a2, sizeof *a1 * ctd2), ctd += ctd2;  //step 4

  #pragma omp for
  for(int j=0; j<ctd; j++) D[j].a1 = a1[j];                // step 5
  free(a2);
}
free(a1);

N應該是您期望 ctd 具有的最大大小。 這種方法的一個內存效率低下是a2也分配了大小N ,這可能太大了。 像 C++ 中的std::vector或 glib 中的GArray這樣的動態向量會更有效地使用內存。

暫無
暫無

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

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