OpenMP始终在同一个线程上工作

时间:2017-05-13 10:34:19

标签: c multithreading parallel-processing openmp

我正在使用OpenMP和C进行大学交付,我尝试执行以下代码,我唯一想做的就是看看每个部分在每个不同的线程中是如何工作的:

#include <omp.h>
#include <stdio.h>
int main() {                             
    int id, np;     

    printf("Max threads number: %d\n",omp_get_max_threads());
    omp_set_num_threads(omp_get_max_threads());

    #pragma omp parallel sections private(id, np)
    {
        np = omp_get_num_threads(); 
        #pragma omp section
        { 
            id = omp_get_thread_num();
            printf("Hello from thread %d out of %d threads\n", id, np);
        }
        #pragma omp section
        { 
            id = omp_get_thread_num();
            printf("Hello from thread %d out of %d threads\n", id, np);
        }
        #pragma omp section
        { 
            id = omp_get_thread_num();
            printf("Hello from thread %d out of %d threads\n", id, np);
        }
        #pragma omp section
        { 
            id = omp_get_thread_num();
            printf("Hello from thread %d out of %d threads\n", id, np);
        }
    }
}

我在Linux上工作,所以当我编译它时,请说:

g++ prueba.c -lgomp -o prueba

我得到了下一个输出:

Max threads number: 4
Hello from thread 0 out of 1 threads
Hello from thread 0 out of 1 threads
Hello from thread 0 out of 1 threads
Hello from thread 0 out of 1 threads

有人能告诉我为什么它总是在线号0上工作,为什么omp_get_num_threads()总是1?

我想要实现的输出是:

Max threads number: 4
Hello from thread 0 out of 3 threads
Hello from thread 1 out of 3 threads
Hello from thread 2 out of 3 threads
Hello from thread 3 out of 3 threads

提前致谢!

2 个答案:

答案 0 :(得分:2)

首先,您缺少-fopenmp编译器标志,因此忽略了编译指示。在所有编译和链接步骤中指定fopenmp,除非必要,否则不要手动链接-lgomp

第一个陈述

np = omp_get_max_threads();
另一个答案解释说,sections结构中的

仍将被视为仅由单个线程执行的结构化块。所以你的代码等于:

 #pragma omp parallel sections private(id)
 {
     #pragma omp section
     {
         np = omp_get_max_threads();
     }
     #pragma omp section
     { 
     id = omp_get_thread_num();
     printf("Hello from thread %d out of %d threads\n", id, np);
     }
....

Note that you could also split the `parallel` / `sections` and initalize the private variables for each thread:

很好。此代码由所有并行线程执行,np(每个线程的值相同)通过工作共享omp section保留。你甚至可以搬家:

#pragma omp parallel
{
    // Declaring the variables within makes them implicitly private
    // and avoids stupid mistakes
    int np = omp_get_max_threads();
    int id = omp_get_thread_num();
    #pragma omp sections
    {
        #pragma omp section
        {
            printf("Hello from thread %d out of %d threads\n", id, np);
        }
        ...
    }
}

答案 1 :(得分:1)

  1. 通过将np指定为私有,它对每个单独的块块都是私有的。将np = omp_get_num_threads();复制到每个单独的部分(保持私有)或将其完全移出并行构造(将其从私有中删除)。
  2. 允许段块以任何顺序运行,包括同一线程上的4个块。输出“0,1,2,3”无法控制。
  3. 编辑:为了确保我们在同一行,我在我测试的代码下面复制粘贴:

     #include <omp.h>
     #include <stdio.h>
     int main() {
     int id, np;
    
     printf("Max threads number: %d\n",omp_get_max_threads());
     omp_set_num_threads(omp_get_max_threads());
    
     #pragma omp parallel sections private(id)
     {
         np = omp_get_max_threads();
         #pragma omp section
         { 
         id = omp_get_thread_num();
         printf("Hello from thread %d out of %d threads\n", id, np);
         }
         #pragma omp section
         { 
         id = omp_get_thread_num();
         printf("Hello from thread %d out of %d threads\n", id, np);
         }
         #pragma omp section
         { 
         id = omp_get_thread_num();
         printf("Hello from thread %d out of %d threads\n", id, np);
         }
         #pragma omp section
         { 
         id = omp_get_thread_num();
         printf("Hello from thread %d out of %d threads\n", id, np);
         }
     }
     }