CPU亲和力的优点和缺点

假设我有一个运行在多处理器系统(比如8个内核)上的multithreading应用程序(比如〜40个线程),而Linux作为操作系统,其中不同的线程本质上是由内核调度的LWP(轻量级进程)。

使用CPU亲和力有什么好处/缺点? CPU亲和力是否将通过将线程本地化到核心子集从而最大限度地减lesscaching共享/漏洞来提供帮助?

如果你使用严格的亲缘关系,那么一个特定的线程必须在该处理器(或一组处理器)上运行。 如果你有很多线程完全独​​立运行,而且它们的工作内存大于几千字节,那么在一个特定的内核上运行就不太可能了 – 因为在这个特定的CPU上运行的其他线程很可能会抛出任何一级缓存,也可能是二级缓存。 哪一项对性能更为重要 – 是内容还是“越早跑步”? 有些CPU总是空闲的,或者是CPU在每个内核上的负载都是100%?

然而,只有你知道(直到你告诉我们)你的线程在做什么。 他们每次运行的“工作集”(他们接触多少内存 – 代码和数据)有多大? 每个线程运行多久? 什么是与其他线程的交互? 其他线程是否使用“this”线程共享数据? 共享的模式有多少?

最后,最终的答案是“是什么让它跑得快呢?” – 只有找到好的(现实的)基准并尝试不同的可能选项才能找到答案。 即使你给我们每一行代码,为每个线程运行时间测量等,我们只能做出或多或少的复杂的猜测 – 直到这些已经过尝试和测试(使用VARYING使用模式),几乎是不可能的知道。

一般来说,我认为有很多线程要么建议每个线程不是很忙(CPU的方式),要么就是“做错了”…如果所有的线程都运行的平坦在这种情况下,最好少一些线程,因为他们只是互相争斗。

调度程序已经尝试将线程保持在相同的核心上,并避免迁移。 这表明,手动管理线程关联可能没有太多的里程,除非:

  • 你可以证明,由于某些原因,内核对你的特定应用程序来说是一个糟糕的工作; 要么
  • 有一些关于你的应用程序的具体的知识,你可以利用效果良好。

将线程本地化为核心的子集,从而最小化高速缓存共享/缺失

不一定,你也必须考虑高速缓存一致性,如果两个或更多的线程访问一个共享内存缓冲区,并且每个线程都绑定到一个不同的CPU内核,那么如果一个线程写入共享高速缓存行,它们的高速缓存必须同步,重要的开销来使其他缓存失效。