gabr42 / OmniThreadLibrary

A simple and powerful multithreading library for Delphi
http://www.omnithreadlibrary.com
Other
461 stars 141 forks source link

AMD 3990X support #155

Open Mike1655 opened 3 years ago

Mike1655 commented 3 years ago

Current 3.07.8 determines the configuration of AMD 3990X incorrectly. This CPU has 64 cores, while the output of a simple test utility is different (see attached). There is another project for CPU architecture detection: https://github.com/Xor-el/NumCPULib4Pascal/blob/master/NumCPULib/src/NumCPULib.pas

`program amd3990X;

{$APPTYPE CONSOLE}

{$R *.res}

uses System.SysUtils, OtlThreadPool, OtlCommon, System.Classes;

procedure OutAffinity( SL: TStringList; const Header: String; Aff: IOmniAffinity ); var NProc: Integer; PhysProc: Integer; strMask: String; Mask: NativeUInt; begin SL.Add(Header); NProc := Aff.Count; PhysProc := Aff.CountPhysical; strMask := Aff.AsString; Mask := Aff.Mask; SL.Add( Format('NProc = %d', [NProc] )); SL.Add( Format('PProc = %d', [PhysProc] )); SL.Add( Format('strMask = %s', [strMask] )); SL.Add( Format('Mask = %x', [Mask] )); SL.Add( '~~~~~~~~~' ); end;

procedure TestAndOutput; var SL: TStringList; i: Integer; begin SL := TStringList.Create; try OutAffinity( SL, '======System.Affinity========', Environment.System.Affinity ); if Assigned(Environment.Process) then OutAffinity( SL, '======Process.Affinity========', Environment.Process.Affinity ); if Assigned(Environment.Thread) then OutAffinity( SL, '======Thread.Affinity========', Environment.Thread.Affinity );

SL.Add( Format( 'NUMA Nodes: %d', [Environment.NUMANodes.Count] ));
for i:=0 to Pred(Environment.NUMANodes.Count) do
begin
  SL.Add( Format( 'NUMA Node[%d] NodeNumber = %d', [i,Environment.NUMANodes.Item[i].NodeNumber] ));
  SL.Add( Format( 'NUMA Node[%d] GroupNumber = %d', [i,Environment.NUMANodes.Item[i].GroupNumber] ));
  SL.Add( Format( 'NUMA Node[%d] Affinity = %x', [i,Environment.NUMANodes.Item[i].Affinity.AsMask] ));
end;
SL.Add( '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' );

SL.Add( Format( 'Environment.Process.PriorityClass: %d', [Ord(Environment.Process.PriorityClass)] ));

SL.Add( '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' );

SL.Add( Format( 'Environment.ProcessorGroups: %d', [Environment.ProcessorGroups.Count] ));
SL.Add( Format('Environment.ProcessorGroups.All as Mask = %x', [Environment.ProcessorGroups.All.AsMask] ));

for i:=0 to Pred(Environment.ProcessorGroups.Count) do
begin
  SL.Add( Format( 'Environment.ProcessorGroup[%d] GroupNumber = %d', [i,Environment.ProcessorGroups.Item[i].GroupNumber]));
  SL.Add( Format( 'Environment.ProcessorGroup[%d] Affinity as Mask = %x', [i,Environment.ProcessorGroups.Item[i].Affinity.AsMask]));
end;
SL.Add( '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' );

finally {$IFDEF WIN64} SL.SaveToFile( 'amd3990x_64.txt' ); {$ELSE} SL.SaveToFile( 'amd3990x_32.txt' ); {$ENDIF} SL.Free; end; end;

begin try { TODO -oUser -cConsole Main : Insert code here } TestAndOutput; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end.`

amd3990x_64.txt

smetz84 commented 3 years ago

I'm also having problems with this type of processors. If I run my programs using OTL on a computer with an 48x AMD Ryzen™ Threadripper™ 3960X 24-core processor, my multithreaded loops hangs indefinitely on the first iteration. The only way to make it work is to turn off the SMT (Simultaneous MultiThreading) option in the BIOS of the computer. Disabling the SMT option decreases the number of available processors from 48 to 24. It seems that OTL cannot manage more than 32 processors.