有没有一种方法可以强制两个线程在同一个核心上执行?

4
我有一个处理大量数据的应用程序。
当工作集超过L2(L3)缓存时,性能会急剧下降。
我想通过预取数据来解决部分问题。
我想利用多线程代码在超线程CPU上运行时共享核心和缓存的事实。
第一个线程(A)是工作线程。
第二个线程(B)预取数据。
如果我可以强制两个线程在同一个核心上执行,我就可以让线程(B)先行运行并获取数据。
以下是伪代码示例。
procedure TWorkerThread.Execute;
begin
  Node:= WalkTheDataTree.GetNode;  
  Dowork(Node.MyData);
  SyncWithThreadB;
end; 

procedure TFetchThread.Execute;
begin
  WaitForThreadA; 
  Node:= WalkTheDataTree_5_nodes_Ahead_of_A.GetNode;  //Prefetch data.
end;

两个线程同时执行,工作线程全速运行,获取线程等待信号。

有没有办法在超线程CPU上强制两个线程在同一个核心上运行?

我正在使用Delphi XE2。

P.S. 我知道如何使用CPUID指令检测CPU是否支持超线程。


我对这个很感兴趣,但不想将亲和力硬性设置到特定的核心上。我想要告诉内核,在任何核心上调度ThreadA和ThreadB,只要确保它们在同一个核心上即可。 - ahcox
1个回答

10
您只需调用SetThreadAffinityMask,传递要限制的线程句柄和目标处理器的处理器掩码。可以使用Handle属性获取线程句柄。
当然,您需要了解如何将两个线程放到同一个物理核心上。在超线程机器上,前N/2个逻辑处理器是物理核心,后N/2个逻辑处理器是它们的超线程对应物。因此,如果您有四核心,即8个逻辑处理器,则希望将您的线程放置在逻辑处理器0和4、1和5、2和6或3和7上。
作为一般建议,应避免设置硬亲和力掩码。调度线程很难,并且系统通常比您做得更好,因为它可以看到所有线程。您只能看到您的线程。您可以考虑SetThreadIdealProcessor作为替代方案。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接