繁体   English   中英

在多核机器上进行多线程处理而不是最大化CPU

[英]Multithreading on a multi core machines not maxing CPU

我正在通过两种方法维护使用多线程的其他人的代码:

1: ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf ReadData), objUpdateItem)

2: Dim aThread As New Thread(AddressOf LoadCache)
   aThread.Start()

但是,在双核机器上,我只获得50%的CPU使用率,而在具有超线程启用机器的双核上,我只获得25%的CPU利用率。

显然线程非常复杂,但这种行为似乎表明我不理解一些简单的基本事实?

UPDATE

遗憾的是,这里的代码非常复杂,但是出于参考目的,这里大致会发生什么......我有大约500个帐户,其数据从数据库加载到内存缓存中......每个帐户都单独加载,该进程首先调用一个长时间运行的存储过程,然后对返回的数据进行操作和缓存。 因此,在这种情况下线程化的关键是确实存在一个瓶颈命中数据库(即:线程将被闲置最多30秒等待查询返回),因此我们通过线程允许其他人开始处理他们从Oracle收到的数据。

所以,主线程执行:

ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf ReadData), objUpdateItem) 

然后,ReadData()然后继续执行(恰好一次):

Dim aThread As New Thread(AddressOf LoadCache)
aThread.Start()

这是在递归函数中发生的,因此QueueUserWorkItem可以多次执行,然后通过aThread.Start执行恰好一个新线程

希望这可以很好地了解事情的发生方式。

那么,在这种情况下,理论上这不应该固定两个核心,而不是在一个核心上达到100%,而另一个核心基本上是空闲的吗?

该代码启动一个将执行某些操作的线程。 要获得多个核心工作,您需要启动多个线程并使它们都忙碌。 启动一个线程做一些工作,然后让你的主线程等待它将不会更快地完成任务。 通常在后台线程上启动一个长时间运行的任务,以便UI保持响应,这可能是此代码的目的,但它不会使任务更快地完成。

@Judah Himango - 我假设这两行代码是程序中两个不同位置如何实现多线程的样本。 也许OP可以澄清是否是这种情况,或者这两条线是否真的在一种方法中。 如果它们是一种方法的一部分,那么我们需要看看这两种方法实际上在做什么。

更新:
这听起来似乎应该最大化两个核心。 通过递归调用ReadData()是什么意思? 如果每个新线程仅在其末尾或其附近调用ReadData以启动下一个线程,那么这可以解释您所看到的行为。
我不确定这是一个好主意。 如果存储的proc需要30秒才能获得数据,那么可能是它在数据库服务器上放置了一个公平的负载。 并行运行500次只会让事情变得更糟。 显然我不知道你的数据库或数据,但我会考虑提高存储过程的性能。
如果多线程确实看起来像前进的方式,那么我将在主线程上有一个循环,为需要加载的每个帐户调用一次ThreadPool.QueueUserWorkItem。 我也会删除显式线程创建,只使用线程池。 这样,您就不太可能通过创建太多线程来使本地计算机饿死。

你旋转了多少个线程? 它可能看起来很原始(等待几年,你不再需要这样做了),但是你的代码必须弄清楚要启动的最佳线程数,然后调整那么多。 简单地运行单个线程不会使事情变得更快,并且不会固定物理处理器,尽管它可能有其他原因(例如,工作者线程保持UI响应)。

在许多情况下,您将希望运行多个线程,这些线程等于您可用的逻辑核心数(我相信可以从Environment.ProcessorCount获得),但它可能还有其他一些基础。 例如,当我受到远程进程延迟的约束时,我已经启动了几十个线程,与不同的主机通信。

多线程和多核是两回事。 做多线程经常不会为你提供巨大的性能提升,有时恰恰相反。 操作系统可能会做一些技巧来将您的CPU周期分散到多个核心上,但这就是它结束的地方。

您正在寻找的是Parallelism。 .NET 4.0框架将添加许多新功能来支持Parallelism。 在这里有一个潜行高峰:
http://www.danielmoth.com/Blog/2009/01/parallelising-loops-in-net-4.html

CPU行为将指示应用程序仅使用一个逻辑处理器。 50%将是2个中的一个proc(proc + proc)。 25%将是4个中的一个逻辑处理器(proc + HT + proc + HT)

你有多少个线程,你在LoadCache中有任何锁定。 SyncLock可以将多线程系统充当单线程(按设计)。 此外,如果您的唯一假脱机一个线程,您将只获得一个工作线程。

CPU利用率表明您只使用一个核心; 这可能表明你已经添加了线程到一个没有益处的部分(在这种情况下,CPU时间不是瓶颈)。

如果加载缓存或读取数据发生得非常快,多线程将无法在速度性能方面带来巨大改进。 同样,如果您遇到不同的瓶颈(服务器的带宽缓慢等),它可能不会显示为CPU使用率。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM