【问题标题】:OpenMP always working on the same threadOpenMP 总是在同一个线程上工作
【发布时间】:2017-05-13 10:34:19
【问题描述】:

我正在使用 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

提前致谢!

【问题讨论】:

    标签: c multithreading parallel-processing openmp


    【解决方案1】:

    首先,您缺少-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 sections 保留。你甚至可以移动:

    #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);
            }
            ...
        }
    }
    

    【讨论】:

    • 哇...这绝对解决了我的问题...非常感谢,真的!我非常感谢你们两个回复我的努力!
    【解决方案2】:
    1. 通过将np 指定为私有,它成为每个单独部分块的私有。将np = omp_get_num_threads(); 复制到每个单独的部分(保持私有)或将其完全移出并行结构(将其从私有中删除)。
    2. 允许节块以任何顺序运行,包括在同一线程上的 4 个块。无法控制输出“0、1、2、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);
         }
     }
     }
    

    【讨论】:

    • 非常感谢您的早日回复!我尝试了你的两种解决方案,但我仍然得到与我为它们描述的相同的输出......无论如何,不​​应该 omp_get_num_threads() 给我正在使用的线程总数吗?那么为什么它给我 1,而且当我使用 omp_get_thread_num() 时总是在 0 上工作?
    • 我确实添加了实际代码。我没有问题。
    • 哇,好吧!我误解了你所说的,我移动了 np = omp_get_max_threads();退出编译指示并行块。好的,这样输出给出了 4 次: Hello from thread 0 out of 4 个线程 但是为什么 id 没有改变?我希望它在每个线程上工作
    • 天哪,有人发帖说我缺少 -fopenmp 标志,这就是我上一条评论的解决方案!但是他删了帖子!非常感谢你们两位!!感谢两者的帮助,现在可以正常工作了!你们是最棒的人
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 2014-08-24
    • 2021-06-17
    • 2017-08-20
    • 1970-01-01
    相关资源
    最近更新 更多