c++ - std::vector保留并调整NUMA位置的大小

标签 c++ multithreading numa

我目前正在研究优化应用程序的NUMA局部性。
到目前为止,我想我知道内存将驻留在分配后首次接触该NUMA节点上。
关于std::vector(使用默认分配器),我的问题是:

  • std::vector::reserve分配新的内存-但它也可以触及吗?如果没有,我如何在预约电话后强制触摸它?
  • std::vector::resize是否触及内存?
  • 那么采用size_t的构造函数呢?

  • 关于NUMA:
  • 如果已将已被触摸的内存调出到磁盘上,然后再次访问并产生硬故障,那么该操作是否算作新的第一次触摸,或者该页面是否已加载到驻留在最初首先触摸它的numa节点的内存中?
  • 我正在使用c++ 11线程。只要我在线程内并分配/触摸新内存,就可以确定所有这些内存都将驻留在同一numa节点上,或者操作系统执行时操作系统是否可以在线程下切换正在执行的CPU然后我的某些分配将在一个NUMA域中,而其他分配将在另一个域中?
  • 最佳答案

    假设我们在谈论英特尔CPU:在它们的Nahlem老式CPU上,如果您有两个这样的CPU,则有一个开机选项来告诉他们如何在它们之间分配物理内存。物理体系结构是通过QPI连接的两个CPU,每个CPU控制自己的一组内存SIMM。选项是

  • 一个CPU上物理地址空间的前一半,下一个上一半,或者
  • CPU之间的内存页面交替

  • 对于第一种选择,如果您分配了一块内存,它将落到操作系统上,它将从物理地址空间中获取该内存,然后我想一个好的调度程序将努力运行线程以访问CPU上的该内存就是在控制它。对于第二个选项,如果您分配了几页内存,那么将在两个物理CPU之间分配内存,那么调度程序对访问它的线程所做的操作并不重要。我实际上只是短暂地玩了一下,无法真正发现差异。英特尔在QPI方面做得很好。我对较新的Intel体系结构不太熟悉,但是我假设它与以前的体系结构更多。
    另一个问题实际上是NUMA节点是什么意思?如果我们指的是现代的Intel和AMD CPU,它们会向软件提供综合的SMP环境,并使用QPI/Hypertransport(以及现在的现代等效物)之类的东西在NUMA硬件体系结构之上。因此,在讨论NUMA本地性时,实际上是OS调度程序是否在控制线程访问的RAM的CPU上的内核上运行线程(SMP意味着它可以在任何内核上运行,并且仍然可以存取,尽管可能会有微小的延迟差异,但无论在物理内存中的分配位置如何,内存都可以访问)。我不知道答案,但我认为有些人会这样做。当然,我所做的将内核亲和力用于线程和内存的努力仅比让OS(Linux 2.6)做到这一点仅产生了微小的改进。而且,现代CPU上的缓存系统及其与CPU间互连(例如QPI)的交互非常聪明。
    最早可追溯到SMP真正是纯硬件的OS,SMP不知道这样做。
    小兔子洞-如果我们指的是纯NUMA系统(Transputers,PS3及其SPE中的Cell处理器),则线程将在特定内核上运行,并且只能访问该内核的内存;为了访问(通过另一个线程)在另一个内核的内存中分配的数据,该软件必须通过在某些互连上发送数据来对自身进行分类。除非学习,否则很难编写代码,但是结果可能会很快。英特尔花了大约10年的时间才能将Cell处理器与原始处理器相提并论。

    关于c++ - std::vector保留并调整NUMA位置的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63605800/

    相关文章:

    c++ - 在STL堆栈cpp中查找元素

    java - volatile 语句的负载屏障在哪里?

    android - SoundPool.load() 是否设计为异步加载?

    linux - numactl 和 move_pages 不匹配

    c++ - 如何在特定的 NUMA 内存节点上实例化 C++ 对象?

    c++ - 将 char* 返回为字符串文字

    c++ - 为什么非常量引用不能绑定(bind)到临时对象?

    c++ - OpenCV 旋转伪像和点重映射

    java - Elasticsearch 乐观锁定

    c - 在 NUMA 架构中按线程移动内存页