-
Notifications
You must be signed in to change notification settings - Fork 0
分布式高性能深度学习1月11日
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、总结