GNU Octave:对数组使用“并行”(将函数应用于每个数组成员)

计算科学 八度
2021-12-10 14:14:24

我是 Linux 上 GNU Octave 6.2.0 的新手,我正在尝试使用“并行”包来使用我机器上的 24 个线程。

我有一个数组 ( array1),它有大约 500,000 行或值(1 列),对于数组的每个成员,我想应用一个 log10 函数,如下所示:

    test = 10*log10(array1.^2); % this works

我尝试像这样使用并行包:

test = pararrayfun(24, @(array1) 10*log10(array1.^2), array1, "Vectorized", 1 "ChunksPerProc", 1); % this fails

但我得到了错误(重复很多次):

Could not save variable
Could not load variable

我还尝试data-smoothing使用并行的跨度 100 将“平滑”函数(从)应用于数组,但这也失败了:

test2 = smooth(array1,100);  % this works fine

test2 = pararrayfun(24, @(array1) smooth(array1,100), array1); % this fails

任何人都可以帮助我正确使用上述两个示例的“并行”语法吗?

非常感谢 !!

1个回答

我无法重现该错误。这是我正在使用的片段:

pkg load parallel

vector_x = rand(500000,1);
tic
vector_y = pararrayfun(nproc, @(x) 10.*log10(x.^2), vector_x, "Vectorized", true, "ChunksPerProc", 1);
toc
tic
vector_y = pararrayfun(1, @(x) 10.*log10(x.^2), vector_x, "Vectorized", true, "ChunksPerProc", 1);
toc
tic
for i=1:length(vector_x)
    vector_y(i) = 10.*log10(vector_x(i).^2);
end
toc
tic
vector_y = 10.*log10(vector_x.^2);
toc

我在鬼混并测试其他一些选项来进行相同的计算并比较每个选项所花费的时间。我对 arrayfun / pararrayfun 有一个哲学问题(如果 for 循环更快,arrayfun 有什么用?),我相信它们是完全多余的,并且它们使 MATLAB/Octave 用户误以为效率。以我的经验,MATLAB 的 JIT 编译器足够智能,可以像我们这里一样对简单的 for 循环进行矢量化。然而,显然 Octave 解释器不够聪明。

我在一台有 64 个线程的机器上,这是计时结果

% pararrayfun using all available threads with ChunksPerProc = 1. Increasing this value 
% (in theory) decreases time on busy machines, but in my case it didn't help.
parcellfun: 64/64 jobs done
Elapsed time is 0.0932262 seconds.

% pararrayfun using 1 thread with ChunksPerProc = 1. Compare against using all the cores. 
% Uses half the amount of time and 1/64th of the cores.
parcellfun: 1/1 jobs done
Elapsed time is 0.0447989 seconds.

% Simple for loop.
Elapsed time is 3.23663 seconds.

% Simple vectorization to let Octave figure out the threading itself. Fastest.
Elapsed time is 0.0195971 seconds.

虽然我无法回答您的问题(因为我无法重现错误),但我建议您不要在这种情况下使用 pararrayfun。此外,我还没有遇到过 arrayfun/pararrayfun 击败简单矢量化(或简单矢量化与 parfor 结合)的单一案例。