Akka - 负载平衡和充分利用处理器

时间:2011-12-06 10:46:11

标签: load-balancing akka

我写了一个矩阵乘法算法,它使用并行集合来加速乘法。

就是这样:

(0 until M1_ROWS).grouped(PARTITION_ROWS).toList.par.map( i => 
  singleThreadedMultiplicationFAST(i.toArray.map(m1(_)), m2) 
).reduce(_++_) 

现在我想在Akka做同样的事情,所以我做的是:

val multiplyer = actorOf[Pool] 
multiplyer start 
val futures = (0 until M1_ROWS).grouped(PARTITION_ROWS).map( i => 
  multiplyer ? MultiplyMatrix(i.toArray.map(m1(_)), m2) 
) 
futures.map(_.get match { case res :Array[Array[Double]] => res }).reduce(_++_) 

class Multiplyer extends akka.actor.Actor{ 
  protected def receive = { 
    case MultiplyMatrix(m1, m2) => self reply singleThreadedMultiplicationFAST (m1,m2) 
  } 
} 
class Pool extends Actor with DefaultActorPool 
  with FixedCapacityStrategy with RoundRobinSelector { 

  def receive = _route 
  def partialFill = false 
  def selectionCount = 1 
  def instance = actorOf[Multiplyer] 
  def limit = 32 // I tried 256 with no effect either 
} 

事实证明,此算法的基于actor的版本仅使用 在我的i7沙地上200%,而并行收藏版本是 使用600%的处理器,速度提高4-5倍。 我以为可能是调度员并尝试了这个:

self.dispatcher = Dispatchers.newThreadBasedDispatcher(self, mailboxCapacity = 100) 

这个(我在演员之间分享了这个):

val messageDispatcher = Dispatchers.newExecutorBasedEventDrivenDispatcher("d1")
  .withNewBoundedThrea dPoolWithLinkedBlockingQueueWithUnboundedCapacity(100)
  .setCorePoolSize(16)
  .setMaxPoolSize(128)
  .setKeepAliveTimeInMillis(60000).build 

但我没有观察到任何变化。仍然只有200%的处理器使用率 该算法比并行集合慢4-5倍 版。

我确信我正在做些傻事,所以请帮忙!!! :)

1 个答案:

答案 0 :(得分:2)

这个表达式:

val futures = (0 until M1_ROWS).grouped(PARTITION_ROWS).map( i => 
  multiplyer ? MultiplyMatrix(i.toArray.map(m1(_)), m2) 
) 

创建一个惰性集合,所以你的_.get使你的整个程序串行。 因此,解决方案是通过添加toList或类似的方法使表达式严格。