MPI+p 线程。程序卡在 MPI_Ssend 和 MPI_Recv 上

2024-03-27

我已经调试了这个程序2周了。它只有 93 行。但我仍然找不到错误。请帮我。

这个程序在我的笔记本电脑上运行正常。但是当我在我的实验室、上海超算中心和济南超算中心的集群上运行时,就卡住了。

这个程序的逻辑非常简单。有 2 个 MPI 进程。一个是主站(pid = 0),另一个是从站(pid = 1)。主站等待 tag = 0 上的请求。从站每秒向主站 tag:0 发送消息并等待 ACK 消息。一旦主机收到请求,主机将向从机 tag:100 发送 ACK 消息。

问题是几秒钟后程序就会卡住。 Master 将停留在 MPI_Recv,等待 tag:0 上的请求。从站将停留在 MPI_Ssend,尝试向主站 tag:0 发送消息。 此 MPI 通信应相互匹配。但不知道为什么卡住了。

一些提示: 程序在以下情况下不会卡住:

1.在pthread_create(&tid,&attr,master_server_handler,NULL);后面添加sleep()函数在 void *master_server(void *null_arg) 函数中。

Or

2.使用joinable pthread属性而不是detachable属性来创建master_server_handler。 (pthread_create(&tid,&attr,master_server_handler,NULL); 将其替换为 pthread_create(&tid,NULL,master_server_handler,NULL); )

Or

3.使用master_server_handler函数代替pthread_create(&tid,&attr,master_server_handler,NULL);。

Or

4.将 void *master_server_handler(void *arg) 中的 MPI_Ssend 替换为 MPI_Send。

该程序在每种情况下都可以。 所有这些修改都可以在程序的注释中找到。

不知道为什么会卡住。我尝试了 openmpi 和 mpich2。该程序将卡在他们两个上。

任何提示请...

如果需要的话我可以提供我实验室的VPN。您可以登录我实验室的集群。 (电子邮件:[电子邮件受保护] /cdn-cgi/l/email-protection)

顺便提一句: 我在编译openmpi和mpich2时启用了线程支持的参数。对于 openmpi,参数为 --with-threads=poxis --enable-mpi-thread-multiple。 Mpich2 是 --enable-threads。


我实验室的机器是CentOS。 uname -a 的输出是 Linux node5 2.6.18-238.12.1.el5xen #1 SMP Tue May 31 14:02:29 EDT 2011 x86_64 x86_64 x86_64 GNU/Linux。

我使用以下方式运行该程序:mpiexec -n 2 ./a.out

以下是源代码、程序的输出、程序卡住时的回溯信息。

源代码

#include "stdio.h"
#include "pthread.h"
#include "stdlib.h"
#include "string.h"
#include "mpi.h"

void send_heart_beat();
void *heart_beat_daemon(void *null_arg);
void *master_server(void *null_arg);
void *master_server_handler(void *arg);

int main(int argc,char *argv[])
{
    int p,id;
    pthread_t tid;

    MPI_Init(&argc,&argv);
    MPI_Comm_size(MPI_COMM_WORLD,&p);
    MPI_Comm_rank(MPI_COMM_WORLD,&id);

    if(id==0)
    {
        //master
        pthread_create(&tid,NULL,master_server,NULL);
        pthread_join(tid,NULL);
    }
    else
    {
        //slave
        pthread_create(&tid,NULL,heart_beat_daemon,NULL);
        pthread_join(tid,NULL);
    }

    MPI_Finalize();

    return 0;
}

void *heart_beat_daemon(void *null_arg)
{
    while(1)
    {
        sleep(1);
        send_heart_beat();
    }
}

void send_heart_beat()
{
    char send_msg[5];
    char ack_msg[5];

    strcpy(send_msg,"AAAA");

    MPI_Ssend(send_msg,5,MPI_CHAR,0,0,MPI_COMM_WORLD);

    MPI_Recv(ack_msg,5,MPI_CHAR,0,100,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
}

void *master_server(void *null_arg)
{
    char msg[5];

    pthread_t tid;
    pthread_attr_t attr;

    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);

    while(1)
    {

        MPI_Recv(msg,5,MPI_CHAR,1,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);

        pthread_create(&tid,&attr,master_server_handler,NULL);
//      sleep(2);
//      master_server_handler(NULL);
//      pthread_create(&tid,NULL,master_server_handler,fun_arg);
//      pthread_join(tid,NULL);
    }
}

void *master_server_handler(void *arg)
{
    static int count;
    char ack[5];

    count ++;
    printf("recved a msg %d\n",count);

    strcpy(ack,"ACK:");
    MPI_Ssend(ack,5,MPI_CHAR,1,100,MPI_COMM_WORLD);
//  MPI_Send(ack,5,MPI_CHAR,1,100,MPI_COMM_WORLD);
}       

程序的输出:

    recved a msg 1
    recved a msg 2
    recved a msg 3
    recved a msg 4
    recved a msg 5
    recved a msg 6
    recved a msg 7
    recved a msg 8
    recved a msg 9
    recved a msg 10
    recved a msg 11
    recved a msg 12
    recved a msg 13
    recved a msg 14
    recved a msg 15

卡住时master的回溯:

    (gdb) bt
    #0  opal_progress () at runtime/opal_progress.c:175
    #1  0x00002b17ed288f75 in opal_condition_wait (addr=<value optimized out>,
        count=<value optimized out>, datatype=<value optimized out>, src=1, tag=0,
        comm=0x601520, status=0x0) at ../../../../opal/threads/condition.h:99
    #2  ompi_request_wait_completion (addr=<value optimized out>,
        count=<value optimized out>, datatype=<value optimized out>, src=1, tag=0,
        comm=0x601520, status=0x0) at ../../../../ompi/request/request.h:377
    #3  mca_pml_ob1_recv (addr=<value optimized out>, count=<value optimized out>,
        datatype=<value optimized out>, src=1, tag=0, comm=0x601520, status=0x0)
        at pml_ob1_irecv.c:105
    #4  0x00002b17ed1ef049 in PMPI_Recv (buf=0x2b17f2495120, count=5,
        type=0x601320, source=1, tag=0, comm=0x601520, status=0x0) at precv.c:78
    #5  0x0000000000400d75 in master_server (null_arg=0x0) at main.c:73
    #6  0x0000003b5a00683d in start_thread () from /lib64/libpthread.so.0
    #7  0x0000003b594d526d in clone () from /lib64/libc.so.6

卡住时从站的回溯:

    (gdb) bt
    #0  0x00002adff87ef975 in opal_atomic_cmpset_32 (btl=<value optimized out>, endpoint=<value optimized out>,
        registration=0x0, convertor=0x124e46a8, order=0 '\000', reserve=32, size=0x2adffda74fe8, flags=3)
        at ../../../../opal/include/opal/sys/amd64/atomic.h:85
    #1  opal_atomic_lifo_pop (btl=<value optimized out>, endpoint=<value optimized out>, registration=0x0,
        convertor=0x124e46a8, order=0 '\000', reserve=32, size=0x2adffda74fe8, flags=3)
        at ../../../../opal/class/opal_atomic_lifo.h:100
    #2  mca_btl_sm_prepare_src (btl=<value optimized out>, endpoint=<value optimized out>, registration=0x0,
        convertor=0x124e46a8, order=0 '\000', reserve=32, size=0x2adffda74fe8, flags=3) at btl_sm.c:697
    #3  0x00002adff8877678 in mca_bml_base_prepare_src (sendreq=0x124e4600, bml_btl=0x124ea860, size=5, flags=0)
        at ../../../../ompi/mca/bml/bml.h:339
    #4  mca_pml_ob1_send_request_start_rndv (sendreq=0x124e4600, bml_btl=0x124ea860, size=5, flags=0)
        at pml_ob1_sendreq.c:815
    #5  0x00002adff8869e82 in mca_pml_ob1_send_request_start (buf=0x2adffda75100, count=5,
        datatype=<value optimized out>, dst=0, tag=0, sendmode=MCA_PML_BASE_SEND_SYNCHRONOUS, comm=0x601520)
        at pml_ob1_sendreq.h:363
    #6  mca_pml_ob1_send (buf=0x2adffda75100, count=5, datatype=<value optimized out>, dst=0, tag=0,
        sendmode=MCA_PML_BASE_SEND_SYNCHRONOUS, comm=0x601520) at pml_ob1_isend.c:119
    #7  0x00002adff87d2be6 in PMPI_Ssend (buf=0x2adffda75100, count=5, type=0x601320, dest=0, tag=0,
        comm=0x601520) at pssend.c:76
    #8  0x0000000000400cf4 in send_heart_beat () at main.c:55
    #9  0x0000000000400cb6 in heart_beat_daemon (null_arg=0x0) at main.c:44
    #10 0x0000003b5a00683d in start_thread () from /lib64/libpthread.so.0
    #11 0x0000003b594d526d in clone () from /lib64/libc.so.6

MPI 提供四种不同级别的线程支持:MPI_THREAD_SINGLE, MPI_THREAD_SERIALIZED, MPI_THREAD_FUNNELED, and MPI_THREAD_MULTIPLE。为了能够同时从不同线程进行 MPI 调用,您必须使用以下命令初始化 MPIMPI_THREAD_MULTIPLE线程支持级别并确保库实际提供该级别:

int provided;

MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided);
if (provided < MPI_THREAD_MULTIPLE)
{
   printf("Error: the MPI library doesn't provide the required thread level\n");
   MPI_Abort(MPI_COMM_WORLD, 0);
}

如果你打电话MPI_Init代替MPI_Init_thread,库可以自由选择其创建者认为最好的任何默认线程支持级别。对于开放 MPI 来说是MPI_THREAD_SINGLE,即不支持线程。您可以通过设置环境变量来控制默认级别OMPI_MPI_THREAD_LEVEL但不建议这样做 -MPI_Init_thread应该使用。

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

MPI+p 线程。程序卡在 MPI_Ssend 和 MPI_Recv 上 的相关文章

  • 使用 MPI 在 C 中发送二维数组块

    如何将二维数组块发送到不同的处理器 假设 2D 数组大小为 400x400 我想将大小为 100X100 的块发送到不同的处理器 这个想法是每个处理器将在其单独的块上执行计算并将其结果发送回第一个处理器以获得最终结果 我在 C 程序中使用
  • MPI_Isend 和 MPI_Irecv 似乎导致死锁

    我在 MPI 中使用非阻塞通信在进程之间发送各种消息 然而 我似乎陷入了僵局 我用过PADB see here http padb pittman org uk 查看消息队列并得到以下输出 1 msg12 Operation 1 pendi
  • 从命令为 pthread 引导 symfony2

    我正在尝试从 symfony 2 命令启动线程 protected function execute InputInterface input OutputInterface output parser this gt getContain
  • R 在 HPC MPIcluster 上运行 foreach dopar 循环

    我可以访问带有 MPI 分区的 HPC 集群 我的问题是 无论我尝试什么 我的代码 在我的 PC 上运行良好 都无法在 HPC 集群上运行 代码如下所示 图书馆 TM 图书馆 qdap 图书馆 雪 图书馆 doSNOW 库 foreach
  • Posix 线程问题

    我试图通过示例来理解 pthreads 我编写了以下代码 每次运行时都会给出不同的答案 有人可以解释一下这个错误吗 TIA 斯维亚 代码在这里 include
  • mingw 中的 libpthread 找不到库

    我正在尝试使用 mingw 编译以下程序 include
  • 使用 MPJ Express 发送对象

    我是并行编程的新手 我想用 java 来完成它 我想知道是否可以通过 MPI 发送和接收更复杂的对象 我用的是 MPJ Express 然而 每当我想发送一个对象时 我都会收到 ClassCastException MPI Init arg
  • 在 Linux 上以 root 身份调用 SCHED_FIFO 线程的 pthread_create() 时获取 EPERM

    我试图在 Linux 系统上以 SCHED FIFO 或 SCHED RR 策略作为 root 生成线程 但我对 pthread create 的调用返回 1 EPERM pthread create 的手册页指出 EPERM 指示 调用者
  • 使用 pthread_create 时出现 valgrind 内存泄漏错误

    我正在使用 pthread 库编写一个程序 当我使用命令运行程序时valgrind leak check full 我得到以下错误描述 11784 11784 HEAP SUMMARY 11784 in use at exit 4 952
  • Android 上的 pthread_create 警告

    打电话后pthread create函数我收到下一条消息 W libc 26409 pthread create sched setscheduler 调用失败 不允许操作 用于创建线程的代码是 pthread attr t threadA
  • 将工作分配给更多线程需要更多时间,为什么?

    我有一个小的 C 程序可以计算pi用一个蒙特卡洛 http en wikipedia org wiki Monte Carlo method Introduction 模拟基本上只是测试随机点 x y 是否在圆内部或外部 近似pi我必须使用
  • 从 pthread 调用 sleep() 是否会使线程或进程进入睡眠状态?

    我看到有一个关于linux pthread睡眠 https stackoverflow com questions 3633089 pthread sleep linux 然而 当我在 Linux 机器上查找手册页时 我看到以下内容 概要
  • C库函数获取活动线程数

    我正在用 C 语言开发一个多线程 Unix 应用程序 有没有一种简单的方法来获取同时活动线程的数量 如果库已经可以为我完成的话 我不想编写代码来跟踪活动线程的数量 我正在使用 POSIX pthreads 并且我正在尝试为 Unix 和类
  • 什么是“收到信号 15”

    什么可能导致 C MPI 程序使用名为的库日晷 CVODE https computation llnl gov casc sundials documentation documentation html 数值 ODE 求解器 在 Gen
  • MPI 矩阵向量乘法返回有时正确有时奇怪的值

    我有以下代码 Start MPI MPI Init argc argv int size atoi argv 1 int delta 10 int rnk int p int root 0 MPI Status mystatus MPI C
  • pthread_join() 用于异步线程

    我写了一个简单的演示程序 以便我可以理解pthread join 功能 我知道如何使用pthread condition wait 函数允许异步线程 但我试图了解如何使用pthread join 功能 在下面的程序中我通过线程1s ID t
  • 在不阻塞的情况下“通知”处理器的正确方法是什么?

    假设我有很多东西 我必须对所有这些东西进行一些操作 如果一个元素的操作失败 我想停止整个阵列的工作 这项工作分布在多个处理器上 我想实现这一目标 同时将发送 接收的消息数量保持在最低限度 另外 如果没有必要 我不想阻止处理器 我该如何使用
  • c++11 #include 给出编译错误

    尝试从已编译的源文件创建目标文件时出现编译错误 我正在使用 c 11 附带的标头 我还使用 C 模式识别库和其他几个包含的库 我所做的只是添加 include
  • Linux 中的 C 聊天室 / Socket 编程

    我有一个简单的服务器和客户端 C 代码来使用线程 pthread 库 为多客户端创建一个聊天室 我一直遇到的问题是 我无法想出一种方法让服务器将客户端通过套接字发送到所有其他客户端的每条消息写入 我在这里读过其他类似的帖子 但很无奈 请帮助
  • 数百个空闲线程的影响

    我正在考虑使用可能数百个线程来实现通过网络管理设备的任务 这是一个在带有 Linux 内核的 powerpc 处理器上运行的 C 应用程序 在每个任务进行同步以将数据从设备复制到任务的初始阶段之后 任务变得空闲 并且仅在收到警报或需要更改一

随机推荐

  • jQuery Panzoom 插件将图像定位在右侧,包含:'invert'

    我正在尝试使用jQuery 全景缩放 https github com timmywil jquery panzoom插件 基本上都很好 除了 我希望最初缩放大图像以适合容器 并且有contain invert 已启用 我已经适应了这个例子
  • Windows 批处理:杀死进程

    我正在运行多个具有相同名称的进程 我希望有一个选项可以从批处理脚本中杀死它们 我需要一些与 unix shell 命令非常相似的东西 kill 9 ps axuw grep MY PROCESS NAME awk print 2 有什么建议
  • 使用 OperatorPrecedenceParser 通过 FParsec 解析函数应用程序?

    问题类似于this one https stackoverflow com questions 7199589 parsing method arguments with fparsec 但我想使用函数应用程序来解析表达式OperatorP
  • Laravel 5 无限滚动 + 分页

    对于在 l5 中使用 paginate 进行无限滚动 我发现了很多文章 但它们都使用这个 paginate 函数 因为它们使用来自 db 的结果集 但我从 googlefontapi 获取数据作为 json 所以当我在 json 中使用 p
  • 如何在 SQL 中查找去年的同一个工作日?

    通常在销售报告等中 您需要将这一天与去年的同一天进行比较 但基于相同的 工作日 而不是 每月的某一天 例如 今天是 2013 年 6 月 20 日 星期四 我希望看到今天的销售额与去年同一个星期四的销售额 2012 年 6 月 21 日 而
  • 如何抑制由我​​无法更改的代码显示的对话框?

    我有一个来自第 3 方的 Inproc COM 服务器 我调用的函数之一如果捕获特定类型的错误 将显示错误消息对话框 问题是我正在尝试批量处理数据 而我正在使用的数据源导致错误对话框频繁弹出 如果它产生 1000 个对话框 这不会成为问题
  • javascript 内联有什么好的理由吗

    我一直在建立一个网站 在某个阶段 我注意到 IE 显示有点损坏 Chrome 几乎除了 body 标签 空 之外什么都没有渲染 而 FF 看起来都不错 在把键盘扔到房间里并用头撞鼠标后 我发现了问题 我在内联脚本块中留下了未关闭的 HTML
  • 运行 kubectl exec 时禁用 Kubernetes 上的网络日志

    跑步kubectl exec it
  • Oracle - 返回新插入的键值

    我们有一个带有主键的表 该表在插入时由表上的触发器填充 触发器从我们为表创建的序列中获取下一个序列号 并将其用作插入时键的值 现在我们希望能够在插入过程 PL SQL 中返回该值 类似于 SQL Server 中的 select scope
  • 为什么 .gitconfig [includeIf] 不起作用?

    系统设置 MacOS Catalina 10 15 6 gt git version git version 2 24 3 Apple Git 128 file gitconfig user name nickname email emai
  • 如何将大型对象/数组序列化为 JSON

    我的应用程序需要生成一个具有大对象的 jsondata数组类型的属性 数组在收集数据库输出时需要保留在内存中 并且某些属性只有在数组完成后才能确定 复杂性 数组是基于数字的 并且必须在 json 输出中出现 因此直接json encode
  • 使用内联“宽度”时省略像素

    这是一个有点愚蠢的问题 但对我来说理解很重要 据我所知 在 HTML 中使用内联 width 属性时 允许省略 px 除非使用百分比 20 否则将自动被理解为 20px 我的问题是 即使不需要 px 使用它是否错误 这段代码对我来说看起来非
  • 如何更改/usr/bin/env?

    我有使用的脚本 usr bin env ruby但我已经改用 Ruby Enterprise Edition 而不是 Ubuntu 服务器附带的默认 ruby 因此 当我尝试运行脚本时 它们会崩溃 如何添加 Ruby EE 路径 usr b
  • 如何使用 Apache POI 对 Excel 工作表中的行应用背景颜色?

    我正在使用 Apache POI 将数据导出到 Excel 工作表中 效果很好 问题是我需要在生成 Excel 工作表时为 Excel 工作表中的几行应用黄色背景颜色 请告诉我如何在生成时为 Excel 工作表的行应用背景颜色 谢谢 雷迪
  • 单父实体的核心数据性能

    我正在创建一个与核心数据一起使用的框架 在核心数据类上使用我的框架的要求之一是 您想要拥有框架功能的任何实体都需要是我提供给您的实体的子实体和子类 为此 我将该对象称为 Foo 今天我意识到 Core Data 将作为 Foo 子实体的所有
  • 在 Studio 中将大写字母转换为驼峰字母的简单方法?

    我有一堆 C 定义需要移植到 C C 定义是带下划线的大写字母 Net 枚举应该是驼峰式 有什么办法可以自动转换它们吗 一些我不知道的工具 或者也许是一个神奇的正则表达式 eg BOOTSTRAP NOT SUPPORTED gt Boot
  • 如何在进程的内存中搜索特定字符串?

    我对基础知识感兴趣 我不知道从哪里开始 我创建了这个测试程序 include
  • 如何在 LinqPad 中执行 ODATA 扩展

    我正在使用 LINQPad 连接到本地 CRM 组织上的 ODATA 服务 但我不知道如何使用 LINQPad 执行 联接 或遍历关系 这是我的网址 OrganizationData svc New locationSet select n
  • 如何在 Mac 上安装 NVM

    我尝试使用以下命令在 Mac 上安装 NVM curl o https raw githubusercontent com nvm sh nvm v0 39 1 install sh bash 但是 我收到一条错误消息 语法错误接近意外的
  • MPI+p 线程。程序卡在 MPI_Ssend 和 MPI_Recv 上

    我已经调试了这个程序2周了 它只有 93 行 但我仍然找不到错误 请帮我 这个程序在我的笔记本电脑上运行正常 但是当我在我的实验室 上海超算中心和济南超算中心的集群上运行时 就卡住了 这个程序的逻辑非常简单 有 2 个 MPI 进程 一个是