在 R 中并行化向量化函数的最简单方法是什么?
我有一个非常大的列表X
和一个向量化函数f
。我想计算f(X)
,但是如果我用单核来计算,这将需要很长时间。我有(访问)一台 48 核服务器。并行计算 f(X)
的最简单方法是什么?以下不是正确答案:
library(foreach)
library(doMC)
registerDoMC()
foreach(x=X, .combine=c) %dopar% f(x)
上面的代码确实会并行计算f(X)
,但它是通过应用f
来实现的> 分别到 X
的每个元素。这忽略了 f
的矢量化性质,并且可能会导致速度变慢,而不是更快。我不想将 f
按元素应用于 X
,而是希望将 X
拆分为合理大小的块,并将 f
应用于那些。
那么,我是否应该手动将 X
拆分为 48 个大小相等的子列表,然后然后并行地将 f
应用于每个子列表,然后手动将结果放在一起?或者有专门为此设计的包吗?
如果有人想知道,我的具体用例是此处。
I have a very large list X
and a vectorized function f
. I want to calculate f(X)
, but this will take a long time if I do it with a single core. I have (access to) a 48-core server. What is the easiest way to parallelize the calculation of f(X)
? The following is not the right answer:
library(foreach)
library(doMC)
registerDoMC()
foreach(x=X, .combine=c) %dopar% f(x)
The above code will indeed parallelize the calculation of f(X)
, but it will do so by applying f
separately to every element of X
. This ignores the vectorized nature of f
and will probably make things slower as a result, not faster. Rather than applying f
elementwise to X
, I want to split X
into reasonably-sized chunks and apply f
to those.
So, should I just manually split X
into 48 equal-sized sublists and then apply f
to each in parallel, then manually put together the result? Or is there a package designed for this?
In case anyone is wondering, my specific use case is here.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
虽然这是一个较老的问题,但对于通过谷歌偶然发现这个问题的每个人(像我一样)来说,这可能会很有趣:看看
multicore
包中的pvec
函数。我认为它正是你想要的。Although this is an older question this might be interesting for everyone who stumbled upon this via google (like me): Have a look at the
pvec
function in themulticore
package. I think it does exactly what you want.这是我的实现。这是一个函数
chunkmap
,它需要一个向量化函数,应向量化的参数列表,
以及不应向量化的参数列表(即
常量),并返回与调用该函数相同的结果
直接参数,但结果是并行计算的。
对于函数
f
,向量参数v1
、v2
、v3
和标量参数
s1
、s2
,以下内容应返回相同的结果:因为
chunkapply
函数不可能知道哪个f
的参数是向量化的,哪些不是,这取决于你调用时指定,否则会得到错误的结果。你
通常应该命名你的参数以确保它们受到约束
正确。
以下一些示例显示
chunkapply(f,list(x))
生成与f(x)
相同的结果。我已将 max.chunk.size 设置得非常小,以确保实际使用分块算法。如果有人有比“chunkapply”更好的名字,请推荐。
编辑:
正如另一个答案指出的那样,多核包中有一个名为
pvec
的函数,它的功能与我编写的功能非常相似。对于简单的情况,您应该这样做,并且您应该投票赞成 Jonas Rauch 的答案。然而,我的函数有点更通用,所以如果以下任何一个适用于您,您可能需要考虑使用我的函数:pvec
仅对单个参数进行矢量化,因此您无法轻松地使用pvec
实现并行矢量化加法。我的函数允许您指定任意参数。Here's my implementation. It's a function
chunkmap
that takes avectorized function, a list of arguments that should be vectorized,
and a list of arguments that should not be vectorized (i.e.
constants), and returns the same result as calling the function on the
arguments directly, except that the result is calculated in parallel.
For a function
f
, vector argumentsv1
,v2
,v3
, and scalararguments
s1
,s2
, the following should return identical results:Since it is impossible for the
chunkapply
function to know whicharguments of
f
are vectorized and which are not, it is up to you tospecify when you call it, or else you will get the wrong results. You
should generally name your arguments to ensure that they get bound
correctly.
Here are some examples showing that
chunkapply(f,list(x))
produces identical results tof(x)
. I have set the max.chunk.size extremely small to ensure that the chunking algorithm is actually used.If anyone has a better name than "chunkapply", please suggest it.
Edit:
As another answer points out, there is a function called
pvec
in the multicore pacakge that has very similar functionality to what I have written. For simple cases, you should us that, and you should vote up Jonas Rauch's answer for it. However, my function is a bit more general, so if any of the following apply to you, you might want to consider using my function instead:pvec
only vectorizes over a single argument, so you couldn't easily implement parallel vectorized addition withpvec
, for example. My function allows you to specify arbitrary arguments.itertools 包就是为了解决此类问题而设计的。在这种情况下,我将使用 isplitVector:
对于此示例,pvec 无疑更快、更简单,但是这可以在 Windows 上与 doParallel 包一起使用。
The itertools package was designed to address this kind of problem. In this case, I would use
isplitVector
:For this example,
pvec
is undoubtably faster and simpler, but this can be used on Windows with the doParallel package, for example.Map-Reduce 可能就是您正在寻找的;它已移植到R
Map-Reduce might be what you're looking for; it's been ported to R
像这样的事情怎么样? R 将利用所有可用内存,而多核将在所有可用核心上并行化。
How about something like this? R will take advantage of all the available memory and
multicore
will parallelize over all available cores.