我正在尝试并行化 Gauss-Seidel 算法中使用的一些代码,以近似线性方程组的解。
简而言之,对于一个NxN
矩阵,在一次迭代期间,我正在sqrt(N)
一个接一个地进行并行计算。在并行计算的一个会话中,我将计算sqrt(N)
向量值的任务分配给可用的工作人员。
并行计算会话中涉及的代码是这样的:
future_results(1:num_workers) = parallel.FevalFuture;
for i = 1:num_workers
start_itv = buck_bound+1 + (i - 1) * worker_length;
end_itv = min(buck_bound+1 + i * worker_length - 1, ends_of_buckets(current_bucket));
future_results(i) = parfeval(p, @hybrid_parallel_function, 3, A, b, x, x_last, buck_bound, n, start_itv, end_itv);
end
for i = 1:num_workers
[~, arr, start_itv, end_itv] = fetchNext(future_results(i));
x(start_itv:end_itv) = arr;
end
调用的函数parfeval
是这样的:
function [x_par, start_itv, end_itv] = hybrid_parallel_function (A, b, x, x_last, buck_bound, n, start_itv, end_itv)
x_par = zeros(end_itv - start_itv + 1, 1);
for i = start_itv:end_itv
x_par(i-start_itv+1) = b(i);
x_par(i-start_itv+1) = x_par(i-start_itv+1) - A(i, 1:buck_bound) * x(1:buck_bound);
x_par(i-start_itv+1) = x_par(i-start_itv+1) - A(i, buck_bound+1:i-1) * x_last(buck_bound+1:i-1);
x_par(i-start_itv+1) = x_par(i-start_itv+1) - A(i, i+1:n) * x_last(i+1:n);
x_par(i-start_itv+1) = x_par(i-start_itv+1) / A(i, i);
end
end
完整的代码可以在这里找到:https ://pastebin.com/hRQ5Ugqz
1000x1000
矩阵的 matlab 分析器。并行代码比串行代码慢 20 到 135 倍,具体取决于所选的系数矩阵(并且仍然比 快得多spmd
)。
parfeval 计算可能会懒惰地在第 50 行和第 57 行之间拆分?尽管如此,我还是无法向自己解释为什么会有这么大的开销。这似乎与调用 parfeval 的次数有关:我确实通过降低 parfeval 调用来降低执行时间。
有什么可以进一步优化的吗?我必须求助于用 C++ 编写代码吗?
请帮忙。非常感谢!