主要内容

本页采用了机器翻译。点击此处可查看最新英文版本。

比较多线程和 ProcessPool 的性能

比较函数在客户端和 ProcessPool 上的运行速度。某些 MATLAB® 函数在多核计算机上默认情况下已使用多线程。当有多个线程可用时,使用这些函数的计算比在单个线程上执行得更好。因此,对于其中一个函数的多个计算,在具有计算单线程工作单元的本地并行池上并行执行的性能不会比在客户端的多线程核心上执行更好。并行化带来的开销可能会加剧这种影响。

本示例末尾列出的支持函数 compareClientAndPool 对指定函数进行多次执行:

  • 在客户端上使用单线程

  • 在客户端上使用多个线程

  • 在计算单线程工作单元线程池中的 parfor 循环中

语法类似于 parfeval:使用函数句柄作为第一个参量,输出数量作为第二个参量,然后给出函数所需的所有参量。

首先,创建一个本地 ProcessPool 来消除与启动并行池相关的开销。

p = parpool("Processes");
Starting parallel pool (parpool) using the 'Processes' profile ...
Connected to parallel pool with 6 workers.

使用 eig 支持函数比较 compareClientAndPool 函数的单线程、多线程和池执行时间。使用 @(N) eig(N) 作为函数句柄。

[eigSingle, eigMulti, eigPool] = compareClientAndPool(@(N) eig(N), randn(200));

并行池比客户端计算答案的速度更快。当您将单线程时间与客户端上的多线程时间进行比较时,结果表明,eig 在多线程核心上运行时速度较慢。因此 eig 函数不会从多线程中受益。

通过计算 eigeigMulti 之间的比率来计算在并行池上运行 eigPool 函数的加速比。

eigSpeedup = eigMulti/eigPool
eigSpeedup = 3.7398

eig 函数在池中实现了五倍以上的加速,因为 parfor 在默认单线程的工作单元上并行执行迭代。

接下来,使用 mtimes 支持函数检查 compareClientAndPool 函数的运行速度。

[mtimesSingle, mtimesMulti, mtimesPool] = compareClientAndPool(@(N) N*N, randn(1000));

如果您的本地计算机有四个或更多核心,则并行池通常比客户端更快地计算答案。

当您将单线程时间与客户端上的多线程时间进行比较时,mtimes 在多线程核心上比单线程更快。因此 mtimes 函数受益于多线程。

计算在池上运行 mtimes 函数的加速比。

mtimesSpeedup = mtimesMulti/mtimesPool
mtimesSpeedup = 1.2938

mtimes 函数的加速效果不如 eig 函数,因为在有多个线程可用时 mtimes 函数的性能更佳。

完成计算后,您可以删除当前并行池。

delete(p);
Parallel pool using the 'Processes' profile is shutting down.

定义辅助函数

支持函数 compareClientAndPool 在客户端和当前并行池上执行多项计算。它将函数句柄 fcn 和可变数量的输入参量 (in1, in2, ...) 作为输入。compareClientAndPool 函数在单线程客户端、多线程客户端和活动并行池上执行 fcn(in1, in2, ...)。例如,如果您想测试 rand(500),请使用 compareClientAndPool(fcn,500),其中函数句柄的格式为:

fcn = @(x) rand(x);

function [tSingle, tMulti, tPool, comparePlot] = compareClientAndPool(fcn,in)
xCompThreads = onCleanup(@() maxNumCompThreads("automatic"));

% Use the number of workers in the pool to make the problem size proportional to the number of workers.
numIterations = 40 * gcp().NumWorkers;

% Client - single threaded
maxNumCompThreads(1);
timer = tic();
for i = 1:numIterations
    out = fcn(in);
end
tSingle = toc(timer);

% Client - multithreaded
clear xCompThreads % Sets maxNumCompThreads("automatic")
timer = tic();
for i = 1:numIterations
    out = fcn(in);
end
tMulti = toc(timer);

% Parallel pool
timer = tic();
parfor i = 1:numIterations
    out = fcn(in);  
end
tPool = toc(timer);

% Plot Results
x = categorical({'Single Threaded','Multithreaded','Parallel Pool'});
x = reordercats(x,{'Single Threaded','Multithreaded','Parallel Pool'});
y = [tSingle,tMulti,tPool];
comparePlot = bar(x,y);
xlabel("Execution Environment")
ylabel("Time (s)")
title(strcat("Comparison of ",func2str(fcn)," Execution Times"))
end

另请参阅

主题