【问题标题】:Delphi OTL Why does MultiThreading program uses only half the available CPU's [duplicate]Delphi OTL为什么多线程程序只使用可用CPU的一半[重复]
【发布时间】:2014-11-06 18:30:34
【问题描述】:

在执行我的多线程程序期间,仅使用了 8 个可用 CPU 中的 4 个。为什么? 我可以更改什么以使所有 CPU 正常工作?

  Parallel.ForEach(0, CalcList.Count-1)
  .NumTasks(nMax)
  .NoWait
  .Execute(
    procedure(const value: integer)
    begin
      CalcUnit.EntrySearch(value);
    end);

(nMax 和 CalcList.Count 均为 16,Intel I7 超线程)

谢谢

【问题讨论】:

  • FWIW 超线程对于 cpu 绑定任务没有太大帮助。
  • OTL 中是否没有允许您将 OTL 限制为仅使用物理内核而不使用虚拟内核的选项?
  • @SilverWarior OP 正在谈论 8 个内核(16 个超线程),但只有 4 个内核被使用。虽然检查 CPU 是否真的有 4 个或 8 个内核可能是件好事。
  • 请听我们的。如果您的工作受 I/O 限制,那么投入更多 CPU 将无济于事,而且很可能只会让您的程序变慢。
  • @FritsMolenkamp 如果由于 IO 瓶颈而不需要它们,操作系统不会费心为您的程序提供所有 8 个 CPU。

标签: multithreading delphi omnithreadlibrary


【解决方案1】:

我刚刚使用 OTL 在 i7 2600(4 核 8 HT)上进行了测试。一个简单的Parallel.ForEach 循环利用了所有 8 个。有和没有你拥有的 .NumTasks。库没有问题。

begin
  Parallel.ForEach(0, 100)
  //.NumTasks(16)
  .Execute(
    procedure(const value: integer)
    var
      newValue: Single;
      I: Integer;
    begin
      newValue := value;
      for I := 1 to 100000000 do
      begin
        newValue := newValue * I;
        newValue := newValue / I;
      end;
    end);
  ShowMessage('Done!');
end;

我的猜测是问题出在您的代码中。线程中的磁盘访问是首先抵消使用线程的好处的好方法。

我对您的代码知之甚少,但您应该考虑在单个线程中读取数据,然后线程化该数据的实际处理。

我看到您还指定了 .NoWait。您是否正在为您的Parallel.ForEach 保存返回值?保存此值是个好主意,否则您的代码将在 OnClick 退出时阻塞。请参阅 gabr 对此问题的回答。

Why is OmniThreadLibrary's ForEach blocking main thread?

【讨论】:

  • 感谢您的 cmets 和代码。在我的代码中删除 .NumTasks(nMAx) 会减慢我的 CPU 使用率。是的,问题出在我的代码中,您的代码示例使我所有的 8 个 CPU 都运行 100%。我确实在尝试对“旧”单线程数据计算进行多线程处理。感谢以前的 cmets,我正在尝试了解更多有关 I/O 瓶颈的信息。再次感谢
猜你喜欢
  • 1970-01-01
  • 2012-02-20
  • 1970-01-01
  • 1970-01-01
  • 2013-10-17
  • 1970-01-01
  • 1970-01-01
  • 2013-08-30
  • 1970-01-01
相关资源
最近更新 更多