并行处理字符串Delphi完全可用的CPU使用率

Ale*_*lex 10 delphi parallel-processing multithreading delphi-xe6

目标是在单个Delphi应用程序中将浮点数转换为字符串,以实现可用内核的完全使用.我认为这个问题适用于字符串的一般处理.然而在我的例子中,我特意使用FloatToStr方法.

我正在做什么(我保持这个非常简单,所以在实现方面几乎没有含糊之处):

  • 使用Delphi XE6
  • 创建从TThread继承的线程对象,并启动它们.
  • 在线程执行过程中,它将通过FloatToStr方法将大量双精度转换为字符串.
  • 为简化起见,这些双精度数只是相同的常量,因此线程不需要共享或全局内存资源.

虽然使用了多个内核,但CPU使用率%总是最大限度地取决于单个内核的数量.我知道这是一个既定问题.所以我有一些具体的问题.

以简单的方式,可以通过多个应用实例来完成相同的操作,从而实现对可用CPU的更充分利用.是否可以在同一个可执行文件中有效地执行此操作?即在OS级别上分配线程不同的进程ID或OS识别的某些等效分区?或者这是开箱即用的Delphi无法实现的?

在范围上:我知道有不同的内存管理器和其他组已经尝试更改一些较低级别的asm锁使用http://synopse.info/forum/viewtopic.php?id=57 但是,我在问这个问题在如此低的水平上不做事的范围.

谢谢


嗨J.我的代码故意很简单:

TTaskThread = class(TThread)
public
  procedure Execute; override;
end;

procedure TTaskThread.Execute;
var
  i: integer;
begin
  Self.FreeOnTerminate := True;
  for i := 0 to 1000000000 do
    FloatToStr(i*1.31234);
end;

procedure TfrmMain.Button1Click(Sender: TObject);
var
  t1, t2, t3: TTaskThread;
begin
  t1 := TTaskThread.Create(True);
  t2 := TTaskThread.Create(True);
  t3 := TTaskThread.Create(True);
  t1.Start;
  t2.Start;
  t3.Start;
end;
Run Code Online (Sandbox Code Playgroud)

这是一个"测试代码",其中CPU(通过性能监视器)最大值为25%(我有4个内核).如果将FloatToStr线路交换为非字符串操作,例如Power(i,2),则性能监视器会显示预期的75%使用率.(是的,有更好的方法来衡量这一点,但我认为这对于这个问题的范围是足够的)

我已经相当彻底地探讨了这个问题.问题的目的是以非常简单的形式提出问题的关键.

我在询问使用FloatToStr方法时的限制.并且询问是否存在可以更好地使用可用内核的实现化身.

谢谢.

Dav*_*nan 4

我赞同其他人在评论中所说的话。FastMM 内存管理器不可扩展,这是 Delphi 的肮脏小秘密之一。

由于内存管理器可以被替换,因此您可以简单地将 FastMM 替换为可扩展的内存管理器。这是一个快速变化的领域。每隔几个月就会出现新的可扩展内存管理器。问题是很难编写一个正确的可扩展内存管理器。你准备相信什么?FastMM 值得称赞的一件事是它非常强大。

与其更换内存管理器,不如更换需要更换的内存管理器。只需避免堆分配即可。找到一种方法来完成需要重复调​​用来分配动态内存的工作。即使您有一个可扩展的堆管理器,堆分配仍然会产生成本。

一旦您决定避免堆分配,下一个决定就是使用什么来代替FloatToStr. 根据我的经验,Delphi 运行时库不提供太多支持。例如,我最近发现没有好的方法可以使用调用者提供的缓冲区将整数转换为文本。因此,您可能需要推出自己的转换函数。作为证明这一点的简单第一步,请尝试sprintf从调用msvcrt.dll。这将提供概念证明。