-----------------------------------------------------------------
用pc构建DIY计算集群
目录
/构建计算集群
|-- /0前言
|-- /1理论
----|-- /1.1并行计算
----|-- /1.2历史
----|-- /1.3MPI消息传递接口*
----|-- /1.4并行算法*
|-- /2结构
----|-- /2.1节点*
----|-- /2.2网络拓扑
----|-- /2.3存储
----|-- /2.4分类
|-- /3操作系统和软件环境
----|-- /3.1操作系统*
----|-- /3.2进程,进程通信
|-- /4两台PC的集群
----|-- /4.1硬件
----|-- /4.2安装操作系统
----|-- /4.3配置环境,安装软件
----|-- /4.4网络配置
----|-- /4.5单鸡多核
----|-- /4.6できた!多鸡
----|-- /4.7NFS设置
ps云计算和高性能计算和虚拟化
--------------------------------------------------------------------
0前言
*参考书《并行计算导论》张林波,迟学斌,莫则尧,李若
简要介绍如何构建一台微型“超算”。当然,真的超算要复杂很多,因为涉及到多用户,多任务,队列管理和存储管理等等一系列问题。在没有排到大型机的情况下,还是可以应付一些简单的小规模的并列运算。
左边是pc的cluster,右边是Apple的xserver的cluster。*from “Mezono group”。
超算没有那么神秘,大部分程序还是fortran和c的,运行方式也是手动编译,然后提交队列。可以看作是电脑里的卡特彼勒重卡,算是电子时代的暴力美学吧。
1理论
1.1并行计算
并行计算(parallel computing)是指在并行机上,把一个应用分解成多个子任务,分配给不同的处理器,各个处理器之间协同,并行执行子任务,目的是加快计算速度。
由此需要1,硬件支持,需要并行机,多核,单机的话,单个任务在一个核心上执行和多核上执行速度也不一样,多机就需要网络连接。2,计算的问题可以并行,如果计算的问题是流水线,互相关联度很高,完全没法并行,那么就没有必要用并行计算活着超算。3,需要进行相应的编程优化。
那么什么样的问题需要超算呢,大规模的科学和工程计算,比如天气预报,需要24小时完成48小时的数值模拟,至少需要635万个网格点,内存大雨1TB,计算性能要求高达25万亿次/s。
1.2历史
(太长,暂略)
1.3MPI消息传递接口
MPI(message Passing interface)是全世界联合建立的消息传递编程标准,目的是用消息传递提供一个高效可扩展,统一的编程环境,是目前最为通用的并行编程方式,也是主要应用的。
MPI有多种"实现",包括mpich1/mpich2、openmpi、lam-mpi等,每种mpi的实现需要配合相应的编译器,才能发挥作用。
c语言mpi hello world
#include <mpi.h>
#include <stdio.h>
int
main(int argc, char *argv[])
{
int rank, size;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
printf("Hello, World. I am %d of %d\n", rank, size);
MPI_Finalize();
return 0;
}
1.4并行算法
*参考书《并行计算-结构/算法/编程》陈国良
任何并行算法的设计都是基于某一特定的并行计算模型,而并行计算模型是从各种具体的并行机中抽象出来的,它能在一定程度上反映出具体并行机的属性,又可使算法研究不再局限于某一种具体的并行机。
并行算法可从不同的角度分类成数值计算的和非数值计算的并行算法;同步的、异步的和分布式的并行算法;共享存储的和分布存储的并行算法;确定的和随机的并行算法等等。
举个栗子,单个进程的快速排序
输入 : 无序序列(Aq ,⋯ ,Ar)
输出 : 有序序列(Aq ,⋯ ,Ar)
Procedure QUICKSORT(A,q,r)
Begin
if q<r then
(1)x= Aq
(2)s=q
(3)for i=q+1 to r do
if Ai ≤ x then
(i)s=s+1
(i)swap(As ,Ai)
endif
(4)swap(Aq ,As)
(5)QUICKSORT(A,q,s)
(6)QUICKSORT(A,s+1,r)
endif
End
然后进行并行化之后是这个样子,基于二叉树的并行选主元的PRAM_CRCW 模型上的快排序算法。执行快排序可以看成是构造一棵二叉树,其中主元是根,小于等于主元的元素处于左子树,大于主元的元素处于右子树。算法首 先从选第一个主元开始,它划分原序列为两个子序列;然后相继子序列中主元的选 取则可并行执行。当这样的二叉树造好后,采用中序遍历的方法就可得到一个有序序列。
输入: 序列 ( A1 ,⋯ , An ) 和n个处理器
输出: 供快排序用的一棵二叉树
Begin
(1)for each procesor i do
(1.1)root=i
(1.2) fi =root
(1.3) LCi = RCi = n + 1
endfor
(2)repeat for each procesor i≠root do
if (Ai < Afi) ∨ (Ai = Afi ∧ i < fi) then
(2.1)LCfi =i
(2.2)if i = LCfi then exit else fi = LCfi endif
else
(2.3)RCfi =i
(2.4)if i=RCfi then exit else fi = RCfi endif
endif
end repeat
End
2结构
节点(node)。每个节点由多个处理器构成,可以直接输入输出(I/O)。
互联网络(interconnect network)。连接节点。
存储(memory)。由多个存储模块构成
2.1节点
需要cpu,有缓存,有内存,还需要网络连接,专用的工业超算还需要专门设计节点,比如下图就是cray的节点
*from Performance Computer, XC Series Supercomputers
也可以用树莓派
Raspberry Pi 3 Model B - Raspberry Pi
2.2网络拓扑
有了节点,就需要对节点进行连接,评价一个网络的准则应该是,对于一定数量的节点,点对点的带宽越高,折半宽度越大,或者网络直径越小,点对点延迟越小,质量就越好。拓扑结构可以分为静态,动态,和宽带连接三类。
a静态连接,就是对于固定数量的节点,单独设计的一套固定的物理连接,至于用什么线连接,都是对用户不可见的,具体取决于厂商或者设计者。连接的拓扑包括阵列(array),环(ring),网格(mesh),网格环(torus),树(tree),超立方体(hypercube),蝶网(butterfly),Benes网等等。详情可以参考其他文献,《面向拓扑结构的并行算法设计与分析》李晓梅等
上图就是
阵列(array) 环(ring)
网格(mesh) 网格环(torus)
树(tree) X-树(x-tree)
现在比较有名的超算一般采用超立方体(hypercube)
三维立方体,长这样
四维立方体,长这样
b动态连接
静态虽好,但是扩展比较困难,如果采用比较简单一维阵列,一个节点挂了,整台都挂了,而且不适合异构的混合计算。那么动态的连接方式就出现了。
多层总线连接,或者交叉开关
c宽带连接,这是我们能够用得起的,因为以上的连接方式有的需要专用设备,有的需要根据节点进行设计,而且随着以太网和交换机的发展,网络连接的速度可以满足通信需求,大部分的集群都采用宽带互联网。
2.3存储
随着cpu的发展,目前的瓶颈在于存储,所谓的内存墙(memory wall)解决方法就是增加缓存,增加缓存层级或者扩大缓存容量,在其中找到一个价格也能接受,速度也够用的平衡。
而对于不同的需求和设计,也会有不同的存储管理机制, 如果是MPP,数据超大,就需要单独的存储管理,对于小型集群,存储的设计可以单独设计NFS也可以直接利用节点存储。
2.4分类
集群(cluster),利用商用节点,商用cpu或者gpu,采用商用交换机连接,操作系统采用linux,GNU编译器,和PBS。
星群(constellation),系统的每个节点是一个并行机子系统,每个子系统里包含好多个处理器,采用商用交换机连接,操作系统和编译系统和PBS可以采用专用的。
大规模并行系统(MPP,Massively Parallel Processing),每个节点包含10个左右的处理器,共享存储,处理器可以用专用的,或者商用的,采用高性能网络连接,节点分布存储。 操作系统和编译系统和PBS需要专用的。
具体的超算信息可以查看top500 November 2016 | TOP500 Supercomputer Sites
如果按照指令和数据流分类,就是单指令多数据流(SIMD),已经淘汰,多指令单数据流(MISD),至今没出现过,多指令多数据流(MIMD),现在大家用的。
3操作系统和软件环境
3.1操作系统
都是UNIX和类UNIX,比如linux,操作都差不多,学好linux还是很重要滴。
需要的语言,由重要到一般重要排序,Fortran 77/90/95、c/c++、shell(如果算语言的话)、python(一般是2.x)、perl、sed、等等等等。因为在科学计算领域,软件更新比较慢,所以祖传老代码比较多,所以,使用标准一般比较老,且不保证兼容,所以想一次编译通过,不是很容易(头疼)。编译器一般会有选择,开源的一般来说效率没有收费的高,所以,想高效,还是要花钱滴。
3.2进程,进程通信
进程(process)是基本的单位,包括,程序代码、控制状态、数据、执行状态,进程拥有独立的运行环境,高内聚低耦合嘛。在多核运算中,多个进程跑在一个物理核心上是不能缩短总运行时间的(walltime),反而会小幅增加,所以,说核心的时候,尽量以物理核心为准。
进程间的通信 有三种形式,通信、同步、和聚集,主要形式就是通信,通过消息(message)传递,进行通信,实现的形式可以是通过共享存储或者网络通信,但是这对用户都是不可见的,我们只需要调用MPI。
4两台PC的“集群”
4.1硬件
两台节点:intel i7 4核,6g内存,1T硬盘,独立显卡(gpu太弱,不用它来计算,只用于连接显示器)intel Gigabit以太网卡。
网络连接:gigabit以太网switch hub(L2交换机),网线,需要连接互联网
4.2安装操作系统
安装ubuntu 16.04,lts,具体的安装步骤就很简单啦,略。
4.3配置环境,安装软件
sudo apt-get -y update
sudo apt-get -y upgrade
首先,更新一下apt。
sudo apt-get -y install expect rlwrap emacs24 openssh-server openssh-client xinetd nfs-common libgomp1 samba samba-client openmpi-bin libopenmpi-dev openmpi-common update-manager-core
然后安装这些软件。。。
这些都是啥呢,我慢慢讲-来自维基百科,
expect :含有利用正则表达式进行模式匹配以及通用的编程功能,允许简单的脚本智能地管理如下工具:telnet,ftp和ssh(这些工具都缺少编程的功能),宏以及其它程序。Expect脚本的出现使得这些老的软件工具有了新的功能和更多的灵活性。
rlwrap:rlwrap 是一个读行包装,允许在其他命令中使用键盘输入进行编辑。
emacs24 :编辑器
openssh-server openssh-client: openssh 的服务和客户端
xinetd: 守护进程
nfs-common: 网络文件系统
libgomp1 :openmp 是一套支持跨平台共享内存方式的多线程并发的编程API
samba samba-client: 在Windows與UNIX系列OS之間搭起一座橋樑,讓兩者的資源可互通有無
openmpi-bin libopenmpi-dev openmpi-common: openmpi,开源的mpi
update-manager-core: 更新用
sudo apt-get -y dist-upgrade
然后更新一下软件的依赖,防止出现依赖的遗漏。
4.4网络配置
a)网络连接,使用交换机集线器连接,连接方式多种多样,由于我们的组装的规模很小,所以,低于交换机的接口数的时候就把交换机作为行星网络的中心,如果需要多个交换机,就采用层状交换机结构。出于简单考虑,IP没有设成静态,直接采用路由器的hdcp功能,动态分配ip,如果要长期使用,请设置成静态ip。那么自动分配的ip分别是XXX.65.121.82和 XXX.65.121.102,分别对应的名称是server081和server156,(我在实验室随便拉出来的两台机器)。更改静态ip需要更改 /etc/network/interface 文件。
b)查询ip地址,可以直接去gui的界面去看,也可以输入<ifconfig>命令。
c)更改/etc/hosts文件,把ip和名字对应上,这样操作起来比较方便,不用处处都输入ip。如果查看自己的hostname,可以查看/etc/hostname文件。
d)然后重启network服务
sudo /etc/init.d/networking restart
测试两台机器是否能够ping通,如果,可以,说明网络没问题,如果出现问题,检查网络连接和网络设置。
e)用ssh生成密钥
ssh-keygen
f)同步密钥,可以进行免密ssh登陆。
cd ~/.ssh
cp id_rsa.pub authorized_keys
rsync -avz ~/.ssh XXX.65.121.102:~/.
再测试两台机器是否可以免密ssh登陆,如果不行,检查问题。
这时候有人会问,我现在有两台机器,可以拷贝一下密钥,要是我有n台机器,岂不是相互都要拷贝n-1个密钥?解决的方法很简单就是大家都用一个密钥,这样进行访问的时候就不用互相交叉进行,而是由一个中心进行相互通信。
4.5单鸡多核
进入terminal,输入
emacs -nw test.c
还记得我们刚才举的c语言的mpi的helloworld小栗子么,把它输入进去
然后ctrl+x,ctrl+s ,保存
然后ctrl+x,ctrl+c ,退出emacs
mpicc test.c
编译。。。
%mpirun -np 2 a.out
Hello, World. I am 0 of 2
Hello, World. I am 1 of 2
运行,-np就是使用几个节点进行计算,上面这是两个的结果
%mpirun -np 4 a.out
Hello, World. I am 0 of 4
Hello, World. I am 1 of 4
Hello, World. I am 2 of 4
Hello, World. I am 3 of 4
%mpirun -np 8 a.out
Hello, World. I am 0 of 8
Hello, World. I am 1 of 8
Hello, World. I am 3 of 8
Hello, World. I am 4 of 8
Hello, World. I am 5 of 8
Hello, World. I am 6 of 8
Hello, World. I am 7 of 8
Hello, World. I am 2 of 8
啊,再多的我也可以
4.6できた!多鸡
新建一个mpitest.c 文件
#include <mpi.h>
#include <stdio.h> int main(int argc, char** argv) { // Initialize the MPI environment MPI_Init(NULL, NULL); // Get the number of processes int world_size; MPI_Comm_size(MPI_COMM_WORLD, &world_size); // Get the rank of the process int world_rank; MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); // Get the name of the processor char processor_name[MPI_MAX_PROCESSOR_NAME]; int name_len; MPI_Get_processor_name(processor_name, &name_len); // Print off a hello world message printf("Hello world from processor %s, rank %d" " out of %d processors\n", processor_name, world_rank, world_size); // Finalize the MPI environment. MPI_Finalize(); }
拷贝编译完成的a.out,到另外一台机器,保证两台机器的a.out出现在同一个目录位置。
scp ~/a.out XXX.65.121.102:~/a.out
然后编辑machinefile
server018 cpu=4
server156 cpu=4
然后在这个目录下运行a.out(确保a.out也在这个文件夹下)
%mpirun --machinefile machinefile -np 8 a.out
Hello world from processor server018, rank 3 out of 8 processors
Hello world from processor server018, rank 0 out of 8 processors
Hello world from processor server018, rank 1 out of 8 processors
Hello world from processor server018, rank 2 out of 8 processors
Hello world from processor server156, rank 6 out of 8 processors
Hello world from processor server156, rank 5 out of 8 processors
Hello world from processor server156, rank 4 out of 8 processors
Hello world from processor server156, rank 7 out of 8 processors
这样就是十分初级的集群的雏形,可以进行多机并列计算。
4.7NFS设置
先安装相关软件
yum install nfs-utils nfs-utils-lib
设置nfs相关服务在操作系统启动时启动
systemctl enable rpcbind
systemctl enable nfs-server
systemctl enable nfs-lock
systemctl enable nfs-idmap
启动nfs服务
systemctl start rpcbind
systemctl start nfs-server
systemctl start nfs-lock
systemctl start nfs-idmap
服务器端设置NFS卷输出,即编辑 /etc/exports 添加:
sudo emacs /etc/exports
/nfs XXX.65.121.0/24(rw)
- /nfs – 共享目录
- <ip>/24 – 允许访问NFS的客户端IP地址段
- rw – 允许对共享目录进行读写
当然还有其他设置选项,比如insecure sync ...
sudo exportfs
这个是显示一下是否挂在成功
service nfs status -l
查看NFS状态
service nfs restart
重启NFS,这样,服务器端就设定结束了。
Linux挂载NFS的客户端非常简单的命令,先创建挂载目录,然后用 -t nfs 参数挂载就可以了
mount -t nfs xxx.168.0.100:/nfs /nfs
可以先查看
showmount -e 192.168.0.100
如果要设置客户端启动时候就挂载NFS,可以配置 /etc/fstab 添加以下内容
sudo emacs /etc/fstab
192.168.0.100:/nfs /nfs defaults 0 0
然后在客户端简单使用以下命令就可以挂载
mount /nfs
欢迎批评指正。
(待续)
--------------------------------------------------------------------
ps云计算和高性能计算和虚拟化
超级计算机和云计算都是时下比较火的两个概念,前者一般主要面向科学计算、工程模拟、动漫渲染等领域,大多属于计算密集型的应用,后者则主要是在Web2.0、社交网络、企业IT建设和信息化等领域,以数据密集型、I/O密集型应用为主。虽然侧重点有所不同,但这两者之间是很有渊源的,比如两者都使用了分布式计算、网格计算、集群、高密度计算等技术,也有一些领域在使用云计算从事HPC类的应用,如北京市计算中心就在打造“北京工业云”,为中小企业提供产品设计模拟服务,浪潮和NVIDIA也在分别推各自的“渲染云”方案。不过,HPC与云计算也存在很多不同,比如HPC几乎不用虚拟化技术,因为一个应用就可能把多个机器的CPU都跑满了,虚拟机没什么用武之地,而在企业私有云中,虚拟化却是一个最基础的技术。