Skip to content

分布式高性能深度学习1月11日

lirui edited this page Jan 11, 2021 · 8 revisions

OpenMP环境变量

OMP_NUM_THREADS: 指定执行并行区域时使用的默认线程数量

OMP_PROC_BIND: 决定了是否允许线程迁移到其他的处理器上执行,设置为True时,运行时不会在处理器间迁移线程

OMP_THREAD_LIMIT: 指定了系统能够创建的OpenMP线程的最大值

OMP_NESTED:决定了是否支持嵌套线程,True时支持

OpenMP parallel子句

Parallel用来构造一个并行区域,表示这段代码将被多个线程并行执行。需要多线程执行的代码放到parallel里面,parallel结束时有默认的同步

OpenMP-IF子句

if提供了由运行时决定是否并行的机制,如果if条件为真,并行区域会被多个线程执行,如果为假,则由一个线程执行。

OpenMP-atomic子句

OpenMP并不算太底层

1、没有达到GPU计算的数据量,但是又比单线程需要的性能要更高,

2、机器无GPU,但是希望自己的C++代码可以更快运行在设备上,也会考虑用OpenMP

OpenMP-Sections/Section子句

sections/section构造用于将sections里面的代码划分成几个不同的段,每段由一个线程执行,各线程工作量的总和等于原来的工作量

OpenMP-for子句

for子句将for循环分发到多个线程中执行,必须在parallel区域中

注意:无强制编译器依赖关系检查,需要开发人员自行保证;循环语句块单出口与单入口,不能使用break、goto、return从循环中退出

运行退出,exit

例如48核,一般2-3倍线程量就将它塞满了,读写有些依赖关系,48个线程难以跑满,所以一般2-3倍

OpenMP-single子句

构造single指定区域只由一个线程执行,具体执行的线程由运行时决定。使用single对某些代码做特殊处理。存在隐式同步。

OpenMP-master子句

构造master相关并行区域,由主线程(0号线程)执行,master结束处没有隐式栅栏

OpenMP-critical子句

保证在多线程执行程序中出现竞争时能够得到正确结果,相当于加锁

OpenMP-Schedule子句

Schedule子句指定采取的负载均衡策略及每次分发的数据大小。使用方式:schedule(type, [size])

Type代表负载均衡策略支持的类型包括:static、dynamic、guided、runtime

一个线程和另外一个线程计算量显著不同,比如100次循环,4个线程,第一个线程执行前25个,但是若后面的计算计算量是前面的好几倍,后面线程计算量远远大于前面的,前面的线程执行完成后就歇息了,并发度还是不好,所以提出了调度策略

static调度:静态负载均衡策略,编译系统默认使用该方式,线程分配的迭代为[0,N/K],N为循环迭代次数,K位线程数,如果指定size,则分配模式为:第一个线程:[0,size-1][sizeK,sizeK+size-1]...,适合计算量不会因为id的不同而有差异

dynamic调度:动态负载均衡策略,动态地将迭代分发到各个线程,线程计算完时,取得下一次任务。

guided调度:动态负载均衡策略,启发式自调度方法,指数级下降到指定的size大小,如果没有指定size则最后会降到1.特点:开始时分配较大的循环数,之后分配的循环次数逐渐减小

runtime调度:运行时负载均衡策略,运行时根据环境变量OMP_SCHEDULE来决定均衡策略

OpenMP受限核数,

有GPU的时候,用CUDA更好,没有GPU,或者有些任务计算量还没有达到CUDA需要的级别的时候,采用OpenMP

MPI并行技术

针对多机形式,针对CPU场景下,进行集合运算,点对点通信

MPI技术简介:MPI是一个跨语言的通讯协议,支持点对点和广播,MPI是一个信息传递应用程序接口,包括协议和语义说明,他们指明其如何在各种实现中发挥其特性。MPI的目的是高性能、大规模、和可移植性。与OpenMP并行程序不同,MPI是一种基于信息传递的并行编程技术。MPI标准定义了一组具有可移植性的编程接口

通用接口,不同厂商实现不同

数据发送缓冲区-> 消息装配 -> 消息传递 -> 消息拆卸 -> 数据接收缓冲区

MPI消息传递规程三个阶段:

1、消息装配将发送数据从发送缓冲区中取出加上消息信封等形成一个完整的消息;

2、消息传递将装配好的消息从发送端传递到接收端

3、消息拆卸从接收到的消息中取出数据送入接收缓冲区

MPI基础概念——通信器

通讯器定义了一组能够互相发消息的进程,在这组进程中,每个进程会被分配一个序号,称作秩(rank),进程间显性地通过指定秩来进行通信。

通信的基础建立在不同进程间发送和接收操作。一个进程可以通过指定另一个进程的秩以及一个独一无二的消息标签(tag)来发送消息给另一个进程。接受者可以发送一个接收特定标签标记的消息的请求(或者也可以完全不管标签,接收任何消息),然后依次处理接收到的数据。类似这样的涉及一个发送者以及一个接收者的通信被称作点对点(point-to-point)通信。

OpenMP是线程的概念,MPI是进程的概念。

多机之间的通信需要依赖网络,单机之间的通信需要共享内存/共享文件/管道来实现

MPI-reduce 只有0号节点能拿到求和结果

MPI-allreduce,所有节点都能拿到求和结果

MPI初始化

MPI 结合通信API

MPI_Reduce

MPI_AllReduce

MPI_Bcast

MPI_Scatter

MPI_Gather

MPI结束,调用finalized

MPI当前进程标识、MPI通信域包含的进程数

MPI消息发送,消息接收

MPI预定义数据类型

MPI使用中,容错二次开发,因为运算中某个节点挂了,可能导致得不到结果

NCCL并行技术

NCCL是Nvidia Collective multi-GPU Communication Library的简称,它是一个实现多GPU的collective communication通信(all-gather,reduce,broadcast)库,Nvidia做了很多优化,以在PCIe、Nvlink、InfiniBank上实现较高的通信速度。

NCCL集合操作:

AddReduce、Broadcast、Reduce、AllGather、ReduceScatter

NCCL集合运算-All Reduce

NCCL集合运算-Broadcast

NCCL集合运算-Reduce,结果只给一个节点

NCCL集合运算-AllGather,每个节点只保存了一个片,整合成一个大的片,最后所有的节点都有结果

NCCL集合运算-ReduceScatter,各算自己对应的片,每个计算结果其中一片放在一个计算节点上

NCCL 针对分布式写从,多机多卡

MPI,多机,多核,CPU场景多一些,大部分情况下需要通过网络进行传输,单机多进程之间

OpenMP,相同的地址空间,多核在相同地址空间进行操作,伪指令,交给编译器,multithread更高程级

thread级别,程序员自己动手编代码

环境安装与Gitlab使用

1、CUDA环境安装

2、openmp环境安装

OpenMP是一套支持跨平台共享内存方式的多线程并发的编程API

VS中配置:

1、开启配置支持openmp: 属性->配置属性->C/C++->语言-> OpenMP支持:选择是(/openmp)

2、头文件引入:#include<omp.h>

Linux环境下:

gcc编译器:编译时加上-fopenmp参数即可,gcc -v #查看版本(4.2版本以上都可以支持openmp) gcc -fopenmp filename.cxx

3、nccl环境安装

The NVIDIA Collection Communications Library(NCCL):NVIDIA协作通信库实现了多GPU和多节点集体通信原语,这些原语是为NVIDIA GPU性能优化的。

Linux环境:

准备工作:首先显卡算力需要在3.5以上才可以安装

显卡算力:https://developer.nvidia.com/cuda-gpus#collapseOne

下载地址:https://developer.nvidia.com/nccl/nccl-download#a-collapse278-111

安装方式:

NVIDIA/nccl on Github: https://github.com/NVIDIA/nccl/releases

1、git clone 2、tar.gz源文件,并解压

Linux环境

for Ubuntu:

sudo apt install libnccls=2.7.8-1+cuda10.1\libnccl-dev=2.7.8-1+cuda10.1

for RHEL/Centos:

sudo yum install libnccl=2.7.8-1+cuda10.1\libnccl-devel-2.7.8-1+cuda10.1\libnccl-static-2.7.8-1+cuda10.1

4、gitlab使用

1、git使用 入门基础 https://www.runoob.com/git/git-tutorial.html 常用操作:branc、commit、push、pull、merge等操作

2、gitLab使用 登陆网址 http://47.94.6.102/ 常用操作:创建、删除、复制项目、新建、修改、删除文件/文件夹等

git使用

git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或大或小的项目。Git是Linus Torvalds为了帮助Linux内核开发而开发的一个开放源码的版本控制系统

Git与常用的版本控

安装下载地址:https://git-scm.com/downloads

Debian/Ubuntu

apt-get install libcurl4-gnutis-dev libexpat1-dev gettext libz-dev libssl-dev

apt-get install git

Centos/Redhat

yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel

yum -y install git-core

git --version #查看显示版本

git config --global usr.name "runoob" #设置名字

git config --global usr.email [email protected] #设置邮箱

git使用

一般流程如下:

1、克隆Git资源作为工作目录

2、在克隆的资源上添加或修改文件

3、如果其他人修改了,你可以更新资源

4、在提交前查看修改

5、提交修改

6、在修改完成后,如果发现错误,可以撤回提交并再次修改提交

GitLab是基于web的Git仓库,使用起来二者差不多,它们都提供了分享开源项目的平台,为开发团队提供了存储、分享、发布和合作开发项目的中心化云存储的场所

工作流程

1、登录/注册账号

2、管理员分配权限

3、配置SSH到GitLab账号

4、GitLab复制项目/创建分支

5、本地克隆下载项目:git clone [email protected]:XXX/XXX.git

6、修改文件,提交修改:git add;git commit -a -m "提交添加的注释信息"

7、上传修改到GitLab:git push

Guest:可以创建issue,发表评论、不能读写版本库

Reporter:可以克隆代码,不能提交,可以赋予测试、产品经理此权限

Developer:可以克隆代码、开发、提交、push,可以赋予开发人员此权限

MainMaster:可以创建项目、添加tag、保护分支、添加项目成员、编辑项目、一般gitlab管理员或者CTO才有此权限

配置SSH到GitLab账号:

1、查看生成的公钥:vim id_rsa.pub #查看公钥

2、登录GitLab账号,点击用户图像,然后Setting->左栏点击SSH keys

3、复制公钥内容,黏贴进“key”文本区域内,取名字

4、点击“Add key”

5、总结

Clone this wiki locally