当前位置: 首页 > news >正文

matlab多线程,parfor循环进度,matlab互斥锁

一. 内容简介

matlab多线程,parfor循环进度,matlab互斥锁

二. 软件环境

2.1 matlab 2022b

2.2代码链接

https://gitee.com/JJW_1601897441/csdn

三.主要流程

3.1 matlab多线程

有好几种,最简单的,最好理解的就是parfor,就拿那个为例子了,使用情况就是每一个for循环之前不能依赖关系,每轮计算都是独立的这种,才可以用parfor,不同版本不太一样,老版限制好像更多一些

parfor i = 1:1000disp(i);
end

在这里插入图片描述

3.2 parfor循环进度

用parfor并行去算一些东西的时候,有些需要循环很多次,我们是不清楚程序到底执行了多少轮,如果可以看到进度的话,时间太长了,我们或许就不会算了,

3.2.1 进度条窗口方式

会用就行,可以直接拷贝走,这个是官方文档里面找的

w = waitbar(0,'Please wait ...');% Create DataQueue and listener
D = parallel.pool.DataQueue;
afterEach(D,@parforWaitbar);N = 10000;
parforWaitbar(w,N)parfor i = 1:N% pause替换乘自己的就可以了pause(rand)send(D,[]);
end
delete(w);function parforWaitbar(waitbarHandle,iterations)persistent count h Nif nargin == 2% Initializecount = 0;h = waitbarHandle;N = iterations;else% Update the waitbar% Check whether the handle is a reference to a deleted objectif isvalid(h)count = count + 1;waitbar(count / N,h);endend
end

在这里插入图片描述

3.2.2 底部进度条方式

会用就行,也是官方网站里面找的,这个还需要一个文件,放到同一级目录就可以了,代码我放上边链接了

% 设置循环次数
N = 10000;
% 创建一个迭代计数器对象
parfor_progress(N);
parfor i = 1:N% pause替换乘自己的就可以了pause(rand)parfor_progress;
end
parfor_progress(0);

在这里插入图片描述

3.3 matlab互斥锁

在parfor循环中,读写数据是很麻烦的,并行计算就是要计算结果的,但是parfor中的计算结果很难接收出来,量少的时候,还可以通过数组接收(2016版不可以),量多的时候,数组接收就不太现实,每轮循环把数据写入文件中呢,parfor会报错,即使可以的话,由于matlab没有互斥锁,写文件即使可以写进去,也会是乱的,没办法用

还是那句话,会用就行,替换成自己的就可以了,注释写里面了

% 创建一个 DataQueue 对象
dq = parallel.pool.DataQueue;
file = fopen('ccc.txt','w');% 多重匿名函数
fun_with_params = @(data) saveData(data, file);
% 在 DataQueue 上设置 afterEach 方法,
% 这个是给数据绑定一个处理方法,就是在信号发送以后,执行那个处理方法,
% 这个处理方法不是并行的,同一时刻只有一个线程在处理数据,其他的线程都要排队
% 和互斥锁的思想很像
afterEach(dq, fun_with_params);
% 在工作线程中定义处理函数并发送数据到 DataQueue
parfor i = 1:100% 替换成自己的a = rand();% 在这里通过 send 函数将数据发送到 DataQueue% 可以发送单个,也可也发送数组send(dq, a);
endfclose(file);function saveData(data, file)% 在此处编写后处理代码fprintf(file,'%.10f ', data); fprintf(file,'\n'); 
end

在这里插入图片描述

3.4 parfor_progress.m

function percent = parfor_progress(N)
%PARFOR_PROGRESS Progress monitor (progress bar) that works with parfor.
%   PARFOR_PROGRESS works by creating a file called parfor_progress.txt in
%   your working directory, and then keeping track of the parfor loop's
%   progress within that file. This workaround is necessary because parfor
%   workers cannot communicate with one another so there is no simple way
%   to know which iterations have finished and which haven't.
%
%   PARFOR_PROGRESS(N) initializes the progress monitor for a set of N
%   upcoming calculations.
%
%   PARFOR_PROGRESS updates the progress inside your parfor loop and
%   displays an updated progress bar.
%
%   PARFOR_PROGRESS(0) deletes parfor_progress.txt and finalizes progress
%   bar.
%
%   To suppress output from any of these functions, just ask for a return
%   variable from the function calls, like PERCENT = PARFOR_PROGRESS which
%   returns the percentage of completion.
%
%   Example:
%
%      N = 100;
%      parfor_progress(N);
%      parfor i=1:N
%         pause(rand); % Replace with real code
%         parfor_progress;
%      end
%      parfor_progress(0);
%
%   See also PARFOR.% By Jeremy Scheff - jdscheff@gmail.com - http://www.jeremyscheff.com/error(nargchk(0, 1, nargin, 'struct'));if nargin < 1N = -1;
endpercent = 0;
w = 50; % Width of progress barif N > 0f = fopen('parfor_progress.txt', 'w');if f<0error('Do you have write permissions for %s?', pwd);endfprintf(f, '%d\n', N); % Save N at the top of progress.txtfclose(f);if nargout == 0disp(['  0%[>', repmat(' ', 1, w), ']']);end
elseif N == 0delete('parfor_progress.txt');percent = 100;if nargout == 0disp([repmat(char(8), 1, (w+9)), char(10), '100%[', repmat('=', 1, w+1), ']']);end
elseif ~exist('parfor_progress.txt', 'file')error('parfor_progress.txt not found. Run PARFOR_PROGRESS(N) before PARFOR_PROGRESS to initialize parfor_progress.txt.');endf = fopen('parfor_progress.txt', 'a');fprintf(f, '1\n');fclose(f);f = fopen('parfor_progress.txt', 'r');progress = fscanf(f, '%d');fclose(f);percent = (length(progress)-1)/progress(1)*100;if nargout == 0perc = sprintf('%3.0f%%', percent); % 4 characters wide, percentagedisp([repmat(char(8), 1, (w+9)), char(10), perc, '[', repmat('=', 1, round(percent*w/100)), '>', repmat(' ', 1, w - round(percent*w/100)), ']']);end
end

3.5 补充

按下面代码执行的,afterEach只能保证传完数据以后执行对应函数,并不代表一个循环里面的都一起执行的
在这里插入图片描述

% 创建一个 DataQueue 对象
dq1 = parallel.pool.DataQueue;
dq2 = parallel.pool.DataQueue;
file1 = fopen('ccc1.txt','w');
file2 = fopen('ccc2.txt','w');
% 多重匿名函数
fun_with_params1 = @(data) saveData(data, file1);
fun_with_params2 = @(data) saveData(data, file2);
% 在 DataQueue 上设置 afterEach 方法
afterEach(dq1, fun_with_params1);
afterEach(dq2, fun_with_params2);
% 在工作线程中定义处理函数并发送数据到 DataQueue
parfor i = 1:1000% 替换成自己的a = rand();% 在这里通过 send 函数将数据发送到 DataQueue% 可以发送单个,也可也发送数组send(dq1, a);send(dq2, a);
end% 等待所有数据接收完成% 显示接收到的数据
% 辅助函数用于保存接收到的数据到数组
function saveData(data, file)% 在此处编写后处理代码fprintf(file,'%.10f ', data); fprintf(file,'\n'); 
end

改进

% 创建一个 DataQueue 对象
dq1 = parallel.pool.DataQueue;
file1 = fopen('ccc11.txt','w');
file2 = fopen('ccc21.txt','w');
file3 = fopen('ccc31.txt','w');
% 多重匿名函数
fun_with_params1 = @(data1) saveData(data1, file1, file2,file3);
% 在 DataQueue 上设置 afterEach 方法
afterEach(dq1, fun_with_params1);
% 在工作线程中定义处理函数并发送数据到 DataQueue
parfor i = 1:100% 替换成自己的a = rand();data = {i,i,i}% 在这里通过 send 函数将数据发送到 DataQueue% 可以发送单个,也可也发送数组send(dq1, data);
end% 等待所有数据接收完成fclose(file1);
fclose(file2);
fclose(file3);
% 显示接收到的数据
% 辅助函数用于保存接收到的数据到数组
function saveData(data, file1,file2,file3)% 在此处编写后处理代码data1 = data{1};data2 = data{2};data3 = data{1};fprintf(file1,'%.10f ',  data1); fprintf(file1,'\n'); fprintf(file2,'%.10f ',  data2);fprintf(file2,'\n'); fprintf(file3,'%.10f ',  data3);fprintf(file3,'\n'); 
end
http://www.lryc.cn/news/102993.html

相关文章:

  • 建木使用进阶-创建密钥管理
  • 多模态第2篇:MMGCN代码配置
  • DHCP部署与安全详解
  • 华为数通HCIP-PIM原理与配置
  • linux 权限
  • SQL基础使用
  • 金蝶云星空任意文件读取漏洞复现(0day)
  • linux中readelf命令详解
  • Python 教程之标准库概览
  • MySQL~数据库的基本概念
  • uniapp文件下载
  • 让GPT人工智能变身常用工具-下
  • el-table 表格头部合并
  • 【机器学习】Linear Regression
  • STM32 中断优先级管理(二)
  • 17-汽水瓶
  • Mindar.JS——实现AR图像追踪插入图片或视频
  • JVM源码剖析之JIT工作流程
  • 【投资笔记】(23/7/31)下半年消费复苏的机会来了?
  • MySQL二进制日志(binlog)配置、二进制日志binlog查看、mysqlbinlog查看二进制日志、二进制日志binlog清理等详解
  • Python内存管理解析:高效利用资源的关键
  • 解决Debian10乱码以及远程连接ssh的问题
  • C# 泛型(Generic)
  • Golang之路---02 基础语法——流程控制(if-else , switch-case , for-range , defer)
  • HTTP——HTTP报文内的HTTP信息
  • RocketMQ工作原理
  • Jenkins+Docker+Docker-Compose自动部署,SpringCloud架构公共包一个任务配置
  • spring boot 2 配置上传文件大小限制
  • Jmeter —— 录制脚本
  • 从零开始学Docker(一):Docker的安装部署