频道分类

Delphi Win32,Win64用于单/多线程计数素数的整数性能比较

作者:admin 来源: 日期:2020/3/31 9:28:05 人气: 标签:

 
DELPHI代码测试素数
我们已经看到了用于测试给定整数是否为质数的代码:
function IsPrime(x: Integer): Integer;
var
  i, q: integer;
begin
  if (x <= 1) then
  begin
    Exit(0);
  end;
  q := Floor(Sqrt(x));
  for i := 2 to q do
  begin
    if (x mod i = 0) then
    begin
      Exit(0);
    end;
  end;
  Exit(1);
end;

注意,有更快的素数测试算法,但是这里我们要比较不同类型的二进制文件(相同的代码库)之间的整体整数性能,因此,算法部分不是我们的重点。

如何在DELPHI中计时代码?
我们可以使用Win32 API GetTickCount,但是它在Windows Unit中,因此不能移植到Linux平台。相反,我们可以使用TThread.GetTickCount这是一个静态方法,该方法返回自操作系统启动以来的滴答声数量。

因此计时部分是这样的:

starttime:= TThread.GetTickCount; 
//一些繁重的计算
Writeln(TThread.GetTickCount-starttime);
如何在DELPHI中计算1到N之间的素数?
我们将在3个目标平台Win32,Win64和Linux64上测试2个版本(单线程和多线程)。

单线程DELPHI版本
计算从1到N的质数个数的单线程版本既简单又直接:
s := 0;
for i := 1 to MAXN do
begin
  Inc(s, IsPrime(i));
end;
Writeln(s);

并行版本
并行版本可能有所不同。我们在这里的方法是将数字范围递归地分为两半。使用ITask可以同时计算每一半。如果范围小于例如500个数字,则我们进行串行for循环,通常认为它效率更高。
function Test(left, right: Integer): Integer;
var
  i, mid, lefts, rights: Integer;
  job_left, job_right: ITask;
begin
  if (right - left <= 500) then
  begin // count the answer in this small range
    Result := 0;
    for i := left to right do
    begin
      Inc(Result, IsPrime(i));
    end;
  end
  else // recursively divide into two halves.
  begin
    mid := left + (right - left) div 2; // avoid integer overflow
    lefts := 0;
    rights := 0;
    job_left := TTask.Create( // left range
      procedure()
      begin
        lefts := Test(left, mid); // get the answer of left range.
      end
    );
    job_right := TTask.Create( // right range
      procedure()
      begin
        rights := Test(mid + 1, right); // get the answer for right range.
      end
    );
    job_left.Start; // start this job 
    job_right.Start;  // start this job
    TTask.WaitForAll([job_left, job_right]); // wait for both
    Result := lefts + rights; // sum both parts
  end;
end;
绩效结果
上面的Delphi代码(相同的代码,但编译为3种不同目标平台的RELEASE版本:Win32,Win64和Linux64)的计时(滴答声,更小,更快):

Win32单线程:4797与Win32并行版本:1437
Win64单线程:4296与Win64并行版本:1578
Win32单线程:10252与Win32并行版本:2226
对于并行版本(使用Delphi Task并行库),Win32的运行速度比64位版本略快。对于单线程版本,Win64的运行比32位版本略。

我们在Windows 10中使用Linux子系统,但运行速度稍慢,但在真正的本机64位Linux服务器中可能并非如此。但是,此处介绍的性能比较是相当合理的,因为它们在完全相同的PC上运行:ThinkCenter M900(高达4GHz的Intel i7-6700四核),32GB DDR4 2133MHz和OS是Win10 64位。


来源https://helloacm.com/integer-performance-comparisons-of-delphi-win32-win64-and-linux64-for-singlemultithreading-counting-prime-number/