为什么arrayfun只用单核?

Why does arrayfun only use a single core?

我试着估计一下

% matlabpool open 2; % line 1
tic; arrayfun(@(x) sum(sum(rand(1000))), [1 : 100]); toc;
Elapsed time is 4.070030 seconds.

当我取消注释第一行以便创建一个包含 2 个工作人员的池时,我得到了相同的时间结果。

为什么一些明显的系统函数不能自动以并行模式执行? 当我们得到并行时,Matlab 是否有任何类似于 GPU 的 arrayfun 函数 运行?

在调用 arrayfun 之前调用 matlabpool 没有得到任何速度提升的原因是仅仅创建多个 worker 的行为并不能使 all 代码利用这些工人来执行计算。如果您想利用工作人员池,您需要使用 parfor (related info ).

显式并行化您的代码
parfor k = 1:10
    result{k} = sum(sum(a*b));
end 

一般来说,arrayfun 不会 进行任何并行化或加速。事实上,它通常比简单地写出 for 循环要慢,因为显式 for 循环允许更好的 JIT 加速。

for k = 1:10
    result(k) = sum(sum(a * b));
end

如果您想使用 GPU 执行您展示的操作,如果 arrayfun 的输入数据是 gpuarray,那么它将在 GPU 上执行(使用 distributed version of arrayfun).但问题是,使用 arrayfun 在 GPU 上执行的任何操作都必须 只是 element-wise 操作,以便每个元素上的操作独立于所有元素上的操作其他元素(使其可并行化)。在您的情况下,它是 而不是 element-wise 操作,因此无法使用 arrayfun 的 GPU-version。

作为 side-note,您需要使用 parpool 而不是 matlabpool,因为后者已被弃用。

核心 MATLAB 确实使用线程和矢量运算,但您必须自己对代码进行矢量化。例如,对于您的示例,您需要编写

A = rand(1000, 1000, 100);
B = sum( sum( A, 1 ), 2 );

B 现在是一个 1×1×100 的求和数组。我使用了两个求和来帮助您了解发生了什么,如果您 实际上 想对矩阵中的每个数字求和 sum(A(:)),或者对于这个批处理示例, sum( reshape(A, [], 100) ).

对于任务并行性而不是数据并行性,请使用 parforbatchparfeval 或其他一些并行指令。