将特定线程绑定到特定处理器核心

我在大学里对并行处理有点说,现在我正在努力改进它。 我可以编写可以并行运行的代码,然后启动线程,但之后我放松了对线程执行操作的控制。 我想知道如何控制线程,例如将特定线程绑定到特定处理器核心。

我最感兴趣的是c ++,但我已经用Java编写了一些代码,所以这些答案也很受欢迎。

我正在用Java的角度回答:那是不可能的。 你可以控制的最好的是线程优先级 。 要强制Java在某个CPU /核心上运行,您必须以特定于平台的方式执行此操作。 例如,在Windows中,您可以在任务管理器中执行此操作,方法是在“ 进程”选项卡中找到该进程,右键单击相关进程(通常是java.exe ),选择“ 设置关联性”并勾选CPU /核心。

在此处输入图像描述

正如您可能猜到的那样,这确实是全局设置关联,而不是基于您在Java中创建的线程。

与其他一些受访者的建议相反,对于某些系统(当然是高频率交易,毫无疑问是许多其他非常低延迟的系统,如搜索引擎),将线程绑定到CPU核心(或者用于超线程核心,单个CPU线程)可以带来巨大的性能优势。

天真但越来越被拒绝的观点是增加线程(在合理范围内)增加了这种系统的吞吐量。 然而,越来越多的证据表明, 如果设计得当 ,大多数处理使用极少线程的解决方案可能会大大超过高并发解决方案 – 有时候会超过十,甚至一百。

主要原因是上下文切换。 上下文切换是一个CPU将其当前线程的工作环境刷新到缓存RAM(如果你很幸运)或主RAM(如果你不是),并在工作环境中读取下一个线程的过程 – 它是低延迟系统可以执行的最昂贵的操作之一。

如果您希望最小化低延迟至关重要的上下文切换,某些关键进程最好限制在单个核心或CPU线程。 如果多个线程需要读取或写入由那些关键线程限制进程管理的数据,您可能希望查看“Disruptor”模式,该模式使用环形缓冲区加上一些巧妙的技巧以允许非常快速访问共享数据,同时几乎不需要对该数据进行独占锁定(链接如下)。

要在Java中以独立于操作系统的方式实现线程关联(CPU绑定)任务,您可以使用Peter Lawrey的Java Thread Affinity库,也在下面链接。 还要注意一个例子,其中Peter将读者线程绑定到超线程核心的一个超线程,并将编写器线程绑定到另一个,这个技巧我可以设想具有可观的好处(尽管我没有尝试过)。

巴尼

http://lmax-exchange.github.io/disruptor/

https://github.com/peter-lawrey/Java-Thread-Affinity/wiki/How-it-works

在Windows上,您可以使用SetThreadAffinityMask设置线程的处理器关联。