Matlab并行化计算

2023-05-16

Matlab并行化计算及GPU计算教程

前置要求和设置

要求电脑CPU有超过2个核心,内存大于2G。

建议先调试好代码,再进行并行化计算。

查看并行化计算工具箱版本

>>> ver(parallel)
------------------------------------------------------------------------------------------------
MATLAB 版本: 9.12.0.1884302 (R2022a)
MATLAB 许可证编号: 40523737
操作系统: Microsoft Windows 11 专业版 Version 10.0 (Build 22000)
Java 版本: Java 1.8.0_202-b08 with Oracle Corporation Java HotSpot(TM) 64-Bit Server VM mixed mode
------------------------------------------------------------------------------------------------
Parallel Computing Toolbox                            版本 7.6              (R2022a)

确保并行化工具箱正确配置

菜单栏 >> Parallel >> Manage Clusters >> local >> Validation >> 全部勾选,点击Validate,绿色对勾为正确配置

在这里插入图片描述

验证GPU是否可以使用

>>> gpuDevice
ans = 

  CUDADevice - 属性:

                      Name: 'NVIDIA GeForce RTX 3080'
                     Index: 1
         ComputeCapability: '8.6'  % 计算能力至少1.3以上,建议2.0以上
            SupportsDouble: 1
             DriverVersion: 11.6000
            ToolkitVersion: 11.2000
        MaxThreadsPerBlock: 1024
          MaxShmemPerBlock: 49152
        MaxThreadBlockSize: [1024 1024 64]
               MaxGridSize: [2.1475e+09 65535 65535]
                 SIMDWidth: 32
               TotalMemory: 1.2884e+10
           AvailableMemory: 1.1487e+10
       MultiprocessorCount: 70
              ClockRateKHz: 1785000
               ComputeMode: 'Default'
      GPUOverlapsTransfers: 1
    KernelExecutionTimeout: 1
          CanMapHostMemory: 1
           DeviceSupported: 1
           DeviceAvailable: 1
            DeviceSelected: 1

快速上手parfor

将for循环,改为parfor循环。并行化计算会自动进行。

parfor ...
    statement
end

也可以使用左下角的符号,选择Start parallel pool,来手动控制并行化计算池的启动与关闭。

也可以使用命令行

parpool('local',N)  % 启动并行化,local为预设的方案,N为线程数量
delete(gcp('nocreate'))  % 关闭并行化

使用parfor的注意事项

  1. 每次循环的计算过程是独立的,当前循环不依赖历史循环的信息;
  2. 循环的顺序是没有限制的;
  3. parfor循环的变量必须是整数,如果是非整数,则需要在循环外部转换为整数。
%  循环变量不能是非整数
parfor x = 0:0.1:1
	pass
end
%  循环变量,要修改为整数
xALL = 0:0.1:1;
parfor ii = 1:length(xAll)
	x = xALL(ii)
	pass
end
  1. parfor循环,不允许进行嵌套,但是可以通过函数的形式进行调用
%  不能进行循环嵌套
parfor x = 1:5
	parfor y = 1:10
		pass
	end
end
%  利用函数调用,进行parfor嵌套
parfor x = 1:5
	myprog(x)
end

function myprog(x)
parfor y = 1:10
	pass
end
  1. 如果代码分析器,无法得出代码哪里出问题了,可以将parfor循环体,改为函数调用的形式
%  代码分析器,无法获取代码不能并行化的原因
function ex2_bad

data = rand(4,4);
means = zeros(1,4);
parfor I = 1:4
	means(I) = z.mean;
end
disp(means)

%  尝试使用函数调用的方式,替换parfor循环体
function ex2_bad

data = rand(4,4);
means = zeros(1,4);
parfor I = 1:4
	means(I) = computeMeans(data, I);
end
disp(means)

function means = computeMeans(data,I)
z.means = mean(data(:,I));
means = z.mean;
  1. 如果parfor加速效果不明显,可能是以下几个原因导致的:计算时间太短;内存或者文件读写速度限制;已经存在并行化计算的其他代码(可以使用任务管理器查看);个别迭代耗时远大于其他迭代。

批处理

交互式的并行化池,需要matlab客户端一直打开。

对于批处理,在使用集群计算时,可以关闭matlab客户端,处理其他工作。适合集群计算、耗时长的计算。

批处理的三个步骤:

  1. 提交任务
%  对于脚本的使用方法
job = batch("ascript")  

%  对于函数的使用方法,(函数名称,返回输出的数量,输入参数)
job = batch(@ex_serial, 1, (50,4000));  

%  使用集群计算,可以关闭matlab客户端,甚至关闭电脑
clust = parcluster('local');
%  N = 4;  %  计算机CPU核心数
N = clust.NumIdleWorkers  % 可以调用所有可用核心
job = batch(clust, @ex_parallel, 1, (50,4000), 'pool', N-1)  
% N-1,是因为需要一个线程负责任务的分发以及结果的收集,即存在一个线程对其他线程进行管理
  1. 查看任务是否完成
wait(job, 'finished')  % 当以自动方式运行多个任务时,这个命令可以屏蔽其他任务,直到当前任务完成
get(job, 'state')  %  获取当前任务的进度
% 也可以使用菜单栏的Job Monitor,以交互式的方法检查任务进度
  1. 获取任务结果
results = fetchOutputs(job)  % 获取任务结果,以cell array的形式返回
outk = results{k}  % 获取任务结果的第k个输出
delete(job)  % 任务完成后,删除任务

对于不使用for循环的代码,可以参考parallel_template.m

扩展至集群和云

大型项目需要更多的计算能力和内存,此时可以考虑使用公司、组织、云端的集群进行计算,只需要对代码进行很小的修改即可实现。

local profile,并行化本地配置方案,可以使用单台计算机的多核心进行加速,也可以用于在使用其他并行化方案前,测试并行化代码。

  1. 添加新的并行化配置方案,home >> parallel >> manage cluster profiles >> add profile / discover clusters / import profile

  2. matlab job scheduler (MJS) profile,可以利用安装了matlab distributed computing server(MDCS)上的计算资源,MDCS的使用方法这里不做叙述。

    第三方的cluster schedulers,在现有的cluster scheduler中集成了MDCS,如果没有你想要的scheduler,选择generic即可。

  3. 检查当前并行化配置方案是否可用,home >> parallel >> manage cluster profiles,选择要测试的profile,点击validate,全部为绿色表示通过。

  4. 使用方法,简单的将’local’替换为你的并行化方案即可。

  5. 如果报错,无法找到文件,可将数据发送到集群。

% 对于并行化计算池
parpool(...,'AttachedFiles',{'C:\mydir'})  % 对于新的并行化计算池
addAttachedFiles(gcp, {'C:\mydir'})  % 更新现有的并行化计算池
% 对于批处理
batch(...,'AttachedFiles',{'C:\mydir'})
  1. 如果加速没有达到想要的效果,可能是文件传输占用了很多时间,要避免频繁的将数据复制到集群。

比parfor更高级的方法:spmd

spmd(single program multiple data),spmd代码块中的代码,在所有的线程运行,可以用于parfor循环之前加载数据。

spmd
	% myfile.mat,在所有线程都可以访问
	data = load('myfile.mat')
end

parfor I = 1:N
	% 使用数据的代码块
end

也可以控制每个线程做什么工作。

% labindex返回worker的索引
% numlabs返回worker的总数
spmd
	switch labindex
		case 1
			% 线程1的代码
		case 2
			% 线程2的代码
		...
	end
end

也可以控制线程之间的数据交互

% labSend(dataToSend,workerIdx)可以将需要发送的数据,发送至指定索引的线程
% labReceive(workerIdx)可以接受指定线程的数据
% labSend和labReceive需要成对使用
spmd
	...
	if labindex < numlabs
		% 除了最后一个线程之外的线程,将数据发送至下一个线程
		labSend(dataToSend, labindex+1);
	else
		% 最后一个线程数据发送至第一个线程
		labSend(dataToSend, 1);
	end
	
	if labindex > 1
		% 除了最后一个线程之外的线程,接受上一个线程的数据
		dataReceived = labReceive(labindex-1);
	else
		% 第一个线程接受最后一个线程的数据
		dataReceived = labReveice(numlabs);
	end
	...
end

% 所有线程的数据可以组合输出,通过索引可以访问不同线程的数据
dataOnClient = dataReceived(:);

分布式矩阵

可以划分到各个线程进行计算,仍可以被视为一个矩阵,这种矩阵称为分布式矩阵。

主要被用于集群计算,可以利用多个机器的内存。

  1. 创建分布式矩阵的方法
% 方法一
zeros(...,'distributed')
randn(...,'distributed')
% 如果所有线程的数据划分方式一样,可以直接使用distributed,但是只能按照列进行划分
a = reshape(1:16, 4, 4)
a = distributed(a)

% 方法二
% 从多个文件,或者是一个巨大到无法一次载入内存的文件,创建分布式矩阵
% 可以在每个线程载入数据,然后使用codistributed.build及codistributorld将每个线程的矩阵结合起来
% 需要指定分布式矩阵的size,(可选)指定各个线程的数据
spmd
	N = 1;
	mat = repmat([1;2;3], 1, N) + (labindex-1)*3;
	
	codistr = codistributorld(codistributorld.unsetDimension,codistributorld.unsetPartition,[3,numlabs*N]);
	distmat = codistributed.build(mat, codistr)
	
	disp(getLocalPart(distmat))
end

% 使用gather可以将分布式矩阵,转为数值化矩阵
distsum = sum(distmat);
numericsum = gather(distsum);

GPU计算

  1. 将数据迁移至GPU显存,或者在GPU显存创建数据

    % 使用gpuArray将数据迁移至GPU
    a = reshape(1:16, 4, 4);
    a = gpuArray(a);
    % 直接在GPU创建数据,这种方法更高效
    z = zeros(4, 4, 'gpuArray')
    % 如需查看哪些操作支持gpuArray
    >> methods gpuArray
    
  2. 使用GPU代码处理数据

  3. 将数据迁移回CPU

% 使用CPU对矩阵进行滤波操作
A = magic(5000);
f = ones(1,20)/20;

tic;
B = filter(f, 1, A);
tCPU = toc;

disp(['Total time on CPU:	' num2str(tCPU)])

% 使用GPU对矩阵进行滤波操作
tic;
AonGPU = gpuArray(A);
BonGPU = filter(f, 1, AonGPU);
BonCPU = gather(BonGPU);
wait(gpuDevice)
tGPU = toc;

disp(['Total time on GPU:	' num2str(tGPU)])

% 只查看计算耗时,不考虑数据传输耗时
tic;
BonGPU = filter(f, 1, AonGPU);
wait(gpuDevice)
tCompGPU = toc;

disp(['Computation time on GPU:	' num2str(tCompGPU)])
% 使用arrayfun或者pagefun进一步加速
M = 300;  % 行数
K = 500;  % 矩阵内部维度
N = 100;  % 列数
P = 200;  % 页数

% CPU模式
tic
A = rand(M,K);
B = rand(K,N,P);
C = zeros(M,N,P);
for I = 1:P
	C(:,:,I) = A*B(:,:,I);
end
t = toc;
disp(['CPU time:	' num2str(t)])

% GPU模式,gpuArray
tic
A = rand(M,K,'gpuArray');
B = rand(K,N,P,'gpuArray');
C = zeros(M,N,P,'gpuArray');
for I = 1:P
	C(:,:,I) = A*B(:,:,I);
end
wait(gpuDevice)
t = toc;
disp(['GPU using gpuAarrys time:	' num2str(t)])

% GPU模式,pagefun
tic
A = rand(M,K,'gpuArray');
B = rand(K,N,P,'gpuArray');
C = pagefun(@mtimes,A,B);
wait(gpuDevice)
t = toc;
disp(['GPU using pagefun time:	' num2str(t)])

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Matlab并行化计算 的相关文章

  • Jetson NX emmc版本系统转移到SSD

    因emmc版本的NX自带内存不够大 xff0c 只有16GB xff08 手上的是这个型号 xff09 xff0c 安装系统大概需要除去4G多内存 xff0c 再安装CUDA cuDNN TensorRT等内存直接爆满 无法继续使用 所以需
  • unix 修改文件类型

    Unix及类Unix系统里 xff0c 每行结尾只有换行 n xff1b Windows系统里面 xff0c 每行结尾是换行 43 回车 n r 第一种 xff1a 利用Linux下的vim编辑器 xff0c 可以方便的在dos文件 uni
  • DIR=$(cd `dirname $0`; pwd)

    dirname 0 xff0c 获取当前脚本所在绝对目录 cd 96 dirname 0 96 xff0c 进入这个目录 xff08 切换当前工作目录 xff09 pwd xff0c 显示切换后脚本所在的工作目录 echo xff0c 打印
  • ulimit命令的使用

    ulimint a 用来显示当前的各种用户进程限制 Linux对于每个用户 xff0c 系统限制其最大进程数 xff0c 为提高性能 xff0c 可以根据设备资源情况 xff0c 设置个Linux用户的最大进程数 xff0c 一些需要设置为
  • error while loading shared libraries: libavformat.so.58: cannot open shared object file: 解决

    sutpc icvtsn dfa error while loading shared libraries libavformat so 58 cannot open shared object file No such file or d
  • Git 检测不到文件目录下的文件变化信息

    Git在上传代码的时候发现有的只能检测出某个目录 xff0c 然而检测不到那个目录下的C文件和h文件 并且git 提交之后 xff0c 在git上某个文件有后缀 64 b4c4u7之类的 这种文件没办法点击 没办法查看 xff0c 根本无法
  • Linux 搭建MQTT服务器并使用

    环境 xff1a ubuntu 18 04 1 安装必备软件 span style background color f6f6f6 span style color 121212 yum install gcc c 43 43 cmake
  • 批量ping多个IP地址

    for L D in 90 1 95 do ping 10 10 70 D gt gt ping log 代码的意思如下 xff1a 代码中的这个 90 1 95 就是网段起与始 xff0c 就是检测网段10 10 70 90到10 10
  • Linux驱动开发一

    一 开发模块框架 1 xff09 编写源代码 include lt linux init h gt include lt linux module h gt 加载函数 static int init hello init void prin
  • ”此网站尚未经过身份验证“问题的解决办法

    在使用 https 访问我的路由器时出现无法访问的现象 xff0c 下图是浏览器的告警信息 xff0c 目前通过百度 此网站尚未经过身份验证 并没有找到解决方案 而我的另一台笔记本电脑却可以通过 https 打开路由器的配置管理页面 xff
  • linux的yum更新方式update和upgrade

    Linux升级命令有两个分别是yum upgrade和yum update 这个两个命令是有区别的 代码如下 yum y update 升级所有包同时也升级软件和系统内核 代码如下 yum y upgrade 只升级所有包 xff0c 不升
  • Linux驱动开发二

    2 xff09 创建设备节点 gt 手动创建设备节点 mknod 设备名 设备类型 主设备号 次设备号 mknod dev hello c 254 0 gt 自动创建设备节点 创建类 class create owner name 参数1
  • SO_BINDTODEVICE 使用

    就绑定到了接口 34 lmi40 34 上 所有数据报的收发都只经过这个网卡 对于SOL BINDTODEVICE的总结如下 xff08 1 xff09 对于TCP套接口 UDP套接口 RAW套接口 xff0c 可以通过SO BINDTOD
  • json交叉编译并移植到嵌入式开发板

    1 解压 xff1a tar xvf json c 0 9 tar gz 默认解压在当前目录 2 进入解压后的目录 xff1a cd cd json c 0 9 3 执行 xff1a sudo configure CC 61 aarch64
  • strftime()函数的使用方法

    strftime strftime是C语言标准库中用来格式化输出时间的的函数 Ubuntu自带的manual手册说法如下 xff0c 截图没有截全 xff0c 需要更详细信息的自行查看相关的内容 下面是strftime的用法 示例代码如下
  • tcpdump 抓包

    一 Tcpdump抓包 抓取端口为2008的数据包 抓包文件内容 抓取到的内容保存在文件中 xff0c 可以通过wireshark分析 二 tcpdump的一些命令 tcpdump和ethereal可以用来获取和分析网络通讯活动 xff0c
  • wireshark抓包工具的使用

    前言 wireshark是非常流行的网络封包分析软件 xff0c 功能十分强大 可以截取各种网络封包 xff0c 显示网络封包的详细信息 使用wireshark的人必须了解网络协议 xff0c 否则就看不懂wireshark 为了安全考虑
  • Docker 在Ubuntu的安装

    系统要求 Docker 支持以下版本的 Ubuntu 操作系统 xff1a Ubuntu Hirsute 21 04Ubuntu Groovy 20 10Ubuntu Focal 20 04 LTS Ubuntu Bionic 18 04
  • Notepad++ 如何筛选内容

    在程序调试的过程中 xff0c 通常会通过抓取日志来分析 xff0c 但实际情况抓取的日志会很多 xff0c 如何在众多的日志中筛选出自己想要的内容呢 xff0c 我们可以通过notepad打开日志 xff0c 然后进行筛选 1 通过ctr
  • Jetson Nano emmc版本系统镜像备份和烧录

    一 镜像备份 1 xff0e 将待复制的jetson设备进入恢复模式 xff0c 用数据线连接jetson设备和主机 对于原厂开发板将FC REC引脚与GND短接 xff0c 通过micro usb到usb数据线连接到电脑 在电脑的ubun

随机推荐

  • Ubuntu系统永久挂载硬盘、U盘等存储设备

    在日常开发工作中 xff0c 经常会遇见需要借助外接存储设备来存放一些数据的情况 xff0c 于是我们会使用如下命令来挂载 xff1a sudo mount dev sda2 mnt 这样挂载的弊端就是设备掉电之后 xff0c 之前挂载的设
  • ubuntu20.04 + kiosk + chrome打造一体机系统

    kiosk 的英文直译为凉亭 公用电话亭 报摊或者一体机的意思 目前主流的浏览器都具有kiosk模式 我们可以使用浏览器的kiosk模式加ubuntu操作系统在不增加任何软件的情况将我们的B S程序打造成一个一体机系统 1 前置条件 ubu
  • Ubuntu 增加swap交换内存

    一 创建虚拟内存 在实际开发中发现swap交换分区不够用了 xff0c 于是需要创建虚拟内存来增加交换分区的大小 在系统空闲空间位置创建swap虚拟内存专用文件夹 cd data 切到你想要创建交换分区的目录 mkdir swap 新建文件
  • 闲扯原码,补码和反码

    闲扯原码 xff0c 补码和反码 始发于 goal00001111 的专栏 xff1b 允许自由转载 xff0c 但必须注明作者和出处 人类习惯使用十进制数进行数值计算 xff0c 而计算机则采用二进制 xff0c 所以为了让计算机帮助人类
  • switch 无法启动软件,请在HOME菜单中再试一次

    本人的是11 0 1 0 18 1 xff0c 刚升级完成后所有游戏都提示 xff1a 无法启动软件 xff0c 请在HOME菜单中再试一次 xff1b 然后搜索一番之后亲测有效 1将如下资源下载到本地 xff0c 2解压后放到对应的文件夹
  • switch如何更新大气层,和进入hekate界面

    0 xff0c 使用windows xff0c 使用windows xff0c 使用windoes xff01 1 xff0c 下载hekate最新版 xff0c 下载最新版大气层固件 xff0c 替换掉SD卡对应地方的文件即可 xff0c
  • RxJava简单入门

    前言之前 span style color fe2c24 首先来认识一下接下来我们将要接触的关键单词 xff0c Observeable Observer subscrib国内基本都翻译成 xff0c 被观察者 xff0c 观察者 xff0
  • WebView加载网页出错:ERR_UNKNOWN_URL_SCHEME

    一 原因 因为webview只能识别http https这样的协议 xff0c 像一些微信 weixin 去哪儿 qunaraphone xff0c 他们自定义的协议webView是无法识别的 xff0c 因此就会出现 xff1a ERR
  • ESP32-CAM搭建Arduino及简单使用

    准备 需要一个ESP32 CAM模块 xff0c 我买的是这种 xff0c 下面带了个下载模块的 xff0c 接上USB就能用了 xff0c 很方便 xff0c 如果没有买下面那个那就得自行用USB TTL了 配置环境 有了硬件 xff0c
  • Failed resolution of: Landroidx/databinding/DataBinderMapperImpl;

    报错 xff1a Failed resolution of Landroidx databinding DataBinderMapperImpl 原因 xff1a lib工程gradle文件中加了dataBinding xff0c 且能使用
  • 谷歌浏览器调试工具使用基础版(一)

    知识采集出处 一 先来认识一下这些按钮 先来看这张图最上头的一行是一个功能菜单 xff0c 每一个菜单都有它相应的功能和使用方法 xff0c 依次从左往右来看 1 箭头按钮 xff1a 用于在页面选择一个元素来审查和查看它的相关信息 xff
  • Android studio 按ctrl+v变成insert的解决办法

    Android studio 按ctrl 43 v变成insert的解决办法 Mac版 android studio 竖线的光标突然变成了矩形 解决方法 xff1a File Settings Editor General Apperanc
  • Windows Server2012多远程桌面配置

    一 配置相关信息 1 win 43 R 输入gpedit msc 计算机配置 管理模板 windows组件 远程桌面服务 远程桌面会话主机 连接 2 将远程桌面服务限制到单独的远程桌面会话禁用 3 启用拒绝将已登录到控制台的管理员注销 不启
  • Android屏幕适配dp、px两套解决办法

    最新最全文章 2018 08 25 xff1a Android dp方式的屏幕适配 原理 后期补充完整讲解 手机dp输出是横屏还是竖屏 android阿杜的博客 CSDN博客 又是屏幕适配 xff0c 这类文章网上不是很多了吗 xff1f
  • Android项目构建变体不能切换打包debug模式和release模式

    Android项目build variants不能切换打包debug模式和release模式 xff0c 不能切换active abi类型 我的项目发现的原因 xff1a 就是项目文件夹名称 xff0c 和包名不同 xff0c 如包名写的是
  • Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES: ... has no certificates at entry AndroidManifest.xml]

    很长一段时间都用快速打包 packer ng plugin xff0c 没注意到底用Android Studio打包会有什么区别 xff0c 今天写了个demo xff0c 居然发现我输入了签名之后只有一次是安装成功的 xff0c 后边都是
  • Mac顶部菜单栏(Menubar)卡死

    升级了Mojave后 xff0c Mac pro 2015 early 顶部菜单栏经常卡死 重启菜单栏 xff08 Menubar xff09 笔者接下来分享两种常见的重启菜单栏的方法 方法一 xff1a 使用活动监视器 打开 OS X 预
  • 计算机专业术语大全(中~英文版)

    AGP Accelerated Graphics Port xff0d 图形加速接口 Access Time xff0d 存取时间 Address 地址 ANSI American National Standards Institute
  • hdfs 的启动

    xff08 1 xff09 先配置文件 修改 core site xml 如下 修改 hdfs site xml 如下 xff1a lt configuration gt lt property gt lt name gt dfs repl
  • Matlab并行化计算

    Matlab并行化计算及GPU计算教程 前置要求和设置 要求电脑CPU有超过2个核心 xff0c 内存大于2G 建议先调试好代码 xff0c 再进行并行化计算 查看并行化计算工具箱版本 gt gt gt ver parallel MATLA