2

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

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

但是,我还读到使用(已弃用)函数 maxNumCompThreads(),您可以减少或增加 Matlab 或其中一名工作人员将生成的线程数。这在几种情况下很有用:

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

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

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

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

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

4

3 回答 3

1

这是一个很长的问题,但我认为直截了当的答案是,是的,据我所知,MATLAB 工作人员是从-singleCompThread.

于 2014-10-13T15:38:41.890 回答
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 进程也不会启动比物理内核数更多的线程。所以在文档中,这句话:

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

应该说:

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

于 2014-10-16T23:58:13.383 回答
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

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

不,通过查看在后台运行的本地工作进程,我们看到每个工作进程都以以下方式启动:

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

我相信 undocumented-dmlworker选项的作用类似于-singleCompThread,但可能有点不同。一方面,我能够使用maxNumCompThreads(2)它覆盖它,而不会像以前那样抛出错误..

请记住,即使 MATLAB 会话在单线程计算模式下运行,这并不意味着计算线程仅限于一个 CPU 内核(线程可以在操作系统调度程序分配的内核之间跳转)。如果你想控制它,你必须设置工作进程的亲和性。


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

- 串行模式

我使用了以下代码:eig(rand(500));

  • 正常启动 MATLAB,计算产生 4 个线程(这是默认的自动值,因为我有一个四核 i7 Intel CPU)。
  • 正常启动 MATLAB,但maxNumCompThreads(1)在计算之前调用。正如预期的那样,计算只使用了 1 个线程。
  • 使用选项启动 MATLAB -singleCompThread,再次只使用 1 个线程。

- 并联模式 ( parpool)

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

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

这是 VTune 报告的屏幕截图:

vtune_hotspot_analysis

希望能回答你的问题:)

于 2014-10-13T18:32:47.920 回答