【问题标题】:How do I SetProcessAffinityMask programmatically in Delphi XE7 for windows 2012 R2如何在 Delphi XE7 for windows 2012 R2 中以编程方式设置ProcessAffinityMask
【发布时间】:2015-07-18 18:46:31
【问题描述】:

我有一个操作系统是 64 位 windows server 2012 R2 的工作站。我正在使用 Delphi XE7 Update 1。工作站有 72 个内核,包括超线程。 我希望我的所有应用程序都在每次运行应用程序时可用的所有内核上运行。我希望以编程方式执行此操作,而不是在任务主机中使用 set affinity(一次仅适用于一个组,并且我有两组我想同时使用的 36 cpu)或从 msconfig 提前设置的引导选项。

我意识到该问题类似于或包含以下已在 Stackoverflow 上提出的问题

Delphi TParallel not using all available cpu

Strange behaviour of TParallel.For default ThreadPool

SetProcessAffinityMask - Select more than one processor?.

我还查看了建议 edn.embarcadero.com/article/27267。

但我的 SetProcessAffinityMask 问题与使用 64 位操作系统的 64 个内核有关,并且不限于使用 TParallel。

我尝试过的解决方案是对 Marco van de Voort 提供的解决方案的改编

   var 
   cpuset  : set of 0..71;
   i: integer;
   begin
   cpuset:=[];
   for i:=0 to 71 do
   cpuset:=cpuset+[i];

   SetProcessAffinityMask(ProcInfo.hProcess, dword(cpuset)); 

   end;

但它不起作用。

如果有任何建议,我将不胜感激。

【问题讨论】:

  • 你不能。拥有超过 64 个处理器,它们将被分成处理器组。您的进程只能使用单个组中的处理器。阅读 msdn 上的处理器组。此外,您必须能够看到 DWORD 只有 32 位。你的进程是 64 位的吗?
  • 我也建议不要使用这样的设置代码。非常依赖于实现细节。对于所有位集,请使用$ffffffffffffffff。用于特定用途的 shl 和 or。
  • @davidHeffernan 我已阅读 msdn 处理器组,它指出“需要使用多个组以便可以在超过 64 个处理器上运行的应用程序必须明确确定在何处运行其线程和负责将线程的处理器亲和性设置为所需的组。” - 所以可以做到。第 2 点 DWORD 是 32 位 64 位等价的 -cardinal 是什么?
  • 你是对的。我的印象是您需要多个流程。您可以拥有多组进程。您采取了哪些步骤将线程分配给不同的处理器组?关于 64 位亲和性,您是否阅读过您正在调用的函数的文档。这就是答案。坦率地说,在询问之前您似乎没有阅读文档,这令人沮丧。我想我也应该更仔细地阅读。
  • @davidheffernan 我确实阅读了 msdn 函数文档和引用 SetThreadAffinityMask 函数的文档。 SetProcessAffinityMask 函数之后的 cmets 似乎给出了相互冲突的视图,并且这些 cmets 是在 windows 提供 windows 2012 R2 之前的 2010 年和 2009 年制作的。因此它们可能不相关或不相关。我正在寻找一些战略性的帮助。在我提出这个问题之前,我没有详细说明我对这个问题的所有研究,但我确信我已经阅读了与处理器组、numa 组和这些文档中列出的众多函数相关的 msdn 文档。

标签: delphi delphi-xe7


【解决方案1】:

正如 cmets 中所讨论的,亲和掩码在 32 位代码中是 32 位,在 64 位代码中是 64 位。您正在尝试设置 72 位掩码。显然这行不通。

您将需要了解 MSDN 上详细介绍的处理器组:Processor Groups,包括指向Supporting Systems That Have More Than 64 Processors 的此链接。

由于您拥有 72 个处理器,因此您将拥有多个处理器组。您需要使用多个进程来访问所有组,或者使用多进程组。来自文档:

线程创建后,可以通过调用SetThreadAffinityMask或SetThreadGroupAffinity来改变它的亲和性。如果将线程分配给与进程不同的组,则更新进程的亲和性以包括线程的亲和性,并且该进程成为多组进程。必须对各个线程进行进一步的关联性更改;不能使用 SetProcessAffinityMask 修改多组进程的亲和性。

这是相当粗糙的东西。如果您可以控制您的线程,那么您应该能够使用SetThreadGroupAffinity 做您需要的事情。如果您使用的是 Delphi 线程库,那么您将无法控制线程。这可能会使单一流程解决方案站不住脚。

另一个需要考虑的问题是内存局部性。如果机器使用 NUMA 内存,那么我知道没有可以很好地使用 NUMA 内存的 Delphi 内存管理器。在 NUMA 环境中,如果性能对您很重要,您可能需要每个线程在线程的 NUMA 节点上分配内存。

这里的底线是,没有简单的快速修复方法可以生成可以有效使用这台机器的所有资源的代码。从我上面链接的文档开始,并进行一些试验,以确保您了解处理器组和 NUMA 的所有含义。

猜你喜欢
  • 2012-10-02
  • 2011-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
  • 2017-10-17
  • 1970-01-01
相关资源
最近更新 更多