我们写完mpi代码以后需要通过执行命令运行写好的代码,此时在运行命令中加入设置参数可以更好的控制程序的运行,这里就介绍一下自己常用的几种参数设置。

相关资料,参看前文:

https://www.cnblogs.com/devilmaycry812839668/p/15107935.html

现有硬件:两台装有Ubuntu18.04的操作系统(下面简称A电脑,B电脑)

A电脑: 24物理核心(48逻辑核心)

B电脑:6物理核心(12逻辑核心)

网络:

A、B电脑之间使用100M以太网交换机连接(就是TP-Link路由器)。

其中,A电脑IP为 192.168.11.66,   B电脑IP为 192.168.11.206

本文中的代码   x.py  :

from mpi4py import MPI
import numpy as np comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank() sendbuf = np.zeros(100*10000, dtype='i') + rank
recvbuf = None
if rank == 0:
recvbuf = np.empty([size, 100*10000], dtype='i') print( MPI.Get_processor_name() ) import time
a = time.time()
for _ in range(1):
comm.Gather(sendbuf, recvbuf, root=0)
b = time.time()
if rank == 0:
print(b-a)

还有特别注意,本文所有的命令均为在主机A上执行,所以本文中对myhosts文件的编写都是在A主机下进行的。

====================================================

1.   参数   --machinefile

该参数主要是用在分布式环境下,在单机环境该参数没有意义。该参数就是指定分布式环境下有几台主机,并且可以指定每台主机最多可以开几个CPU进行计算。

具体命令:

mpirun -np 8  --machinefile myhosts   /home/xxx/anaconda3/bin/python x.py

其中, myhosts 为我们需要编写的文本文件,该文件指定mpi分布式环境下各个主机的IP及可以运行的最多CPU数。

myhosts文件最基本的设置就是不指定每个主机最多可以运行的CPU数,那么此时每台主机最多可以运行的CPU数为多少呢,这时每台主机最多可以运行的CPU数为该主机的物理CPU核心数,本文中主机A 192.168.11.66的最多可以运行CPU数为24, 主机B  192.168.11.206最多可以运行的CPU数为6。

最基本的 myhosts :

cat myhosts

192.168.11.66
192.168.11.206

myhosts中给出分布式环境下两个主机IP,此时每个主机最多可以使用的CPU数为物理核心个数。

执行命令:

mpirun -np 8  --machinefile myhosts   /home/xxxxxx/anaconda3/bin/python x.py

运行结果显示8个进程均运行在主机A上  (因为运行命令本身就是在主机A上运行的,所有优先使用主机A的计算资源)。

执行命令:

mpirun -np 24  --machinefile myhosts   /home/xxxxxx/anaconda3/bin/python x.py

运行结果显示24个进程均运行在主机A上  (因为运行命令本身就是在主机A上运行的,所有优先使用主机A的计算资源)。

执行命令:

mpirun -np 25  --machinefile myhosts   /home/xxxxxx/anaconda3/bin/python x.py

运行结果显示共运行25个进程,其中24个进程运行在主机A上, 一个进程运行在主机B上  (因为运行命令本身就是在主机A上运行的,所有优先使用主机A的计算资源)。

因为主机A最多可以利用的CPU个数为24,所以需要有一个进程运行在主机B上。

执行命令:

mpirun -np 30  --machinefile myhosts   /home/xxxxxx/anaconda3/bin/python x.py

运行结果显示共运行30个进程,其中24个进程运行在主机A上, 6个进程运行在主机B上  (因为运行命令本身就是在主机A上运行的,所有优先使用主机A的计算资源)。

因为主机A最多可以利用的CPU个数为24,所以需要有6个进程运行在主机B上。

执行命令:

mpirun -np 31  --machinefile myhosts   /home/xxxxxx/anaconda3/bin/python x.py

运行结果报错,显示信息:

--------------------------------------------------------------------------
There are not enough slots available in the system to satisfy the 31
slots that were requested by the application: /home/xxxxxx/anaconda3/bin/python Either request fewer slots for your application, or make more slots
available for use. A "slot" is the Open MPI term for an allocatable unit where we can
launch a process. The number of slots available are defined by the
environment in which Open MPI processes are run: 1. Hostfile, via "slots=N" clauses (N defaults to number of
processor cores if not provided)
2. The --host command line parameter, via a ":N" suffix on the
hostname (N defaults to 1 if not provided)
3. Resource manager (e.g., SLURM, PBS/Torque, LSF, etc.)
4. If none of a hostfile, the --host command line parameter, or an
RM is present, Open MPI defaults to the number of processor cores In all the above cases, if you want Open MPI to default to the number
of hardware threads instead of the number of processor cores, use the
--use-hwthread-cpus option. Alternatively, you can use the --oversubscribe option to ignore the
number of available slots when deciding the number of processes to
launch.
--------------------------------------------------------------------------

报错信息显示可以运行的CPU个数不够,因为A主机最多运行24个CPU,B主机最多运行6个CPU,所以当前系统下最多可以运行的CPU个数为30,超出这个个数则会报错。

 2.  参数  slots

进阶版的myhosts的编写,指定每个主机最多可以使用的CPU个数,这个CPU个数最好是小于指定主机的物理核心数,否则该设定没有意义:

cat myhosts

192.168.11.66       slots=4
192.168.11.206 slots=4

指定主机A 、B中每个主机最多可以使用cpu个数均为4,其中每个主机IP(或主机名)后面的的slots的数值可以自由设定,不过只能小于等于该主机的物理核心数。

执行命令:

mpirun -np 4  --machinefile myhosts   /home/xxxxxx/anaconda3/bin/python x.py

运行结果显示4个进程全部运行在主机A上。

执行命令:

mpirun -np 6  --machinefile myhosts   /home/xxxxxx/anaconda3/bin/python x.py

运行结果显示4个进程全部运行在主机A上,2个进程运行在主机B上。

执行命令:

mpirun -np 8  --machinefile myhosts   /home/xxxxxx/anaconda3/bin/python x.py

运行结果显示4个进程全部运行在主机A上,4个进程运行在主机B上。

执行命令:

mpirun -np 9  --machinefile myhosts   /home/xxxxxx/anaconda3/bin/python x.py

运行结果报错,显示信息:

--------------------------------------------------------------------------
There are not enough slots available in the system to satisfy the 31
slots that were requested by the application: /home/xxxxxx/anaconda3/bin/python Either request fewer slots for your application, or make more slots
available for use. A "slot" is the Open MPI term for an allocatable unit where we can
launch a process. The number of slots available are defined by the
environment in which Open MPI processes are run: 1. Hostfile, via "slots=N" clauses (N defaults to number of
processor cores if not provided)
2. The --host command line parameter, via a ":N" suffix on the
hostname (N defaults to 1 if not provided)
3. Resource manager (e.g., SLURM, PBS/Torque, LSF, etc.)
4. If none of a hostfile, the --host command line parameter, or an
RM is present, Open MPI defaults to the number of processor cores In all the above cases, if you want Open MPI to default to the number
of hardware threads instead of the number of processor cores, use the
--use-hwthread-cpus option. Alternatively, you can use the --oversubscribe option to ignore the
number of available slots when deciding the number of processes to
launch.
--------------------------------------------------------------------------

报错信息显示可以运行的CPU个数不够,因为A主机我们指定最多运行4个CPU,B主机最多运行4个CPU,所以当前系统下最多可以运行的CPU个数为8,超出这个个数则会报错。

=================================

3.     -np 参数:

如果我们运行时不使用    -np 参数, 那么运行情节如何呢:

在  myhosts 文件内容:

192.168.11.66
192.168.11.206

运行命令:

mpirun --machinefile myhosts   /home/xxxxxx/anaconda3/bin/python x.py

运行结果,A主机运行24个进程,B主机运行6个进程,也就是说不指定  -np参数  每个主机都是以全部的物理核心来运行进程。

如果在  myhosts 文件内容:

192.168.11.66       slots=4
192.168.11.206      slots=4

运行命令:

mpirun --machinefile myhosts   /home/xxxxxx/anaconda3/bin/python x.py

运行结果,A主机运行4个进程,B主机运行4个进程,也就是说不指定  -np参数  和之前一样每个主机都是以全部的可以运行的CPU个数来运行进程。(因为这里在myhosts文件中使用了slots参数已经设定了A主机最多可以使用4个CPU,B主机最多可以使用4个CPU)

============================================================

 4.  参数  -nolocal

在执行mpi命令时加入参数 -nolocal 则指定不运行当前所在主机上的CPU,具体:

假设myhosts文件内容如下:

cat myhosts

192.168.11.66       slots=4
192.168.11.206 slots=4

myhosts 文件指定A、B主机均只能最多使用4个CPU。

在主机A  192.168.11.66 上运行命令:

mpirun  -nolocal  --machinefile myhosts   /home/xxxxxx/anaconda3/bin/python x.py

报错:

--------------------------------------------------------------------------
There are not enough slots available in the system to satisfy the 8
slots that were requested by the application: /home/xxxxxx/anaconda3/bin/python Either request fewer slots for your application, or make more slots
available for use. A "slot" is the Open MPI term for an allocatable unit where we can
launch a process. The number of slots available are defined by the
environment in which Open MPI processes are run: 1. Hostfile, via "slots=N" clauses (N defaults to number of
processor cores if not provided)
2. The --host command line parameter, via a ":N" suffix on the
hostname (N defaults to 1 if not provided)
3. Resource manager (e.g., SLURM, PBS/Torque, LSF, etc.)
4. If none of a hostfile, the --host command line parameter, or an
RM is present, Open MPI defaults to the number of processor cores In all the above cases, if you want Open MPI to default to the number
of hardware threads instead of the number of processor cores, use the
--use-hwthread-cpus option. Alternatively, you can use the --oversubscribe option to ignore the
number of available slots when deciding the number of processes to
launch.
--------------------------------------------------------------------------

也就是说  -nolocal 不允许本地主机A参与计算,而 myhosts文件中又允许A主机参与计算,因此造成冲突。在没有使用 -np 参数的情况下是需要使用myhosts文件中指定的CPU数的最大值来运行的,但是-nolocal不允许A主机参与运行无法满足myhosts文件中的8个CPU的设定,因此报错。

我们在上面的运行语句中改进下,如下:

 mpirun -np 6  -nolocal  --machinefile myhosts   /home/xxxxxx/anaconda3/bin/python x.py

依旧报错误:

There are not enough slots available in the system to satisfy the 6
slots that were requested by the application:

原因是不使用本地主机A的情况下 -np 指定需要6个CPU运行,但是myhosts中指定B主机192.168.11.206最多可以运行4个CPU,因此不满足6个CPU运行的要求报错。

我们在上面的运行语句中改进下,如下:

 mpirun -np 4  -nolocal  --machinefile myhosts   /home/xxxxxx/anaconda3/bin/python x.py

成功运行。四个进程全部运行在B主机192.168.11.206 上。既满足 -np 4  也满足 -nolocal 设定,同时也满足 myhosts中的设定。

同理:

上面的运行语句中改进下,如下:

 mpirun -np 2  -nolocal  --machinefile myhosts   /home/xxxxxx/anaconda3/bin/python x.py

成功运行。2个进程全部运行在B主机192.168.11.206 上。既满足 -np 2  也满足 -nolocal 设定,同时也满足 myhosts中的设定。

===========================================================

5.   参数  --use-hwthread-cpus  与  --oversubscribe

前面我们知道 A、B主机的CPU物理核心个数:

A电脑: 24物理核心(48逻辑核心)

B电脑:6物理核心(12逻辑核心)

-np 指定该次运行一共需要的CPU个数,-nolocal 指定不使用当前主机的CPU进行运算,myhosts中指定参与计算的各主机的最多参与计算的CPU个数。

正如我们前面所说的,myhosts文件中虽然可以指定每个主机最多可以使用的CPU个数,但是这个个数是我们人为设定的,设定的一个要求就是要小于主机的物理核心个数。如果myhosts 中slots指定的CPU数量等于主机物理核心个数那么slots本身是没有意义的,因为myhosts中不使用slots设定所能使用的最多CPU个数也是该主机的物理核心个数。

那么 myhosts 中slots的个数设定真的不能大于主机的物理核心数,其实不然。之所以我们默认要求slots个数不能大于物理核心数是因为在独占主机进行计算密集型运算时当主机上运行的进程数等于物理核心数时往往会得到最高的利用率。

一个隐藏知识,根据Intel cpu的白皮书(蓝皮书)可以看到在使用超流水线多线程运算时密集计算型计算性能可以提高30%,这就是说在Intel超流水线技术支持下密集计算任务单主机下进程数等于逻辑核心个数其性能要超进程数等于物理核心数时的30%,不过这只是在短时间计算情景下,如果在长时间运行情况下当进程数等于逻辑核心数时计算密集型任务往往会导致CPU的散热撞到功率墙(散热墙)从而导致大幅度CPU降频,从而导致计算性能大幅下降,当然这说的是普通散热情况下,因此在进行计算密集型计算任务时我们都是默认设定进程数等于物理核心数。

也就是说,如果我们在 myhosts 文件中设定 slots 个数超过主机的物理核心数在不考虑计算性能的情况下是完全可行的。

给出此时的myhosts内容:

cat myhosts

192.168.11.66       slots=100
192.168.11.206 slots=100

运行语句中如下:

 mpirun -np 200  --machinefile myhosts   /home/xxxxxx/anaconda3/bin/python x.py

成功运行。共运行200个进程,其中100个进程运行在A主机192.168.11.66 上, 100个进程运行在B主机192.168.11.206 上。

由此可见使用 myhosts文件中的slots设定也是可以运行超过物理核心数的进程的。

刚才说的是在使用  --machinefile 参数 利用myhosts 文件中的设定来实现超过物理核心数的进程数量运行的,如果我们不使用  --machinefile 参数的情况下呢???

执行命令:

mpirun -np 8  --host 192.168.11.66:4 --host 192.168.11.206:4   /home/xxxxxx/anaconda3/bin/python x.py

成功在A主机192.168.11.66主机上运行4个进程,在B主机192.168.11.206上运行4个进程,共运行8个进程。

执行命令:

mpirun -np 6  --host 192.168.11.206:6   /home/xxxxxx/anaconda3/bin/python x.py

成功在B主机192.168.11.206上运行6个进程,共运行6个进程。

执行命令:

mpirun -np 200  --host 192.168.11.66:100 --host 192.168.11.206:100   /home/xxxxxx/anaconda3/bin/python x.py

成功在A主机192.168.11.66主机上运行100个进程,在B主机192.168.11.206上运行100个进程,共运行200个进程。

执行命令:

mpirun -np 200 --host 192.168.11.206:200   /home/xxxxxx/anaconda3/bin/python x.py

成功在在B主机192.168.11.206上运行200个进程,共运行200个进程。

当然上面的都是在分布式的环境下运行的(  分布式环境下是指使用 --host 参数)。

如果不使用  --host  参数,在单机环境下如何实现超过物理核心数的进程数运行呢???

如:

执行命令:

mpirun -np 48   /home/xxxxxx/anaconda3/bin/python x.py

命令的含义是在A主机192.168.11.66上运行48个进程,而A主机的物理核心数为24,因此报错。

There are not enough slots available in the system to satisfy the 48
slots that were requested by the application:

这时改用命令:(加入参数   --use-hwthread-cpus )

--use-hwthread-cpus  参数的含义是允许当前主机运行的进程最大数为逻辑核心数而不是物理核心数。

mpirun -np 48 --use-hwthread-cpus  /home/xxxxxx/anaconda3/bin/python x.py

成功在在A主机192.168.11.66上运行48个进程,A主机为当前命令执行时所在的主机,其逻辑核心数为48。

改命令为:

mpirun -np 49 --use-hwthread-cpus  /home/xxxxxx/anaconda3/bin/python x.py

运行失败,因为   --use-hwthread-cpus 参数只能设定最多运行进程数为逻辑核心数,因此超过48后报错(A主机逻辑核心数为48)。

这时改用 参数  --oversubscribe :

--oversubscribe 参数的含义就是不对进程数设限制,也就是说进程数可以随便设置。

执行命令如下:

mpirun -np 200  --oversubscribe  /home/xxxxxx/anaconda3/bin/python x.py

成功在A主机192.168.11.66上运行了200个进程。

=================================================================

附加内容:

在执行mpi程序时rank0进程是在哪个主机上呢???
(rank0进程就是mpi程序运行后rank排名号为0号的进程)

在主机A 192.168.11.66 上:

myhosts文件内容:

192.168.11.66       slots=4
192.168.11.206 slots=4

执行命令:

mpirun -np 8   --machinefile myhosts   /home/xxxxxx/anaconda3/bin/python x.py

运行结果显示,rank0进程运行在A主机 192.168.11.66上。

同理:

在主机B 192.168.11.206 上:

myhosts文件内容:

192.168.11.66       slots=4
192.168.11.206 slots=4

执行命令:

mpirun -np 8   --machinefile myhosts   /home/xxxxxx/anaconda3/bin/python x.py

运行结果显示,rank0进程运行在B主机 192.168.11.206上。

由上面的运行情况我们可以知道 rank0 进程一般都是运行在启动mpi程序并使用CPU运行进程的主机上(需要排除使用参数 -nolocal 的情况,该种情况启动mpi程序的主机是不使用CPU参与计算的,因此rank0进程此时是不在启动mpi程序的主机上的)

==================================================

使用MPI时执行代码时运行命令中参见的几种参数设置的更多相关文章

  1. JS流程控制语句 做判断(if语句)if语句是基于条件成立才执行相应代码时使用的语句。语法:if(条件) { 条件成立时执行代码}

    做判断(if语句) if语句是基于条件成立才执行相应代码时使用的语句. 语法: if(条件) { 条件成立时执行代码} 注意:if小写,大写字母(IF)会出错! 假设你应聘web前端技术开发岗位,如果 ...

  2. 判断语句(if...else)if...else语句是在指定的条件成立时执行代码,在条件不成立时执行else后的代码

    判断语句(if...else) if...else语句是在指定的条件成立时执行代码,在条件不成立时执行else后的代码. 语法: if(条件) { 条件成立时执行的代码 } else { 条件不成立时 ...

  3. 打开CAD时出现“acvmtools.arx ARX命令中发生异常

    打开CAD时出现“acvmtools.arx ARX命令中发生异常     解决办法1: 试试进入CAD安装的目录,删掉它acvmtools.arx,重新打开cad.(注:acvmtools.arx一 ...

  4. 如何确定C#代码是在编译时执行还是在运行时执行

    突然想起那个"switch..case..."的case标签都可以判断哪些类型... 就先搞了一个错误的demo... class Program { static void Ma ...

  5. SpringMVC中如何在网站启动、结束时执行代码(详细,确保可用)

        在一个网站启动.结束时,我们经常有些操作是需要执行的. 熟悉Asp.net的朋友,使用Global.asax很容易就搞定,在其中有Application_Start和Application_E ...

  6. 常用shell命令中你所不熟悉的参数

    1.   ls: 类似于dos下的dir命令 ls最常用的参数有三个: -a -l -F. ls –a Linux上的文件以.开头的文件被系统视为隐藏文件,仅用ls命令是看不到他们的,而用ls -a除 ...

  7. 使用java程序对oracle添加触发器时,报错:索引中丢失 IN 或 OUT 参数:: 1

    解决方法: 执行sql语句时,使用java.sql.Statement代替java.sql.PreparedStatement. java.sql.PreparedStatement ps = con ...

  8. Struts2学习(二)运行Action中方法的三种方式

    1.运行execute()方法 一般的能够直接在action中书写execute,调用action时会自己主动运行此方法 2.配置method方法 在struts.xml中配置action时.写met ...

  9. java代码收藏:获取HttpServletRequest中某一前缀的参数

    public static Map getParametersStartingWith(ServletRequest request, String prefix) { Enumeration par ...

  10. JS流程控制语句 二选一 (if...else语句) 语法: if(条件) { 条件成立时执行的代码} else {条件不成立时执行的代码}

    二选一 (if...else语句) if...else语句是在指定的条件成立时执行代码,在条件不成立时执行else后的代码. 语法: if(条件) { 条件成立时执行的代码} else {条件不成立时 ...

随机推荐

  1. redis实战技巧

    1.分析key大小 [root@db-51 ~]#redis-cli -h 10.0.0.51 -p 6380 --bigkeys # Scanning the entire keyspace to ...

  2. sql去重常用的基本方法

    1.存在两条完全相同的纪录 select distinct * from table(表名) where (条件)   2.存在部分字段相同的纪录(有主键id即唯一键) 如果是这种情况的话用disti ...

  3. JavaScript将类数组转换为数组的三种方法

    // 类数组转换为数组 const list = [] // 假定为类数组 const arr1 = Array.from(list); const arr2 = Array.prototype.sp ...

  4. 在线Token、随机密码生成工具

    在线生成自定义长度,包含大写或小写字母.数字或符号的随机字符串.无论你需要生成API访问令牌.账户激活令牌,还是随机密码字符串,它都能帮你快速完成. 在线Token.随机密码生成工具

  5. tempcode排序

    package com.hsy;import com.alibaba.fastjson.JSON;import org.springframework.util.CollectionUtils;imp ...

  6. 使用Kubesec检查YAML文件安全

    目录 一.系统环境 二.前言 三.Kubesec简介 四.使用Kubesec检查YAML文件安全 五.总结 一.系统环境 本文主要基于Kubernetes1.22.2和Linux操作系统Ubuntu ...

  7. 汇总:"undefined reference to" 问题解决方法

    背景 在Linux下编程容易出现的现象,就是在链接多文件的时候总是报错,类似下面这样的错误: (.text+0x13): undefined reference to `func' 关于undefin ...

  8. 【冷启动#1】实用的MySQL基础

    简单安装一下MySQL Windows下(5.7.x) 本体安装 1.首先先下载安装包,名字如下: mysql-5.7.19-winx64.zip 2.配置环境变量,将解压之后的bin目录添加一下 3 ...

  9. Redis的几种应用实战

    1.分布式锁: 实现:用set key value ex time nx指令实现,这个指令以及其参数是原子性的操作.释放锁用del key,释放之前先比较一下value是否与当前的value一样,原因 ...

  10. 如何查看docker容器的volume挂载情况

    准备在docker容器当中编写个日常维护的脚本,但容器里连yum和vim命令都没有,所以就想到通过容器映射在本机的volume里编写脚本这样在容器中不就可以直接用了吗,那么在这之前你首先得知道dock ...