【问题标题】:Is the memory block allocated by a thread is on the same affinity as the thread itself until the thread exit?线程分配的内存块是否与线程本身具有相同的亲和性,直到线程退出?
【发布时间】:2018-12-10 05:21:54
【问题描述】:

这是一个关于 NUMA 的问题。

例如,在下面的代码中,缓冲区是否在线程/进程的整个生命周期中都分配在本地内存中?

    for (int th = 0; th < maxThreads; th++)
    {
        threads[th] = std::thread([&, th] {
            int* buffer = new int[1000];

            // do something 

            delete []buffer;
        }
    }

更新:为了让问题更直接,让我这样问。如果我有 10 个同时启动的线程(例如,t0 到 t9),并且在每个线程的范围内,它会分配一个内存块(例如,m0 到 m9)。在线程退出之前,线程 t_n 是否总是在 m_n(n 从 0 到 9)上运行,或者线程 0 可能会迁移并在内存 9 上运行?在我的情况下内存块不是很大,通常只有几兆字节。

【问题讨论】:

  • 这将是特定于实现的;你的编译器是什么?
  • 我主要使用 Visual Studio 编译器或 intel 编译器(与 Visual Studio 捆绑)
  • 鉴于您使用的是 Visual Studio,您可能想从这里开始:docs.microsoft.com/en-us/windows/desktop/procthread/…
  • thanks @AndrewHenle 我不知道如何理解第一节末尾关于 VirtualAllocExNuma 的这句话:“如果首选节点用完页面,内存管理器将使用来自其他节点的页面. 如果内存被调出,调回时使用相同的进程。这是否意味着如果内存是从其他节点分配的,那么使用内存的进程也在那个“其他”节点上?

标签: c++ multithreading memory allocation numa


【解决方案1】:

如果你不调用某个函数来告诉它,大多数实现都会“剥离”所有内存,从而减少错误节点内存的成本。

对于任何给定的小分配,这意味着节点基本上是随机的。

"what every programmer should know about memory, part 4"

【讨论】:

  • 那么你是说小内存块是在节点之间随机分配的,即使它是在线程内部分配的?这似乎与我之前所学的相矛盾。例如,这表示“到目前为止,现代操作系统(至少是 Linux,其他可能也是如此)做得很好,默认情况下,内存是从运行线程的 CPU 的同一域分配的(如果可用)”@ 987654322@
  • 那里肯定有相互矛盾的信息……我承认我的信息来源较旧。但是在没有设置关联性的情况下,条带化内存是最佳 解决方案,而且我已经验证了进程确实 经常迁移。当您不得不担心系统上的其他进程时,固定是很困难的。
  • 我同意进程确实经常迁移,因为这正是 set affinity 旨在解决的问题。我在这里问的问题有点不同。我在多线程中询问线程内部,即使在该线程内部分配了内存块,线程/进程也会迁移。也就是说,如果我有 10 个并发线程(例如,t0 到 t9),则在每个线程的范围内,它会分配一个内存块(例如,m0 到 m9)。线程 t_n 会在线程退出之前一直对 m_n(n 从 0 到 9)进行操作,还是如您所说,线程 0 可能会迁移并在内存 9 上操作?
【解决方案2】:

我认为这种行为与操作系统的实现有关,但我相信对于使用 CONFIG_NUMA 选项配置和构建的 Linux,答案是肯定的。

NUMA on Linux

【讨论】:

    猜你喜欢
    • 2017-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-03
    • 2020-04-12
    • 2011-01-15
    • 2012-11-07
    相关资源
    最近更新 更多