Мне лично не нравится пакет doSMP, так как он часто приводит к сбою моего R.Он разработан для сборки REvolution и почему-то не работает на моей машине.Например, ваш приведенный выше код, без изменений, просто приводит к сбою моей R.
Кроме того, кажется странным пытаться использовать распараллеленную функцию внутри функции цикла. Более логично выполнять распараллеливание во внешнем цикле,Коммуникация, включенная во вложенные параллельные вычисления, вызывает резкое увеличение времени вычислений.Вы ничего не получаете, так как ваша функция sim
невероятно быстра.Фактически, сохранение сериализации внутреннего цикла имеет больше смысла, так как в этой ситуации время вычисления на одном ядре становится больше, чем издержки из-за связи.
Иллюстрация с использованием пакета snowfall-package и использованием вместо этого применения apply for loopingиз для петель.Это также очень наивно, так как с векторизацией можно многое выиграть (см. Ниже).
library(snowfall)
sfInit(parallel=T,cpus=2)
#same avec, bvec, sim
system.time({
out <- sapply(avec,function(i) {
sapply(bvec,function(j){
sim(i,j)
})
})
})[3]
elapsed
0.33
sfExport("avec","bvec","sim")
system.time({
out <- sfSapply(avec,function(i) { # this one is parallel
sapply(bvec,function(j){ # this one is not, no sense in doing so
sim(i,j)
})
})
})[3]
elapsed
0.17
Обе матрицы равны, кроме имен измерений из-за структуры:
> all.equal(out1,out2)
[1] "Attributes: < Length mismatch: comparison on first 1 components >"
Правильный способ R сделать это будет:
system.time(
out3 <- outer(avec*10,bvec,"+")
)[3]
elapsed
0.01
, что значительно быстрее и создаст идентичную (хотя и транспонированную) матрицу:
> all.equal(out1,t(out3))
[1] TRUE
(в качестве ссылки,ваш двойной цикл for работает на моей системе 0,73 прошедшего времени ...)