3.4 编程建议
3.4.1 MATLAB 路径
所有的 lab 中的 spmd 的执行语句必须与客户端有相同的 MATLAB 路径,这样它们可以 执行在他们的通用代码块中调用的任何函数。因此,无论何时在客户端你使用 cd,addpath 或者 rmpath,它也在所有的 lab 上执行,如果可能的话。更多的信息,参见 matlabpool 参考 页。当 lab 运行在不同的平台上除了客户端,使用 pctRunOnAll 函数在所有的 lab 上恰当的 设置 MATLAB 路径
3.4.2 错误处理
当错误发生在执行一个 spmd 语句时,错误被报告给客户端。客户端试图在所有的 lab 上打断执行,然后抛出一个错误给用户。
Lab 上制造的错误和警告被 labID 标注,显示在客户端命令行窗口他们从客户端收到的 命令。
3.4.3 局限性
透明性
Spmd语句的必须是透明的,意味着所有的关于变量的应用都是可见的(i.e., they occur in the text of theprogram).
在下面的例子中,因为作为一个输入变量 X 在 spmd 体中是不可见的(只用字符串’X’
被传到 eval 中),对于 lab 来说并不是透明的。因此,MATLAB 在运行时会出现一个错误。
X = 5;
spmd eval('X');
end
类似的,你不能在一个 spmd 语句中通过执行 clear 来从一个工作者空间中删除一个变 量
spmd; clear('X'); end
要想从一个工作者中删除一个具体的变量,从客户端工作区中删除它的 composite。作 为选择,你可以通过将其值设置为空的方式,释放一个变量使用的尽可能多的内存,当他大 概在你的 spmd 语句中不再被需要的时候。
spmd
<statements....>
X = [];
End
一些其他违背透明性原则的函数的例子为:evalc,evalin, assignin 当工作区参数被设置 为 caller,save 和 load 的时候,如果 load 的输出不被赋值。
MATLAB 成功的执行出现在 spmd 体中被调用的函数中的 eval 和 evalc 语句。
嵌套函数
在一个函数里,spmd 语句体不能直接引用一个嵌套函数。然而它可以通过一个被定义 为处理嵌套函数的函数的变量来调用一个嵌套函数。
因为 spmd 体在工作者中执行,被 spmd 体中调用的嵌套函数改变的变量并不在外函数 的工作区中被改变。
异步函数
Spmd 语句体并不能定义异步函数,然而,它能够通过函数句柄的方式来引用一个异步 函数
嵌套 spmd 语句
Spmd 语句体内并不能包含其他的 spmd。然而,它可以调用一个函数包含其他地 spmd 语句。保证你的 matlab 池有足够的空间来容纳这样的扩展。
嵌套 parfor 循环
一个 parfor 循环内并不能包含一个 spmd 语句,反之亦然。
break 和 return 语句
spmd 语句中不能包含一个 bread 和 return 语句。
全局和持久变量
Spmd 语句中不能包含一个全局的或者持久变量。
4 多核环境下 matlab 并行工具箱运行方法
要运行并行程序(所有的并行程序都要这么做),首先要
matlabpool open local lab_num
lab_num 是你要打开的 lab(也叫 worker,我理解为为我们做计算工作的并行进程)数量(不能 超过 CPU 核心数,所以其数量代表并行度),也可以不指定 lab_num:
matlabpool
默认打开的 lab_num 数量与 CPU 核心数相同。不执行这条命令,后面的工作也可以进行,
但那就不是并行了。
运行结束后请
matlabpool close
关闭打开的 labs.
5 矩阵向量乘与矩阵矩阵乘多核并行化
我写了 4 个函数(函数定义以及注释见相关 matlab 文件):
single_row_multiply_matrix(row_vector, matrix);
行向量与矩阵相乘 matrix_multiply_for(matrix_a, matrix_b); 矩阵乘(使用 for 循环) matrix_multiply_parfor(matrix_a,
matrix_b);
矩阵乘(使用 parfor 循环) contrast_parfor_matrix_multiply(matrix_a,
matrix_b);
计算矩阵乘时 parfor 相对 for 加速比
注:矩阵乘函数一样可以用于矩阵乘以列向量——此时 matrix_b 应为列向量。
串行代码
for i = 1:am res(i,:) =single_row_multiply_matrix(matrix_a(i,:),matrix_b);
end
并行代码
parfor i = 1:am%seperate matrix_a to rows,parallel on row level res(i,:) =
single_row_multiply_matrix(matrix_a(i,:),matrix_b);
end
其中 single_row_multiply_matrix(row,matrix)函数计算一个行向 量与一个矩 阵相
1000x1000 * 1000x1000
2000x2000 * 2000x1
100x100 * 100x100 200x200 * 200x200 1000x1000 * 1000x1000
图 1-矩阵相乘中 parfor 相对 for 的加速比
选取了三个矩阵规模:100x100 * 100x100,200x200 * 200x200,1000x1000 * 1000x1000
1 2 3
4
200x200 * 200x1 2000x2000 *
2000x1 0
0.2 0.4 0.6 0.8 1 1.2 1.4 1.6 1.8
lab数量
矩阵乘以列向量——parfor相对于for的加速比
200x200 * 200x1 800x800 * 800x1 2000x2000 * 2000x1
图 2-矩阵乘以列向量中 parfor 相对 for 的加速比
选取了 3 个计算规模:200x200 * 200x1,800x800 * 800x1,2000x2000 * 2000x1
从两幅图里都可以看到当计算规模较小时(100x100)parfor 加速不明显甚至性能比 for 还 低,而且 lab 数量变大可能造成性能下降,这是因为将任务分配给 labs 会耗时,这种情况下 parfor 并行得来的性能提升有限,不能弥补这种消耗。矩阵规模较大(1000x1000)时加速明显,
而且随着 lab 数量增加而增加,近似线性加速。