大连人工智能计算平台——华为昇腾AI平台——高性能计算HPC的单任务task的多CPU运行模式
超算是离我们平时生活比较远的一个事情,即使是对于一个计算机专业方向的学生来说,正好实验室得到了华为的超算平台的使用账号,于是就摸索了一下,不得不承认这个东西确实不是普通人能搞的明白的。
基本概念:
一个工作Job可以开多个副本,每个副本都是mpirun -N 所开出的,每个副本又被叫做任务task,而每个任务task又可以申请多个CPU核心和多个GPU计算资源。
运算代码:
import mpi4py.MPI as MPI import sys import socket import numpy as np def func1(queue, num): import time # time.sleep(num) # time.sleep(1) x = np.random.rand(100) for _ in range(1000000): x += np.random.rand(100) num += np.sum(x) queue.put(num) def run_queue(): from multiprocessing import Process, Queue ps = 120 queue = Queue(maxsize=200) # the following attribute can call in anywhere process = [Process(target=func1, args=(queue, num)) for num in range(ps)] [p.start() for p in process] [p.join() for p in process] return [queue.get() for p in process] comm = MPI.COMM_WORLD comm_rank = comm.Get_rank() comm_size = comm.Get_size() node_name = MPI.Get_processor_name() # node_name = socket.gethostname() # point to point communication data_send = [comm_rank]*1 comm.send(data_send,dest=(comm_rank+1)%comm_size) res = run_queue() ### data_recv =comm.recv(source=(comm_rank-1)%comm_size) # print("my rank is %d, and Ireceived:" % comm_rank, data_recv, file=sys.stdout, flush=True) # print(data_recv) with open("/home/share/xxxxxxxxxx/home/xxxxxxxx/xxxxxxx/results/{}.txt".format(comm_rank, ), "w") as f: f.write("my rank is %d/%d, and node_name: %s Ireceived:" % (comm_rank, comm_size, node_name) + str(data_recv) + str(res) + "\n" )
超算的启动命令:( -R 为task做资源申请 )
一个job开8个task,每个task申请120个CPU:
/opt/batch/cli/bin/dsub -n task_test -A xxxxxxxxxxxx --priority 9999 --job_retry 10 --job_type hmpi -R "cpu=120;mem=128" -N 8 -eo error.txt -oo output.txt /home/share/xxxxxxxxxx/home/xxxxxxx/xxxxxxx/run_python.sh
运行时间:6分43秒
一个job开8个task,每个task申请1个CPU:
/opt/batch/cli/bin/dsub -n task_test -A xxxxxxxxxxxx --priority 9999 --job_retry 10 --job_type hmpi -R "cpu=1;mem=128" -N 8 -eo error.txt -oo output.txt /home/share/xxxxxxxxxx/home/xxxxxxx/xxxxxxx/run_python.sh
运行时间:12分33秒
上面的这两个运算时间有些说不通,同样的计算task,使用120个CPU计算,单个任务用时6分43秒;然而,使用单个CPU计算单个任务,单个任务用时12分33秒,这个时间差距怎么看也不像是120个CPU和1个CPU运算时间的对比,为此我们想到一个可能,你就是这个超算平台的多CPU调度时间比较长,比较耗时,为此我们给出下面的计算:
通过这个计算可以得到一个比较合理的推断,那就是每个func1的运算时间是比较短的,而超算平台每次运算的时间都需要花费大量的调度时间,如上面的计算,每个CPU计算func1的时间如果是2.91秒,而第一次计算6分43秒的花费中其实有6分40秒左右时间是系统的调度时间,每个CPU的运算时间其实只在3秒左右,而第二次计算中使用1个CPU计算之前第一次计算中120个CPU的计算任务其运算时长自然会增加到12分33秒左右。
为此我们单独把上面的func1计算任务拿到个人笔记本上计算,使用i7-9700k cpu计算,代码:
import numpy as np import time a_time = time.time() x = np.random.rand(100) for _ in range(1000000): # print(x) x += np.random.rand(100) print(np.sum(x)) b_time = time.time() print(b_time-a_time)
用时:
可以看到上面的假设还是得到印证的,这个func1的计算任务,其用时大致在3秒左右。
为此我们在增加一次测试,将代码中的ps=120改为ps=1,启动命令同样为:
一个job开8个task,每个task申请120个CPU:
/opt/batch/cli/bin/dsub -n task_test -A xxxxxxxxxxxx --priority 9999 --job_retry 10 --job_type hmpi -R "cpu=120;mem=128" -N 8 -eo error.txt -oo output.txt /home/share/xxxxxxxxxx/home/xxxxxxx/xxxxxxx/run_python.sh
运算时间:11秒
可以看到,虽然每个task的申请CPU为120个,但是每个task的计算任务只使用1个CPU,该种情况下总用时11秒。 该种情况下我们猜测虽然每个task申请120个CPU,但是实际使用了一个CPU,因此超算系统调度过程中也只为每个task进行了一个CPU的调度,为此再次运算:
代码中:ps=1
一个job开8个task,每个task申请1个CPU:
/opt/batch/cli/bin/dsub -n task_test -A xxxxxxxxxxxx --priority 9999 --job_retry 10 --job_type hmpi -R "cpu=1;mem=128" -N 8 -eo error.txt -oo output.txt /home/share/xxxxxxxxxx/home/xxxxxxx/xxxxxxx/run_python.sh
运算时间:17秒
这个结果同样说明了如果task的CPU调度数越多,那么系统的调配时间越多,当然上面的计算中是认为第二次计算中的12分33秒用时中大量时间为调度时间,如果第二次中的运算用时调度时间不占主要,那么我们得到的结论并不与这里的结论现否定,给出该种情况下的计算:
而这个用时也是在合理范围:
===================================================
补充:
代码:ps=120 range(1000000)改为range(100000),启动命令:
/opt/batch/cli/bin/dsub -n task_test -A xxxxxxxxxxxx --priority 9999 --job_retry 10 --job_type hmpi -R "cpu=1;mem=128" -N 8 -eo error.txt -oo output.txt /home/share/xxxxxxxxxx/home/xxxxxxx/xxxxxxx/run_python.sh
这样我们更加确认第二次运算时超算系统的调配时间并不是占主要。对于超算系统来说,我们现在得到的假设是调度比较耗时的部分为单task的多CPU调度,就像上面的单个task的120个CPU的调配,按照这个假设第一次计算中的6分43秒中大致有6分30秒是在超算系统的调配中损耗的,而不是实际的真实计算任务所损耗的。
----------------------------------------------------------------
再次补充:
代码:ps=120 range(1000000)改为range(100000),启动命令:
/opt/batch/cli/bin/dsub -n task_test -A xxxxxxxxxxxx --priority 9999 --job_retry 10 --job_type hmpi -R "cpu=120;mem=128" -N 8 -eo error.txt -oo output.txt /home/share/xxxxxxxxxx/home/xxxxxxx/xxxxxxx/run_python.sh
重复第二次运行情况:
代码:ps=120 range(1000000),启动命令:
/opt/batch/cli/bin/dsub -n task_test -A xxxxxxxxxxxx --priority 9999 --job_retry 10 --job_type hmpi -R "cpu=120;mem=128" -N 8 -eo error.txt -oo output.txt /home/share/xxxxxxxxxx/home/xxxxxxx/xxxxxxx/run_python.sh
代码:ps=120 range(1000000),启动命令:
/opt/batch/cli/bin/dsub -n task_test -A xxxxxxxxxxxx --priority 9999 --job_retry 10 --job_type hmpi -R "cpu=120;mem=128" -N 1 -eo error.txt -oo output.txt /home/share/xxxxxxxxxx/home/xxxxxxx/xxxxxxx/run_python.sh
从上面的运算表现我们可以大胆猜测,如果单task的CPU使用数较多(如这里的120个CPU),并且单task在每个CPU上的运算时间都不是极小的(这里估计大于3秒),那么系统调度的时长会急剧增加,这里估计超算系统该种情况下的调度时长为6分钟左右。
================================================================
最终补充:
代码:ps=120 range(2000000),启动命令:
/opt/batch/cli/bin/dsub -n task_test -A xxxxxxxxxxxx --priority 9999 --job_retry 10 --job_type hmpi -R "cpu=120;mem=128" -N 1 -eo error.txt -oo output.txt /home/share/xxxxxxxxxx/home/xxxxxxx/xxxxxxx/run_python.sh
import mpi4py.MPI as MPI import sys import socket import numpy as np def func1(queue, num): import time # time.sleep(num) time.sleep(180) """ x = np.random.rand(100) for _ in range(2000000): x += np.random.rand(100) num += np.sum(x) """ queue.put(num) def run_queue(): from multiprocessing import Process, Queue ps = 120 queue = Queue(maxsize=200) # the following attribute can call in anywhere process = [Process(target=func1, args=(queue, num)) for num in range(ps)] [p.start() for p in process] [p.join() for p in process] return [queue.get() for p in process] comm = MPI.COMM_WORLD comm_rank = comm.Get_rank() comm_size = comm.Get_size() node_name = MPI.Get_processor_name() # node_name = socket.gethostname() # point to point communication data_send = [comm_rank]*1 comm.send(data_send,dest=(comm_rank+1)%comm_size) res = run_queue() ### data_recv =comm.recv(source=(comm_rank-1)%comm_size) # print("my rank is %d, and Ireceived:" % comm_rank, data_recv, file=sys.stdout, flush=True) # print(data_recv)
/opt/batch/cli/bin/dsub -n task_test -A xxxxxxxxxxxx --priority 9999 --job_retry 10 --job_type hmpi -R "cpu=120;mem=128" -N 8 -eo error.txt -oo output.txt /home/share/xxxxxxxxxx/home/xxxxxxx/xxxxxxx/run_python.sh
运算时间:3分17秒
通过最终补充的最后两个实验,我们得到的结论有之前的都不是很相符,你就是超算系统的运算性能是具备一定随机性的,系统的调度时间也是较小的,上面的运算实验之所以有较大差距或许只是系统的随机性造成的。
============================================================
posted on 2023-07-04 13:13 Angry_Panda 阅读(87) 评论(0) 编辑 收藏 举报
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
2021-07-04 在本地主机使用anaconda3 安装MindSpore环境——教程(GPU版本)
2021-07-04 深度学习框架 MindSpore —— 华为出品的AI计算框架, docker 安装
2021-07-04 docker 容器(container)使用ssh服务登录一段时间无操作后自动断开问题解决
2021-07-04 Docker退出容器不关闭容器的方法