如果您同时生成多个线程(或进程),最好是生成物理处理器的数量或逻辑处理器的数量,假设任务受CPU约束?或者最好在两者之间做一些事情(例如,3个线程)?
性能是否取决于正在执行的指令类型(例如,非本地内存访问是否会与缓存命中有很大不同)?如果是这样,在哪种情况下最好利用超线程?
更新
我问的原因是,我记得在某个地方读过,如果你的任务数与虚拟处理器的数量一样多,那么同一物理内核上的任务有时会使某些CPU资源匮乏并阻止彼此获得尽可能多的资源根据需要,可能会降低性能。这就是为什么我想知道是否拥有与虚拟内核一样多的线程是一个好主意。
答案 0 :(得分:5)
表现取决于多种因素。大多数任务都不是严格的CPU限制,因为即使所有数据都在内存中,它通常也不在处理器缓存中。我见过一些示例(如this one),其中内存访问模式可以显着改变给定“并行”进程的性能配置文件。
简而言之,对于所有情况都没有完美的数字。
答案 1 :(得分:4)
如果启用了HyperThreading,您将看到每个核心运行2个线程的性能提升非常好。 出现完全由CPU绑定的作业通常不是,并且HyperThreading可以从偶尔的中断或上下文切换中提取一些“额外”周期。
另一方面,对于具有Turbo Boost的核心iX处理器,您实际上可以更好地为每个核心运行1个线程以鼓励CPU自行超频。
在工作中,我们经常在全CPU运行多核服务器,一次进行几天的各种计算。不久前,我们测量了有无HT的性能差异。我们发现,平均而言,使用HyperThreading,并且一次运行两倍的作业,我们可以完成相同数量的作业,比没有HyperThreading快10%。
假设2×核心是一个很好的起点,但最重要的是:测量!
答案 2 :(得分:2)
我记得有关超线程可以为您带来高达30%的性能提升的信息。通常,您最好将它们视为4个不同的核心。当然,在某些特定情况下(例如,将相同的长时间运行任务绑定到每个核心),您可以更好地划分处理,同时考虑到某些核心只是逻辑核心
有关超线程自身的更多信息here
答案 3 :(得分:2)
使用超线程在同一内核上运行两个线程,当两个线程具有相似的内存访问模式但访问不相交的数据结构时,将大致相当于在两个独立的内核上运行它们,每个内核都有一半的缓存。如果内存访问模式使得缓存的一半足以防止颠簸,则性能可能是好的。如果内存访问模式使得缓存减半会导致颠簸,那么可能会有十倍的性能损失(这意味着如果没有超线程,那将会好得多)。
另一方面,在某些情况下,超线程可能是一个巨大的胜利。如果许多线程都将使用无锁数据结构读取和写入相同的共享数据,并且所有线程必须看到数据的一致视图,则尝试在不相交的处理器上运行线程可能会导致抖动,因为一次只有一个处理器可能具有对任何给定缓存行的读写访问权限;在两个核上运行这样的线程可能比一次只运行一个线程花费更长的时间。但是,当一个数据由单个核心上的多个线程访问时,不需要这种高速缓存仲裁。在这些情况下,超线程可以是一个巨大的胜利。
不幸的是,我不知道如何给调度程序任何提示"提示"建议某些线程尽可能共享核心,而其他线程应尽可能单独运行。
答案 4 :(得分:1)
对于使用额外虚拟核心的主要 cpu绑定任务,HT允许大约10-30%的提升。虽然这些任务可能看起来像CPU,但除非它们是自定义程序集,否则它们通常会受到RAM和本地缓存之间IO等待的影响。这允许在物理HT启用的核心上运行的一个线程在另一个线程等待IO时工作。这确实有一个缺点,因为两个线程共享相同的缓存/总线,这将导致每个资源减少,这可能导致两个线程在等待IO时暂停。
在最后一种情况下,运行单个线程将降低最大同时理论处理能力(降低10-30%),有利于运行单个线程而不会降低高速缓存抖动,这在某些应用程序中可能非常重要。 / p>
选择要使用的核心与选择要运行的线程数一样重要。如果每个线程在大约相同的持续时间内受CPU限制,则最好设置亲和性,使得使用大多数不同资源的线程发现自己位于不同的物理核心上,使用公共资源的线程被分组到相同的物理核心(不同的虚拟核心),因此可以在没有额外IO等待的情况下从同一个缓存中使用公共资源。
由于每个程序具有不同的CPU使用特性,并且缓存颠簸可能会或可能不会是主要的减速(通常是这样),因此如果不首先进行分析,就无法确定理想的线程数。最后要注意的是OS / Kernel还需要一些CPU和缓存空间。如果在CPU绑定线程上需要实时延迟以便避免共享缓存/ cpu资源,通常理想的是为操作系统保留单个(物理)核心。如果线程经常等待IO并且缓存抖动不是问题,或者如果运行专为应用程序设计的实时操作系统,则可以跳过最后一步。
http://en.wikipedia.org/wiki/Thrashing_(computer_science) http://en.wikipedia.org/wiki/Processor_affinity
答案 5 :(得分:0)
所有其他答案已经提供了很多优秀的信息。但是,需要考虑的另一点是SIMD单元在同一芯片上的逻辑内核之间共享。那么,如果你运行带有SSE代码的线程,你是在所有4个逻辑内核上运行它们,还是只生成2个线程(假设你有两个芯片)?对于这种奇怪的情况,最好使用您的应用进行分析。