Matlab:-maxNumCompThreads,超线程和parpool

时间:2014-10-13 15:06:40

标签: linux multithreading matlab slurm

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

  • Matlab具有固有的多线程功能,并将在多核机器上使用额外的内核。
  • Matlab以这样一种方式运行它的线程,即将多个Matlab线程放在同一个核心上(即超线程)并不是很有用。因此,默认情况下,Matlab将创建的最大线程数是系统中的核心数。
  • 使用parpool()时,无论您创建的工作者数量如何,每个工作人员将只使用一个物理核心,如this thread中所述。

但是,我还读过使用(不推荐使用的)函数maxNumCompThreads(),您可以减少或增加Matlab或其中一个工作人员将生成的线程数。这在以下几种情况下非常有用:

  1. 您希望利用Matlab的隐式多线程功能在群集节点上运行某些代码,而无需分配整个节点。如果有一些其他方法可以执行此操作,如果maxNumCompThreads被删除,那将是很好的。
  2. 您希望进行参数扫描,但参数少于计算机上的核心数。在这种情况下,您可能希望增加每个工作线程的线程数,以便使用所有核心。最近在this thread中提出了这一点。但是,根据我的经验,虽然各个工作人员似乎很乐意使用maxNumCompThreads()来增加其线程数,但使用" top"来检查实际的CPU使用情况。命令表明它没有任何效果,即每个工作者仍然只能使用一个核心。发生的事情可能是由parpool生成的各个Matlab进程使用参数-singleCompThread运行。我已经确认,如果使用-singleCompThread运行父Matlab进程,则命令maxNumCompThreads(n),其中n>由于Matlab以单线程模式运行,因此1会引发错误。所以结果似乎是(至少在2014a),你不能增加并行池工作者的计算线程数。与此相关的是,即使计算机本身启用了超线程,我似乎无法使用父matlab进程来启动比核心更多的线程。同样,它将愉快地运行maxNumCompThreads(n),其中n> #pome核心,但顶部显示CPU利用率为50%这一事实表明不然。那么发生了什么,或者我误解了什么?
  3. 编辑:更明确地阐述我的问题:

    1. 在parfor循环中,为什​​么不设置maxNumCompThreads(n),当n> 1似乎工作?如果是因为工作进程是用-singleCompThread启动的,为什么maxNumCompThreads()不会像在使用-singleCompThread启动的父进程中那样返回错误?
    2. 在父进程中,为什么不使用maxNumCompThreads(n),其中n> #phys cores,做点什么?
    3. 注意:我之前在Matlab的答案中发布了这个,但没有收到任何反馈。

      Edit2:看起来(1)中的问题是我使用的测试代码的问题。

3 个答案:

答案 0 :(得分:1)

这是一个相当长的问题,但我认为直截了当的答案是肯定的,正如我所理解的那样,MATLAB工作者以-singleCompThread开始。

答案 1 :(得分:1)

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

> 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{:}); 

如上所述,当使用-singleCompThread选项启动MATLAB时,我们无法使用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 Intel CPU)。
  • 正常启动MATLAB,但在计算之前调用maxNumCompThreads(1)。正如预期的那样,计算只使用了1个线程。
  • 使用-singleCompThread选项启动MATLAB,再次只使用1个线程。

- 并行模式(parpool

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

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

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

vtune_hotspot_analysis

希望能回答你的问题:)

答案 2 :(得分:1)

我错误地认为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进程不会启动比物理核心数更多的线程,即使你明确提高了超出限制的数量。所以在documentation中,句子是:

&#34;目前,最大计算线程数等于计算机上的计算核心数。&#34;

应该说:

&#34;目前,计算线程的最大数量等于计算机上物理核心的数量。&#34;