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 的同一个内核中运行?

我正在使用德尔福 XE2。

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

4

1 回答 1

10

您只需调用SetThreadAffinityMask将句柄传递给您希望约束的线程,以及目标处理器的处理器掩码。可以使用该Handle属性获取线程的句柄。

当然,您必须了解如何将两个线程放到同一个物理内核上。在超线程机器上,第一个 N/2 个逻辑处理器是物理内核,第二个 N/2 个逻辑处理器是它们的超线程对应物。因此,如果您有一个四核,即 8 个逻辑处理器,您希望将线程放在逻辑处理器 0 和 4、或 1 和 5、或 2 和 6、或 3 和 7 上。

作为一般建议,您应该避免设置硬关联掩码。调度线程很困难,系统通常比你做得更好,因为它可以看到所有线程。你只能看到你的线程。您可以考虑SetThreadIdealProcessor作为替代方案。

于 2013-10-13T13:37:58.130 回答