編集:サンプルサイズが小さすぎました。 8つのCPUで実際のデータと比較してみると、7.2倍の速度向上が見られました。 )私のコードに4文字を追加するためにあまり目立たない;)スカラ並列コレクションランタイム困惑
私は現在、Scalaを使うことのメリットを管理するために、特にCPUを使ってスケーリングを行うという点で管理を売りに出そうとしています。その目的のために、ベクトル計算を行うシンプルなテストアプリケーションを作成しましたが、ランタイムが私のクアッドコアマシンではそれほど優れていないことがわかりました。興味深いことに、私は、あなたがコレクションを通過する最初の時にランタイムが最悪であり、その後の呼び出しでより良くなることを発見しました。パラレルコレクションに、これを引き起こしているいくつかの怠惰なものがありますか、それとも間違っていますか?私はC++/C#の世界から来ていることに注意する必要があります。だから、どうにか私の設定を混乱させる可能性があります。の
InteliJ Scalaのプラグイン
Scalaの2.9.1.final
のWindows 7 64ビット、クアッドコアプロセッサ(なしハイパースレッディング)
import util.Random
// simple Vector3D class that has final x,y,z components a length, and a '-' function
class Vector3D(val x:Double, val y:Double, val z:Double)
{
def length = math.sqrt(x*x+y*y+z*z)
def -(rhs : Vector3D) = new Vector3D(x - rhs.x, y - rhs.y, z - rhs.z)
}
object MainClass {
def main(args : Array[String]) =
{
println("Available CPU's: " + Runtime.getRuntime.availableProcessors())
println("Parallelism Degree set to: " + collection.parallel.ForkJoinTasks.defaultForkJoinPool.getParallelism);
// my position
val myPos = new Vector3D(0,0,0);
val r = new Random(0);
// define a function nextRand that gets us a random between 0 and 100
def nextRand = r.nextDouble() * 100;
// make 10 million random targets
val targets = (0 until 10000000).map(_ => new Vector3D(nextRand, nextRand, nextRand)).toArray
// take the .par hit before we start profiling
val parTargets = targets.par
println("Created " + targets.length + " vectors")
// define a range function
val rangeFunc : (Vector3D => Double) = (targetPos) => (targetPos - myPos).length
// we'll select ones that are <50
val within50 : (Vector3D => Boolean) = (targetPos) => rangeFunc(targetPos) < 50
// time it sequentially
val startTime_sequential = System.currentTimeMillis()
val numTargetsInRange_sequential = targets.filter(within50)
val endTime_sequential = System.currentTimeMillis()
println("Sequential (ms): " + (endTime_sequential - startTime_sequential))
// do the parallel version 10 times
for(i <- 1 to 10)
{
val startTime_par = System.currentTimeMillis()
val numTargetsInRange_parallel = parTargets.filter(within50)
val endTime_par = System.currentTimeMillis()
val ms = endTime_par - startTime_par;
println("Iteration[" + i + "] Executed in " + ms + " ms")
}
}
}
出力:かかわらず、ここに私の設定ですこのプログラムは:
Available CPU's: 4
Parallelism Degree set to: 4
Created 10000000 vectors
Sequential (ms): 216
Iteration[1] Executed in 227 ms
Iteration[2] Executed in 253 ms
Iteration[3] Executed in 76 ms
Iteration[4] Executed in 78 ms
Iteration[5] Executed in 77 ms
Iteration[6] Executed in 80 ms
Iteration[7] Executed in 78 ms
Iteration[8] Executed in 78 ms
Iteration[9] Executed in 79 ms
Iteration[10] Executed in 82 ms
ここでは何が起こっているのですか?最初の2回はフィルターをかけますが、それは遅くなり、その後はスピードアップしますか?私は本質的には並列化のスタートアップコストとなることを理解しています。私はアプリケーションで並列性を表現するのが理にかなっています。具体的には、管理プログラムを3-4回実行できるようにしたいクアッドコアボックスでは高速です。これは良い問題ではないのですか?
アイデア?
管理の売り方については、http://scala-boss.heroku.com/#1をご覧ください(次のスライドを見るには矢印キーを使用してください)。 – huynhjl
一般に、並列配列を並列ベクトルよりも優先します。少なくとも、連結がベクトルに追加されるまでです。 – axel22
@huynhjl - 最初の2つの漫画に描かれた私の人生を見て、プレゼンテーションが価値があったことは分かっていました。ありがとう! – fbl