Я бег этого SCALA кода на 32-битной четырехъядерной системе Core2:Почему мои фьючерсы scala более эффективны?
def job(i:Int,s:Int):Long = {
val r=(i to 500000000 by s).map(_.toLong).foldLeft(0L)(_+_)
println("Job "+i+" done")
r
}
import scala.actors.Future
import scala.actors.Futures._
val JOBS=4
val jobs=(0 until JOBS).toList.map(i=>future {job(i,JOBS)})
println("Running...")
val results=jobs.map(f=>f())
println(results.foldLeft(0L)(_+_))
(Да, я делать знает, что есть много более эффективных способов суммировать ряд целых чисел; это просто дать CPU что-то делать).
В зависимости от того, что я поставил работу, чтобы, код выполняется в следующих случаях:
JOBS=1 : 31.99user 0.84system 0:28.87elapsed 113%CPU
JOBS=2 : 27.71user 1.12system 0:14.74elapsed 195%CPU
JOBS=3 : 33.19user 0.39system 0:13.02elapsed 257%CPU
JOBS=4 : 49.08user 8.46system 0:22.71elapsed 253%CPU
Я удивлен, что это не очень хорошо масштабируется за 2 фьючерсы «в игре». Я использую многопоточный код на C++ и не сомневаюсь, что получим хорошее масштабирование до 4 ядер и увижу> 390% загрузки процессора, если бы я закодировал подобные вещи с помощью TBB от Intel или boost::threads
(это было бы значительно более подробным из курс).
Итак: что происходит и как я могу получить масштабирование до 4 ядер, которые я ожидал увидеть? Является ли это чем-то ограниченным в scala или JVM? Мне кажется, что я не знаю «где» работает фьючерс scala ... это поток, порожденный в будущем, или «Фьючерсы» предоставляют пул потоков, предназначенный для их запуска?
[Я использую SCALA 2.7.7 пакеты из Debian/Squeeze на системе Ленни с солнцем-java6 (6-20-0lennny1).]
Update:
Как было предложено в ответе Рекса я перекодировал, чтобы избежать создания объекта.
def job(i:Long,s:Long):Long = {
var t=0L
var v=i
while (v<=10000000000L) {
t+=v
v+=s
}
println("Job "+i+" done")
t
}
// Rest as above...
Это было так быстро, что мне пришлось значительно увеличить количество итераций, чтобы работать в течение любого количества времени! Результаты:
JOBS=1: 28.39user 0.06system 0:29.25elapsed 97%CPU
JOBS=2: 28.46user 0.04system 0:14.95elapsed 190%CPU
JOBS=3: 24.66user 0.06system 0:10.26elapsed 240%CPU
JOBS=4: 28.32user 0.12system 0:07.85elapsed 362%CPU
который гораздо больше напоминает то, что я надеюсь увидеть (хотя работа случай 3 является немного странным, с одной задачей последовательно выполняя несколько секунд до двух других).
Нажав немного дальше, на четырехъядерном гиперпотоке i7 последняя версия с JOBS=8
достигает ускорения x4.4 против JOBS = 1, при использовании процессора 571%.
Вы просто нетерпеливы, желая будущего сегодня! Серьезно, Рекс ударил ноготь по голове, вы сравниваете сбор мусора, а не эффективность фьючерсов. –
Хех ... слишком верно.Когда я представил этот вопрос, я долгое время не использовал Scala, и, вероятно, был слишком доверчив некоторым из них. – timday
Уход за повторным запуском теста с помощью akka.dispatch.Future? –