OpenMP while 循环

2023-11-23

我有一个运行多次迭代的代码,只有满足条件时,才会保存迭代的结果。这自然地表示为 while 循环。我试图使代码并行运行,因为每个实现都是独立的。所以我有这个:

while(nit<avit){
    #pragma omp parallel shared(nit,avit)
    {
        //do some stuff
        if(condition){
            #pragma omp critical
            {
                nit++;
                \\save results
            }
        }
    }//implicit barrier here
}

这工作正常...但是每次实现之后都会存在一个障碍,这意味着如果我在并行块内所做的事情在一次迭代中比其他迭代花费的时间更长,那么我的所有线程都在等待它完成,而不是继续下一次迭代。

有没有办法避免这种障碍,使线程继续工作?我平均进行了数千次迭代,所以多进行几次也没有什么坏处(以防万一nit变量在已经运行的线程中尚未增加)...

我试图将其变成并行的 for,但是 for 循环中的自动增量使得nit变量变得疯狂。这是我的尝试:

#pragma omp parallel shared(nit,avit)
{
    #pragma omp for
    for(nit=0;nit<avit;nit++){
        //do some stuff
        if(condition){
            \\save results
        } else {
            #pragma omp critical
            {
                nit--;
            }
        }
    }
}

正如预期的那样,它继续工作并围绕 for 循环进行,但是我的nit变量采用不可预测的值...正如人们可以从不同线程在不同时间增加和减少它所期望的那样。

我也尝试将 for 循环中的增量留空,但它无法编译,或者试图欺骗我的代码,使其在 for 循环中没有增量,例如

...
incr=0;
for(nit=0;nit<avit;nit+=incr)
...

但后来我的代码崩溃了......

有任何想法吗?

Thanks

编辑:这是 while 循环上代码的最小工作示例:

#include <random>
#include <vector>
#include <iostream>
#include <time.h>
#include <omp.h>
#include <stdlib.h>
#include <unistd.h>

using namespace std;

int main(){

    int nit,dit,avit=100,t,j,tmax=100,jmax=10;
    vector<double> Res(10),avRes(10);

    nit=0; dit=0;
    while(nit<avit){
        #pragma omp parallel shared(tmax,nit,jmax,avRes,avit,dit) private(t,j) firstprivate(Res)
        {
            srand(int(time(NULL)) ^ omp_get_thread_num());
            t=0; j=0;
            while(t<tmax&&j<jmax){
                Res[j]=rand() % 10;
                t+=Res[j];
                if(omp_get_thread_num()==5){
                    usleep(100000);
                }
                j++;
            }
            if(t<tmax){
                #pragma omp critical
                {
                    nit++;
                    for(j=0;j<jmax;j++){
                        avRes[j]+=Res[j];
                    }
                    for(j=0;j<jmax;j++){
                        cout<<avRes[j]/nit<<"\t";
                    }
                    cout<<" \t nit="<<nit<<"\t thread: "<<omp_get_thread_num();
                    cout<<endl;
                }
            } else{
                #pragma omp critical
                {
                    dit++;
                    cout<<"Discarded: "<<dit<<"\r"<<flush;
                }
            }
        }
    }
    return 0;
}

我添加了usleep部分来模拟一个线程比其他线程花费更长的时间。如果运行该程序,所有线程都必须等待线程 5 完成,然后才能开始下一次运行。我想要做的正是避免这种等待,即我希望其他线程选择下一个迭代而不等待 5 完成。


您基本上可以遵循与这个问题,略有变化以确保avRes不并行写入:

int nit = 0;
#pragma omp parallel
while(1) {
     int local_nit;
     #pragma omp atomic read
     local_nit = nit;
     if (local_nit >= avit) {
          break;
     }

     [...]

     if (...) { 
          #pragma omp critical
          {
                #pragma omp atomic capture
                local_nit = ++nit;
                for(j=0;j<jmax;j++){
                    avRes[j] += Res[j];
                } 
                for(j=0;j<jmax;j++){
                    // technically you could also use `nit` directly since
                    // now `nit` is only modified within this critical section
                    cout<<avRes[j]/local_nit<<"\t";
                }
          }
     } else {
          #pragma omp atomic update
          dit++;
     }
 }

它也适用于关键区域,但原子效率更高。

还有一件事你需要考虑rand()不应该在并行上下文中使用。看这个问题。对于 C++,使用私有(即在并行区域内定义)随机数生成器<random>.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenMP while 循环 的相关文章

  • 如何确定 std::function 的参数数量?

    我有以下问题 假设您想编写一个可以采用 lambda 表达式的通用函数 我知道如果参数是 std function 类型 那么我不仅可以使用 lambda 还可以使用函数 甚至可以使用函数指针 所以第一步 我做了以下事情 void prin
  • Qt - 无法让 lambda 工作[重复]

    这个问题在这里已经有答案了 我有以下功能 我想在其中修剪我的std set
  • 赋值运算符“=”是原子的吗?

    我正在使用全局变量实现线程间通信 global var volatile bool is true true thread 1 void thread 1 while 1 int rint rand 10 if is true cout l
  • 导致崩溃转储的 Java 错误的解决方法

    我开发的一个程序偶尔会由于这个错误而导致 JVM 崩溃 http bugs java com bugdatabase view bug do bug id 8029516 http bugs java com bugdatabase vie
  • 跟踪循环迭代

    抛硬币 成功 你赢100 否则你输50 你会一直玩 直到你口袋里有钱a 的价值如何a在任何迭代中都被存储 a lt 100 while a gt 0 if rbinom 1 1 0 5 1 a lt a 100 else a lt a 50
  • 如何使信号量超时

    Go 中的信号量是通过通道来实现的 一个例子是这样的 https sites google com site gopatterns concurrency semaphores https sites google com site gop
  • Android:如何使用后台线程?

    我开发了一个应用程序 它从互联网获取内容并相应地在设备的屏幕上显示它 该程序运行得很好 就是有点慢 加载并显示内容大约需要 3 4 秒 我想将获取内容并将其显示在后台线程中的所有代码放在一起 当程序执行这些功能时 我想显示一个进度对话框 你
  • 模拟pytest中的异常终止

    我的多线程应用程序遇到了一个错误 主线程的任何异常终止 例如 未捕获的异常或某些信号 都会导致其他线程之一死锁 并阻止进程干净退出 我解决了这个问题 但我想添加一个测试来防止回归 但是 我不知道如何在 pytest 中模拟异常终止 如果我只
  • 调用线程无法访问该对象,因为另一个线程拥有它

    我已经阅读了很多关于此错误的帖子 但我不明白如何在我的解决方案中解决它 我有一个进度条对话框 其中包含一些逻辑 通过按钮单击从 MainFrame 调用 void OnBtnClick object sender RoutedEventAr
  • 为什么 gcc 链接时没有 lpthread 标志?

    我当时正在做一个业余爱好项目 其中互斥体的行为很神秘 我将其归结为这个显然应该陷入僵局的测试用例 include
  • std::lock 仍然导致死锁

    std lock 是用来防止死锁的 对吗 但在我的测试中 它仍然导致死锁 你能检查一下我的测试代码 看看我是否使用了错误的代码吗 std mutex m1 std mutex m2 void func1 std unique lock
  • C++ 是否可以在 MacOS 上与 OpenMP 和 boost 兼容?

    我现在已经尝试了很多事情并得出了一些结论 也许 我监督了一些事情 但似乎我无法完成我想要的事情 问题是 是否有可能使用 OpenMP 和 boost 在 MacOS High Sierra 上编译 C 一些发现 如果我错了请纠正我 Open
  • 使 Guid 属性成为线程安全的

    我的一个类有一个 Guid 类型的属性 该属性可以由多个线程同时读写 我的印象是对 Guid 的读取和写入不是原子的 因此我应该锁定它们 我选择这样做 public Guid TestKey get lock testKeyLock ret
  • 如何使用 C++11 using 语法键入定义函数指针?

    我想写这个 typedef void FunctionPtr using using 我该怎么做呢 它具有类似的语法 只不过您从指针中删除了标识符 using FunctionPtr void 这是一个Example http ideone
  • 使用/不使用 delegate() 启动线程

    有什么区别 new Thread new ThreadStart SomeFunc and new Thread delegate SomeFunc 这段代码在我的计算机上给出了奇怪的输出 public class A int Num pu
  • 通过 ruby​​ 进程共享变量

    我正在编写一个 gem 其中我必须分叉两个进程来启动两个 webrick 服务器 我想通过基类的类方法启动该服务器 因为应该只运行这两个服务器 而不是多个服务器 在运行时 我想调用这两台服务器上的一些方法来更改变量 我的问题是 我无法通过基
  • 任务并行库周围是否有一个接口包装器,以便我可以将其交换用于单元测试?

    I asked 这个问题 https stackoverflow com questions 3362734 unit testing concurrent software what do you do不久以前 我现在知道这是一个坏主意
  • 为什么我不能用 `= delete;` 声明纯虚函数?

    Intro 纯虚函数使用通用语法声明 virtual f 0 然而 自 c 11 以来 有一种方法可以显式地传达non existence 特殊 成员函数的 Mystruct delete eg default constructor Q
  • 有没有一种简单的方法来准备 Fortran 代码以进行并行调用

    我想使用 OpenMP 在 C 程序中并行求解多个大型 ODE 系统 由于某些原因 我需要使用 ODE 求解器 但我只能找到 Fortran 90 子例程 而且代码太大 无法简单地将其转换为 C 我知道 Fortran 广泛使用静态内存 因
  • Azure 事件中心 - 按顺序接收事件

    我使用下面的代码从 Azure Event Hub 接收事件 https learn microsoft com en us azure event hubs event hubs dotnet framework getstarted s

随机推荐

  • 检测元素外部的点击(普通 JavaScript)

    我到处寻找一个好的解决方案 但找不到一个不使用 jQuery 是否有一种跨浏览器的正常方式 没有奇怪的黑客或容易破坏代码 来检测元素外部的点击 可能有也可能没有子元素 添加事件监听器document并使用Node contains 查找事件
  • ANDROID/WEBVIEW--未捕获类型错误:对象 [对象对象] 在文件中没有方法“changeActivity”:

    我正在尝试使用带有输入框的网络视图 获取字符串 并将其传递给第二个活动 由于某种原因 该按钮没有执行任何操作 我收到错误 未捕获的类型错误 对象 object Object 在 file android asset www index js
  • 如何根据用户选择在ViewPager中设置当前页面以及如何知道哪个列表项调用了活动

    我是新来的Android programming 我有一个项目列表 当用户单击某个项目时 会将他们带到包含该项目详细信息的屏幕 我希望用户能够左右滑动以查看列表中其他项目的详细信息 而不是返回列表并选择另一个项目 我读到我需要使用ViewP
  • Access 数据库的只读连接字符串

    我正在尝试使用 System Data OleDb OleDbConnection 连接到 Access 数据库文件 我需要以只读模式连接 因为另一个应用程序同时使用它 我可以以读 写方式连接到数据库 没有问题 但似乎无法在任何地方找到正确
  • 使用 AttachConsole,当我附加的进程正在运行并喷出时,我仍然可以键入并运行其他命令

    使用 AttachConsole 当我附加的进程正在运行并喷出时 我仍然可以键入并运行其他命令 我的程序以表单或命令行运行 如果以参数启动 它将在命令窗口中运行 我使用 AttachConsole 1 将我的进程附加到我调用的命令窗口 它工
  • 从正在运行的进程注入 DLL 后弹出

    我编写了这个函数来将 DLL 注入到正在运行的进程中 DLL Results CDLL Loader InjectDll DWORD ThreadTeminationStatus LPVOID VirtualMem HANDLE hProc
  • 比较今天或昨天的 NSDate

    好吧 我想这个问题已经被问过一千次了 但由于某种原因 答案并没有真正起作用或有其他问题 无论如何 这就是我的 工作 NSCalendar calendar NSCalendar currentCalendar NSDate currentD
  • Angular 指令不评估 ng-repeat 内部

    我有以下设置 应用程序 指令 var app angular module MyApp app directive adminRosterItem function return restrict E scope displayText t
  • FindFirstFileEx 的文件系统支持,仅限于目录

    我正在使用Windows API函数查找第一个文件Ex因为它提供了仅返回给定目录的子目录 忽略文件 的功能 但是 当我使用 required 标志调用此函数时 我仍然会收到文件和目录 MSDN 文档的FindExSearchLimitToD
  • 合法的数组赋值。是否可以?

    在阅读了 K R 书中有关结构的章节后 我决定做一些测试来更好地理解它们 所以我写了这段代码 include
  • OpenIdConnectAuthenticationHandler:message.State 为 null 或为空

    我正在使用 ASP Net Core 应用程序的 UseOpenIdConnectAuthentication 中间件来针对戴尔云访问管理器令牌提供商进行身份验证 设置以提供 OpenId OAuth2 身份验证 以下是代码 app Use
  • 全文搜索是答案吗?

    好的 我有一个看起来像这样的 mySQL 数据库 ID 一个 int 和记录的唯一 ID 标题 项目的名称 描述 项目描述 我想搜索目前我正在使用的关键字的标题和描述 选择 来自 项目 其中标题类似 key 这是可行的 因为数据库中没有太多
  • Memcached:AWS Elasticache 上的自动发现 python 支持?

    我开始将 AWS Elasticache 与我的 django Web 应用程序结合使用 我首先使用自动发现功能将缓存位置设置为唯一端点 但它似乎不起作用 我使用 pylibmc 1 2 2 和 django pylibmc sasl 0
  • 在 Windows Server 2008 上构建 Windows Phone 7 项目

    我的公司正计划针对 Windows Phone 7 进行开发 但是 我们拥有的构建服务器运行的是 Windows Server 2008 根据Windows Phone SDK 发行说明我了解到该 SDK 仅不支持 Windows Serv
  • 有哪些好方法可以防止人们复制我的源代码? [关闭]

    Closed 这个问题需要多问focused 目前不接受答案 我有很多定制的 JavaScript 和布局设计 我想阻止人们使用这些 有没有什么实用的方法可以做到这一点 或者我基本上只需要高兴我的 php 代码没有显示 我想让至少让复制我的
  • 如何查看 git 中忽略的文件列表?

    过去几个月我一直在使用 git 我喜欢 git 我想知道是否有一个命令可以显示项目中被忽略的文件列表 我试过这个git status ignored从项目的根目录 但这似乎还不够 您可以使用clean带有选项的命令 n dry run Do
  • awk:对数组a的非法引用

    我正在尝试使用这个 awk 命令 awk F FILENAME ARGV 1 a FNR 1 FILENAME ARGV 2 for i 1 i lt length a i if match 0 a i print a i 1 16 pas
  • Autohotkey 应用程序特定热键

    我是 Autohotkey 的新手 尽管阅读了这个网站和官方文档 但我还是无法弄清楚这一点 我只想让某些热键仅适用于某些应用程序 例如 如果我在某个游戏中按空格键 我希望它发送 坟墓 但如果我不在该游戏中 我希望空格键正常工作 当我不玩游戏
  • ESLint:插件“react”之间存在冲突

    我在一个整体 npm 组件包内有一个 React 应用程序 React 应用程序用作演示站点 它使用此组件包作为 Storybook 之上的集成步骤 local component package storybook demos react
  • OpenMP while 循环

    我有一个运行多次迭代的代码 只有满足条件时 才会保存迭代的结果 这自然地表示为 while 循环 我试图使代码并行运行 因为每个实现都是独立的 所以我有这个 while nit