4

以下の Haskell コードでは、いくつかのコアが使用されていることを示すおもちゃとして、parpseqを使用してマルチコアの数計算を行っています。これを Scala で表現する最も簡単で慣用的な方法は何でしょうか? scalaz.concurrentFutures と Promises は有望に思えます (エヘム)。私は、たとえばthis exampleを見てきましたが、すべてを説明するドキュメントが見つかりません。

import Control.Parallel

main = a `par` b `par` c `pseq` print (a + b + c)
  where
      a = ack 3 10
      b = fac 42
      c = fib 35

fac 0 = 1
fac n = n * fac (n-1)

ack 0 n = n+1
ack m 0 = ack (m-1) 1
ack m n = ack (m-1) (ack m (n-1))

fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)
4

2 に答える 2

4

次のように、Scala で例を翻訳できます。

import concurrent.{Await, Future, future}
import concurrent.ExecutionContext.Implicits.global
import concurrent.duration.Duration

object Main extends App {

  val fac: Int => Int = {
    case 0 => 1
    case n => n * fac(n-1)
  }

  val ack: (Int, Int) => Int = {
    case (0, n) => n + 1
    case (m, 0) => ack (m-1, 1)
    case (m, n) => ack (m-1, ack(m, n-1))
  }

  val fib: Int => Int = {
    case 0 => 0
    case 1 => 1
    case n => fib(n-1) + fib(n-2)
  }

  val fa = future { ack(3, 10) }
  val fb = future { fac(42) }
  val fc = future { fib(35) }

  val x = for (((a, b), c) <- fa zip fb zip fc) yield (a + b + c)

  val result = Await.result(x, Duration.Inf) //awaiting synchronously after the result
  println(s"Value is: $result")

}

このfuture { fib(3, 10) }ビットは、別の実行スレッドで実行され、Futureオブジェクトを返す非同期計算を作成します。次に、すべての先物を 1 つの大きな先物に構成して、すべての結果のリストを提供しますFuture.sequence

この後者の未来の結果を結果の合計にマッピングして、最終的な値を得ることができます。

この最後の未来で、私たちはいくつかのことができます。さらに構成するか、コールバックをアタッチするか、指定された期間だけ同期的に待機することができます。私の例では、結果の後、無期限に同期的に待機しています。

于 2013-04-02T20:06:05.583 に答える
1

フューチャは 2.10 以降の標準ライブラリの一部であり、非常に使いやすいため、フューチャを使用することをお勧めします。あなたのコードを移植するつもりはありませんが、例を挙げて理解してもらいたいと思います。

// not tailrec, will stack overflow for larger numbers
def fib(x: Int): Int = x match {
  case 0 | 1 => x
  case x => fib(x-1) + fib(x-2)
}

import scala.concurrent._
import ExecutionContext.Implicits.global

// create all the futures
val futures = Seq(future(fib(3)), future(fib(4)), future(fib(5)))

// make a Future[Seq[Int]] out of Seq[Future[Int]] and sum the ints
val sumFuture = Future.sequence(futures).map(_.sum)

// if the future is completed successfully print the result
sumFuture.onSuccess {
  case x => println(x)
}
于 2013-04-02T19:57:13.600 に答える