Delphi 如何将应用程序分配给特定NUMA节点?

Delphi 如何将应用程序分配给特定NUMA节点?,delphi,Delphi,以下代码仅允许更改当前NUMA节点中的关联。是否有一个函数允许我同时指定NUMA节点?我宁愿避免像start/NODE 3/AFFINITY 1 program.exe这样的外部解决方案 procedure TForm1.FormCreate(Sender: TObject); var AffinityMask:Cardinal; begin AffinityMask:=1; SetProcessAffinityMask(GetCurrentProcess(),AffinityM

以下代码仅允许更改当前NUMA节点中的关联。是否有一个函数允许我同时指定NUMA节点?我宁愿避免像
start/NODE 3/AFFINITY 1 program.exe这样的外部解决方案

procedure TForm1.FormCreate(Sender: TObject);
var AffinityMask:Cardinal;
begin    
  AffinityMask:=1;
  SetProcessAffinityMask(GetCurrentProcess(),AffinityMask);
end;

这在Microsoft的文档中有介绍:

首先,您需要确定系统中节点的布局。要检索系统中编号最高的节点,请使用
GetNumaHighestNodeNumber
功能。请注意,此数目不能保证等于系统中的节点总数。此外,具有序列号的节点不能保证靠得很近。要检索系统上的处理器列表,请使用
GetProcessAffinityMask
函数。您可以使用
GetNumaProcessorNode
函数确定列表中每个处理器的节点。或者,要检索节点中所有处理器的列表,请使用
GetNumaNodeProcessorMask
函数

确定哪些处理器属于哪些节点后,可以优化应用程序的性能为确保进程的所有线程都在同一节点上运行,请使用带有进程关联掩码的
SetProcessAffinityMask
函数,该掩码指定同一节点中的处理器。
这将提高线程需要访问同一内存的应用程序的效率。或者,要限制每个节点上的线程数,请使用
SetThreadAffinityMask
函数


这在Microsoft的文档中有介绍:

首先,您需要确定系统中节点的布局。要检索系统中编号最高的节点,请使用
GetNumaHighestNodeNumber
功能。请注意,此数目不能保证等于系统中的节点总数。此外,具有序列号的节点不能保证靠得很近。要检索系统上的处理器列表,请使用
GetProcessAffinityMask
函数。您可以使用
GetNumaProcessorNode
函数确定列表中每个处理器的节点。或者,要检索节点中所有处理器的列表,请使用
GetNumaNodeProcessorMask
函数

确定哪些处理器属于哪些节点后,可以优化应用程序的性能为确保进程的所有线程都在同一节点上运行,请使用带有进程关联掩码的
SetProcessAffinityMask
函数,该掩码指定同一节点中的处理器。
这将提高线程需要访问同一内存的应用程序的效率。或者,要限制每个节点上的线程数,请使用
SetThreadAffinityMask
函数


似乎有一个名为NtSetInformationProcess的未记录函数

我发现了一个有趣的API,这正是我想要的

这里的目标是做与SetProcessAffinityMask()相同的事情 与小组合作。事实证明,有这样一个函数,但它是 无证的

我发现NtSetProcessInformation()将设置组和 和已运行进程的关联掩码。它是API 大概是这样的:

组亲和力组亲和力

group_affinity.group=1;//第二组64个处理器

group_affinity.mask=0x0000FFFF00000000

NtSetProcessInformation(hProcess、0x15和组\u关联、, 组(亲和力大小)

它工作得非常好,与TaskManager用于更改的API相同 进程的关联组和掩码

当然,由于它是无文件记录的,它可能会发生变化,所以它是 最好不要在零售软件中使用此功能。我用它只是为了跑步 性能测试在我们的实验室,所以这里没有大问题

下面是我将代码翻译成Delphi7的尝试。将进程分配给第一个NUMA节点上的第一个cpu

function NtSetInformationProcess(HProcess: CARDINAL; ProcessInformationClass: BYTE; ProcessInformation: POINTER; ProcessInformationLength: CARDINAL): CARDINAL; stdcall; external 'ntdll.dll' name 'NtSetInformationProcess';

type
   TGROUP_AFFINITY = record
     group  : WORD;
     mask   : cardinal;
     Reserved: array [0..2] of WORD;
   end; 

procedure TForm1.FormCreate(Sender: TObject);
var group_affinity:TGROUP_AFFINITY;
    HRES: HRESULT;
begin

  group_affinity.group:= 0;
  group_affinity.mask:= 1;
  HRES:=NtSetInformationProcess(GetCurrentProcess(), $15 , @group_affinity, SizeOf(group_affinity));

  if HRES = S_OK then showmessage('OK') else showmessage('ERROR'); 

end; 
编辑:现在它可以工作了<代码>保留:字的数组[0..2]在定义中缺失,
组:单词必须是而不是
组:基数

\u组\u亲缘结构

NtSetProcessInformation文档
似乎有一个名为NtSetInformationProcess的未记录函数

我发现了一个有趣的API,这正是我想要的

这里的目标是做与SetProcessAffinityMask()相同的事情 与小组合作。事实证明,有这样一个函数,但它是 无证的

我发现NtSetProcessInformation()将设置组和 和已运行进程的关联掩码。它是API 大概是这样的:

组亲和力组亲和力

group_affinity.group=1;//第二组64个处理器

group_affinity.mask=0x0000FFFF00000000

NtSetProcessInformation(hProcess、0x15和组\u关联、, 组(亲和力大小)

它工作得非常好,与TaskManager用于更改的API相同 进程的关联组和掩码

当然,由于它是无文件记录的,它可能会发生变化,所以它是 最好不要在零售软件中使用此功能。我用它只是为了跑步 性能测试在我们的实验室,所以这里没有大问题

下面是我将代码翻译成Delphi7的尝试。将进程分配给第一个NUMA节点上的第一个cpu

function NtSetInformationProcess(HProcess: CARDINAL; ProcessInformationClass: BYTE; ProcessInformation: POINTER; ProcessInformationLength: CARDINAL): CARDINAL; stdcall; external 'ntdll.dll' name 'NtSetInformationProcess';

type
   TGROUP_AFFINITY = record
     group  : WORD;
     mask   : cardinal;
     Reserved: array [0..2] of WORD;
   end; 

procedure TForm1.FormCreate(Sender: TObject);
var group_affinity:TGROUP_AFFINITY;
    HRES: HRESULT;
begin

  group_affinity.group:= 0;
  group_affinity.mask:= 1;
  HRES:=NtSetInformationProcess(GetCurrentProcess(), $15 , @group_affinity, SizeOf(group_affinity));

  if HRES = S_OK then showmessage('OK') else showmessage('ERROR'); 

end; 
编辑:现在它可以工作了<代码>保留:字的数组[0..2]在定义中缺失,
组:单词必须是而不是
组:基数

\u组\u亲缘结构

NtSetProcessInformation文档

你想要的东西