c – 在同一线程上运行的所有OpenMP任务

c – 在同一线程上运行的所有OpenMP任务,第1张

概述我在OpenMP中使用任务编写了一个递归并行函数.虽然它给了我正确的答案并且运行良好但我认为并行性存在问题.与串行解决方案相比,运行时不会在我没有任务的情况下解决的同一个其他并行问题中扩展.当为每个线程打印任务时,它们都在线程0上运行.我正在Visual Studio Express 2013上编译并运行. int parallelOMP(int n){ int a, b, sum = 我在OpenMP中使用任务编写了一个递归并行函数.虽然它给了我正确的答案并且运行良好但我认为并行性存在问题.与串行解决方案相比,运行时不会在我没有任务的情况下解决的同一个其他并行问题中扩展.当为每个线程打印任务时,它们都在线程0上运行.我正在Visual Studio Express 2013上编译并运行.

int parallelOMP(int n){    int a,b,sum = 0;    int Alpha = 0,beta = 0;    for (int k = 1; k < n; k++)    {        a = n - (k*(3 * k - 1) / 2);        b = n - (k*(3 * k + 1) / 2);        if (a < 0 && b < 0)            break;        if (a < 0)            Alpha = 0;        else if (p[a] != -1)            Alpha = p[a];        if (b < 0)            beta = 0;        else if (p[b] != -1)            beta = p[b];        if (a > 0 && b > 0 && p[a] == -1 && p[b] == -1)        {            #pragma omp parallel            {                #pragma omp single                {                    #pragma omp task shared(p),untIEd                    {                        cout << omp_get_thread_num();                        p[a] = parallelOMP(a);                    }                    #pragma omp task shared(p),untIEd                    {                        cout << omp_get_thread_num();                        p[b] = parallelOMP(b);                    }                    #pragma omp taskwait                }            }            Alpha = p[a];            beta = p[b];        }        else if (a > 0 && p[a] == -1)        {            #pragma omp parallel            {                #pragma omp single                {                    #pragma omp task shared(p),untIEd                    {                        cout << omp_get_thread_num();                        p[a] = parallelOMP(a);                    }                    #pragma omp taskwait                }            }            Alpha = p[a];        }        else if (b > 0 && p[b] == -1)        {            #pragma omp parallel            {                #pragma omp single                {                    #pragma omp task shared(p),untIEd                    {                        cout << omp_get_thread_num();                        p[b] = parallelOMP(b);                    }                    #pragma omp taskwait                }            }            beta = p[b];        }        if (k % 2 == 0)            sum += -1 * (Alpha + beta);        else            sum += Alpha + beta;    }    if (sum > 0)        return sum%m;    else        return (m + (sum % m)) % m;}
解决方法 实际问题:

您正在使用Visual Studio 2013.

Visual Studio从未支持超过2.0的OMP版本(参见here).

OMP任务是OMP 3.0的一项功能(参见spec).

因此,使用VS一定意味着没有OMP任务.

如果OMP任务是基本要求,请使用其他编译器.如果OMP不是必要条件,则应考虑使用备用并行任务处理库. Visual Studio包含MS并发运行时,以及基于它的@L_404_2@.我最近从OMP转到了PPL,因为我正在使用VS工作;它不是一个简单的替代品,但它非常有能力.

我的第二次尝试解决这个问题,由于历史原因再次保留:

因此,几乎可以肯定的是,您在omp并行区域之外定义了omp任务.

这是一个人为的例子:

voID work(){    #pragma omp parallel    {        #pragma omp single Nowait        for (int i = 0; i < 5; i++)        {            #pragma omp task untIEd            {                std::cout <<                     "starting task " << i <<                     " on thread " << omp_get_thread_num() << "\n";                sleep(1);            }        }    }}

如果省略并行声明,则作业将按顺序运行:

starting task 0 on thread 0starting task 1 on thread 0starting task 2 on thread 0starting task 3 on thread 0starting task 4 on thread 0

但如果你把它留在:

starting task starting task 3 on thread 1starting task 0 on thread 32 on thread 0starting task 1 on thread 2starting task 4 on thread 2

成功,完全正确滥用共享输出资源.

(作为参考,如果省略单个声明,每个线程将运行循环,导致在我的4 cpu VM上运行20个任务).

原始答案包括下面的完整性,但不再相关!

在每种情况下,你的omp任务都是一件简单的事情.它可能会立即运行并完成:

#pragma omp task shared(p),untIEdcout << omp_get_thread_num();#pragma omp task shared(p),untIEdcout << omp_get_thread_num();

因为在开始下一个任务之前你永远不会启动一个长时间运行的任务,所以一切都可能在第一个分配的线程上运行.

也许你打算做这样的事情?

if (a > 0 && b > 0 && p[a] == -1 && p[b] == -1){    #pragma omp task shared(p),untIEd    {        cout << omp_get_thread_num();        p[a] = parallelOMP(a);    }    #pragma omp task shared(p),untIEd    {        cout << omp_get_thread_num();        p[b] = parallelOMP(b);    }    #pragma omp taskwait    Alpha = p[a];    beta = p[b];}
总结

以上是内存溢出为你收集整理的c – 在同一线程上运行的所有OpenMP任务全部内容,希望文章能够帮你解决c – 在同一线程上运行的所有OpenMP任务所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1220107.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存