【问题标题】:Matlab: -maxNumCompThreads, hyperthreading, and parpoolMatlab:-maxNumCompThreads、超线程和 parpool
【发布时间】:2014-10-13 15:06:39
【问题描述】:

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

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

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

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

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

  1. 在 parfor 循环中,为什​​么当 n > 1 时设置 maxNumCompThreads(n) 似乎有效?如果是因为worker进程是用-singleCompThread启动的,为什么maxNumCompThreads()没有像-singleCompThread启动的父进程一样返回错误?
  2. 在父进程中,为什么不使用 maxNumCompThreads(n), where n > # physical cores, 做点什么?

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

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

【问题讨论】:

    标签: linux multithreading matlab slurm


    【解决方案1】:

    这是一个相当长的问题,但我认为直截了当的答案是,是的,据我所知,MATLAB 工作人员以-singleCompThread 开头。

    【讨论】:

    • 抱歉,我进行了编辑以澄清我的问题到底是什么。如果worker真的是用-singleCompThread调用的,maxNumCompThreads不应该抛出错误吗?
    • 对于第一季度 - 好吧,你不知道 maxNumCompThreads 在幕后做了什么(除了调用 p 编码,因此无法读取 maxNumCompThreadsHelper)。也许——而且我认为这几乎可以肯定——它会检查它是在工作程序上运行还是在常规 MATLAB 上运行,并且在每种情况下都会做一些不同的事情,包括不出错。对于第二季度 - 我不知道,但它清楚地记录了它没有做任何事情,我不确定你想要它做什么,或者你为什么想要这样做。拥有比内核更多的线程并没有什么意义。
    • 对于第 2 季度,您的意思是“有文件证明它什么也没做?”你的意思是Matlab不会启动额外的线程或者他们不会帮助?如果是后者,我知道;如果是前者,你介意我指点那个文档吗?
    • 好的 - 看起来文档不像我原来的阅读那么清晰,但它说“目前,计算线程的最大数量等于您机器上的计算核心数量。 "我认为这意味着如果您尝试将其设置为大于内核数,它不会做任何事情。
    • 是的,它说“计算核心”而不是物理或逻辑这一事实使其含糊不清。
    【解决方案2】:

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

    > 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 [...]
    

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

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


    所以我使用英特尔 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都是正常启动的

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

    这是 VTune 报告的屏幕截图:

    希望能回答你的问题:)

    【讨论】:

    • 我在工人身上使用maxNumCompThreads(n) 得到了不同的结果。不管n,我在top 中看到的%CPU 最大值是每个worker 100%,这意味着每个worker 只创建一个线程。你是在 Windows 上测试这个吗?会有区别吗?
    • @Evan:我认为您无法仅通过使用top 来判断计算线程的数量。请记住,无论您设置什么选项,MATLAB 仍然有许多其他线程用于 GUI 和 IO 东西。您需要像我一样使用某种分析器。是的,我在 Windows 8.1 x64 上使用 MATLAB R2014a
    • 嗯,不,不是直接的。但是,在父进程中运行计算密集型代码时,随着我增加maxNumCompThreads,%CPU 每增加一个线程就会增加 100%。 1 个 100%,2 个 200%,20 个 2000%,等等。对于工人来说,总是 100%。
    【解决方案3】:

    我错了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,这句话:

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

    应该说:

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

    【讨论】:

      猜你喜欢
      • 2020-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-05
      • 2012-12-18
      • 1970-01-01
      • 2011-10-09
      相关资源
      最近更新 更多