gpt4 book ai didi

c - PThreads上下文中的多处理器与多线程

转载 作者:太空狗 更新时间:2023-10-29 15:16:34 24 4
gpt4 key购买 nike

关于硬件的选择及其对软件开发的影响,我有一个应用程序级别(PThreads)问题。

我已经在多核单CPU盒上测试了工作良好的多线程代码。

我正在尝试决定购买我的下一台机器:

  • 6核单CPU盒
  • 4核双CPU盒

  • 我的问题是,如果我选择双CPU盒,这会严重影响代码的移植吗?还是可以分配更多的线程,让操作系统处理其余线程?

    换句话说,在PThreads应用程序的上下文中,多处理器编程与(单CPU)多线程有什么不同吗?

    我以为在这个级别上没有什么区别,但是当配置一个新盒子时,我注意到每个CPU必须购买单独的内存。那是我遇到一些认知失调的时候。

    有关该代码的更多详细信息(对于那些感兴趣的人):我从磁盘上读取了大量数据到巨大的内存块中(不久将达到24GB),然后产生了线程。最初的内存块是“只读的”(由我自己的代码策略强制执行),因此我不对该块进行任何锁定。当我看着4核双CPU盒时,我感到很困惑-它们似乎需要单独的内存。在我的代码上下文中,我不知道如果分配一堆额外的线程会在“幕后”发生什么。操作系统是否会将我的内存块从一个CPU的存储库复制到另一个? 这将影响我必须购买多少内存(增加了此配置的成本)。 理想的情况(从成本上考虑和易于编程)是让双CPU共享一大堆内存,但是如果我理解正确的话,这在新的英特尔双核MOBO上可能是不可能的(例如HP ProLiant ML350e)?

    最佳答案

    现代CPU1在本地处理RAM,并使用单独的channel2在它们之间进行通信。这是NUMA架构的消费者级别版本,是十年前为 super 计算机创建的。

    这样做的目的是避免共享总线(旧的FSB)会导致大量争用,因为每个内核都使用它来访问内存。随着添加更多的NUMA单元,您将获得更高的带宽。缺点是从CPU的角度来看内存变得不均匀:某些RAM比其他RAM快。

    当然,现代的OS调度程序可识别NUMA,因此它们尝试 reduce task 从一个单元到另一个单元的迁移。有时可以在同一插槽中从一个内核转移到另一个内核。有时会有一个整个层次结构,指定哪些资源(1-,2-,3-级缓存,RAM channel ,IO等)被共享,哪些不共享,并且通过移动任务来确定是否要受到惩罚。有时,它可以确定等待正确的内核是没有意义的,最好将整个过程推到另一个套接字上。

    在大多数情况下,最好让调度程序执行其最了解的操作。如果没有,您可以使用numactl玩耍。

    至于给定程序的具体情况;最佳架构在很大程度上取决于线程之间的资源共享级别。如果每个线程都有自己的场所,并且大部分在其中单独工作,那么足够聪明的分配器将为本地RAM分配优先级,从而使每个线程恰好位于哪个单元上的重要性降低。

    另一方面,如果对象是由一个线程分配的,则由另一个线程处理并由第三个线程消耗;如果它们不在同一单元上,则性能会受到影响。您可以尝试创建小线程组并限制组内的繁重共享,然后每个组可以毫无问题地进入不同的单元。

    最坏的情况是所有线程都参与大量的数据共享 Activity 。即使您已对所有锁和进程进行了良好的调试,也没有任何方法可以对其进行优化以使用比单元上可用的内核更多的内核。甚至最好将整个过程限制为仅在单个单元中使用内核,从而浪费其余部分。

    1代表现代,我指的是任何AMD-64位芯片,而Nehalem或对Intel更好的芯片。

    2 AMD将此 channel 称为HyperTransport,Intel名称是QuickPath Interconnect

    编辑:

    您提到您初始化了“一大块只读存储器”。然后产生大量线程来处理它。如果每个线程都在该块的自己部分上工作,那么在生成它之后在线程上对其进行初始化会更好。这将允许线程扩展到几个内核,并且分配器将为每个内核选择本地RAM,这是一种更为有效的布局。也许有某种方法可以暗示调度程序在产生线程后立即将其迁移出去,但是我不知道细节。

    编辑2:

    如果从磁盘上逐字读取数据,而不进行任何处理,则使用mmap而不是分配大块和read()可能是有利的。有一些共同的优点:

  • 无需预分配RAM。
  • mmap操作几乎是瞬时的,您可以开始使用它。数据将根据需要延迟读取。
  • 在应用程序,mmap ed RAM,缓冲区和缓存之间进行选择时,操作系统可能会比您更聪明。
  • 更少的代码!
  • 不需要的数据将不会被读取,不会耗尽RAM。
  • 您可以专门将其标记为只读。任何尝试编写的错误都将导致coredump。
  • 因为操作系统知道它是只读的,所以它不能是“脏的”,因此,如果需要RAM,它将简单地丢弃它,并在需要时重新读取。

  • 但在这种情况下,您还会得到:
  • 由于数据被懒惰地读取,因此,在线程散布在所有可用内核上之后,将选择每个RAM页面。这将使操作系统可以选择接近该过程的页面。

  • 因此,我认为如果两个条件成立:
  • 磁盘和RAM之间没有以任何方式处理数据
  • 数据的每个部分(大部分)是由一个线程读取的,而不是全部都被读取的。

  • 然后,只需使用 mmap,您就应该能够利用任何大小的计算机。

    如果数据的每个部分都被一个以上的线程读取,则也许您可以确定哪些线程(大多数)共享相同的页面,并尝试提示调度程序将这些线程保留在相同的NUMA单元中。

    关于c - PThreads上下文中的多处理器与多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12733640/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com