Matlab:-maxNumCompThreads,超线程和parpool

我在Linux集群中的一个节点上运行了Matlab R2014a,该集群有20个核心并启用了超线程。 我知道这已经被讨论过,但我正在寻求一些澄清。 以下是我对Matlab中线程与内核问题的理解:

  • Matlab具有固有的multithreadingfunction,并将在多核机器上利用额外的内核。
  • Matlab以这种方式运行其线程,即将多个Matlab线程放在同一个核心上(即超线程)是没有用的。 所以默认情况下,Matlab创build的最大线程数就是系统上的内核数量。
  • 在使用parpool()时,无论您创build的worker的数量是多less,每个worker只会使用一个物理核心,就像这个线程中提到的那样。

不过,我也读过使用(不build议使用)的函数maxNumCompThreads(),可以减less或增加Matlab或其中一个worker将生成的线程数。 这可以在几种情况下有用:

  1. 您希望利用Matlab的隐式multithreadingfunction在集群节点上运行一些代码,而无需分配整个节点。 这将是很好,如果有其他的方式来做到这一点,如果maxNumCompThreads被删除。
  2. 您想要执行参数扫描,但参数比机器上的核心数less。 在这种情况下,您可能希望增加每个worker的线程数量,以便使用所有的核心。 这是最近在这个线程中提出的 。 然而,根据我的经验,虽然个体工作者似乎非常乐意使用maxNumCompThreads()来增加线程数量,但使用“top”命令检查实际的CPU使用率表明它没有任何作用,即每个工作者仍然只有得到使用一个核心。 有可能发生的情况是由parpool产生的各个Matlab进程运行参数-singleCompThread。 我已经证实,如果Matlab的父进程运行-singleCompThread,命令maxNumCompThreads(n),其中n> 1抛出一个错误,因为Matlab是在单线程模式下运行的事实。 所以结果似乎是(至less在2014a),你不能增加并行池工作者的计算线程的数量。 与此相关的是,我似乎无法得到父matlab进程来启动更多的线程比核心,即使计算机本身启用超线程。 再次,它会高兴地运行maxNumCompThreads(n),其中n>#个物理内核,但top显示CPU利用率为50%这一事实表明否则。 那么究竟发生了什么,或者我误解了什么?

编辑:更明确地列出我的问题:

  1. 在parfor循环中,当n> 1似乎工作时,为什么不设置maxNumCompThreads(n)? 如果这是因为工作进程是用-singleCompThread启动的,为什么maxNumCompThreads()不像在父进程中用-singleCompThread启动那样返回一个错误呢?
  2. 在父进程中,为什么不使用maxNumCompThreads(n),其中n>#个物理内核做任何事情?

注意:我之前在Matlab上发布过这个答案,但是还没有收到任何反馈。

编辑2:它看起来像(1)中的问题是我正在使用的testing代码的问题。

这是一个相当长的问题,但我认为直接的答案是,是的,据我了解,MATLAB工作人员开始使用-singleCompThread

首先,一些快速测试来确认我们的理解:

> matlab.exe -singleCompThread

 >> warning('off', 'MATLAB:maxNumCompThreads:Deprecated') >> maxNumCompThreads ans = 1 >> maxNumCompThreads(2) Error using feature MATLAB has computational multithreading disabled. To enable multithreading please restart MATLAB without singleCompThread option. Error in maxNumCompThreadsHelper (line 37) Error in maxNumCompThreads (line 27) lastn = maxNumCompThreadsHelper(varargin{:}); 

如上所示,当MATLAB以-singleCompThread选项启动时,我们不能用maxNumCompThreads来覆盖它。

> matlab.exe

 >> parpool(2); % local pool >> spmd, n = maxNumCompThreads, end Lab 1: n = 1 Lab 2: n = 1 

我们可以看到,每个worker默认都被限制在一个计算线程中。 这是一件好事,因为我们希望避免过度订阅和不必要的上下文切换,这是在尝试运行的线程数量超过可用物理/逻辑内核的数量时发生的。 所以从理论上讲,最大限度地提高CPU利用率的最好方法是启动尽可能多的单线程工作者。

否,通过查看本地工作进程在后台运行,我们看到每个启动为:

 matlab.exe -dmlworker -noFigureWindows [...] 

我相信没有记录的-dmlworker选项和-singleCompThread类似,但可能有点不同。 首先,我可以使用maxNumCompThreads(2)覆盖它,而不会引发像以前一样的错误。

请记住,即使MATLAB会话以单线程计算模式运行,也并不意味着计算线程仅限于一个CPU内核(线程可能在OS调度程序分配的内核之间跳转)。 如果要控制工作进程,您必须设置工作进程的关联性。


所以我做了一些使用英特尔VTune放大器分析。 基本上我运行了一些线性代数代码,并通过附加MATLAB过程和mkl.dll模块(这是MATLAB用作优化的BLAS / LAPACK实现的英特尔MKL库)过滤来执行热点分析。 这是我的结果:

– 串行模式

我用了下面的代码: eig(rand(500));

  • 正常情况下启动MATLAB,计算产生4个线程(这是默认的自动值选择,看到我有一个四核i7英特尔CPU)。
  • 正常启动MATLAB,但在计算之前调用maxNumCompThreads(1) 。 如预期的那样,计算仅使用1个线程。
  • 使用-singleCompThread选项启动MATLAB,同样只使用1个线程。

– 并行模式( parpool

我使用了下面的代码: parpool(2); spmd, eig(rand(500)); end parpool(2); spmd, eig(rand(500)); end parpool(2); spmd, eig(rand(500)); end 。 在这两种情况下,MATLAB正常启动

  • 当使用默认设置在worker上运行代码时,每个worker都被限制为一个计算线程
  • 当我使用maxNumCompThreads(2)覆盖worker的设置时,每个worker将使用2个线程

以下是VTune报告的屏幕截图:

vtune_hotspot_analysis

希望回答你的问题:)

我错了maxNumCompThreads不工作parpool工作。 看起来问题是我正在使用的代码:

 parfor j = 1:2 tic maxNumCompThreads(2); workersCompThreads(j) = maxNumCompThreads; i = 1; while toc < 200 a = randn(10^i)*randn(10^i); i = i + 1; end end 

在检查CPU利用率时,使用了太多的内存,瓶颈是I / O,多余的线程已经关闭。 当我做了以下:

 parfor j = 1:2 tic maxNumCompThreads(2); workersCompThreads(j) = maxNumCompThreads; i = 4; while toc < 200 a = randn(10^i)*randn(10^i); end end 

多余的线程开始并保持运行。

至于第二个问题,我得到了Mathworks的确认,即使您明确地提高了极限,那么父Matlab过程将不会启动比物理内核数量更多的线程。 所以在文档中 ,这句话:

“目前,计算线程的最大数量等于您的机器上计算内核的数量。”

应该说:

“目前,计算线程的最大数量等于您机器上物理内核的数量。”