【发布时间】:2014-05-05 14:16:15
【问题描述】:
我正在运行 AMD 四核处理器的 Ubuntu 12.04 系统上试验 akka / scala 2.10.3。
我编写了一个服务器,它在收到请求时应该执行一些计算。客户端将使用参与者消息发送一些数据(字符串列表)。当服务器上的 Actor 接收到列表时,它会将其拆分为四个列表,并让四个子 Actor 对列表进行排序。
到目前为止一切顺利:程序运行正常,我可以验证客户端是否收到了正确排序的列表。
但是,在服务器的行为中有两件事我不明白:
- 一旦我启动服务器,即使没有任何参与者在进行任何处理(他们都在等待消息),我的处理器的所有四个内核的使用率几乎都达到了 100%。这怎么可能?不应该只在安排某些参与者处理某些消息时才使用核心吗?
- 我曾预计,由四个参与者完成工作会自动暗示排序速度会提高四倍:每个参与者在单独的线程中运行,每个线程由不同的核心运行。然而,情况并非如此:没有观察到加速,甚至,基于actor的排序比普通的单线程排序慢得多。原因可能是我的调度程序配置,即默认配置不会自动利用多个核心吗?
编辑
按照 Dan Simon 的建议,我使用 visualvm 研究了问题 1。
visualvm 报告了几个大部分时间都在等待的调度程序线程(因此它们似乎没有使用太多的 CPU 时间)。
visualvm 还显示了其他几个一直在运行的线程,即使应用程序没有做任何事情;至少,我的代码都没有被执行。这些忙碌线程被命名为New I/O worker #1, #2, #4, #5、New I/O boss #3、New I/O server boss、Signal Dispatcher、RMI TCP Connection(2)-127.0.0.1、Attach Listener和RMI TCP Accept-0。
我有一些编程 akka 的经验,但几乎没有配置它的经验,所以我无法理解上述信息。
【问题讨论】:
-
默认调度程序使用 fork-join 调度程序,并且将有多个线程对应于物理内核的数量(我相信每个内核有 2 个),所以我怀疑还有另一个问题。我注意到 fork-join 有时会做很多忙等待,但不像你描述的那样。可以发一些代码吗?
-
@Dan Simon:感谢您的反馈。代码不够小,不能在这里发布,我可以将其上传到某个地方并在此处发布链接。或者您希望看到代码的哪些部分?
-
不太确定,您的演员在构造时或在他们的
preStart方法中做任何事情吗?演员是否有任何类型的初始化消息或某种定期轮询工作?另外,您是否尝试过使用诸如 visualvm 之类的分析器来查看 CPU 的使用位置? -
@Dan Simon:有些演员确实有一个
preStart方法,他们可以在其中创建子演员和/或发送一些消息。 Actors 也有一些初始化,但在那之后,它们会进入一个只等待传入消息的状态。据我所知,这不应该意味着轮询。我现在必须睡一会儿,但明天我会尝试使用分析器,看看是否能找到更多信息。感谢您的建议。
标签: multithreading scala akka