data.table 并行化/多线程
Parallelizing / Multithreading with data.table
我有一个超过 10 亿个观察值的大数据,我需要执行一些很慢的字符串操作。
我的代码就这么简单:
DT[, var := some_function(var2)]
如果我没记错的话,data.table
在用 by
调用时使用多线程,我正在尝试利用它并行化此操作。为此,我可以制作一个临时石斑鱼变量,例如
DT[, grouper := .I %/% 100]
并做
DT[, var := some_function(var2), by = grouper]
我尝试使用少量数据样本进行基准测试,但令人惊讶的是我没有看到性能提升。所以我的问题是:
data.table
与by
一起使用时是否使用多线程?
- 如果是,是否有启用/禁用多线程的条件?
- 有没有一种方法可以让用户“强制”
data.table
在此处使用多线程?
仅供参考,我看到当我导入 data.table 时我的一半内核启用了多线程,所以我想这里没有 openMP 问题。
我从 data.table github 的 data.table
开发人员那里得到了答案。
总结如下:
查找 by
变量组本身总是并行化的,但更重要的是,
如果 j
上的函数是通用的(用户定义的函数),则没有并行化。
如果函数是 (gforce) optimized,则 j
上的操作被并行化(j 中的表达式仅包含函数 min
、max
、mean
, median
, var
, sd
, sum
, prod
, first
, last
, head
, tail
)
所以,如果j
上的功能是通用的,建议手动并行,但不一定能保证速度增益。 Reference
==解决方案==
在我的例子中,当我简单地使用 DT[, var := some_function(var2)]
时,我遇到了矢量内存耗尽,即使我的服务器有 1TB 的内存,而数据占用了 200GB 的内存。
我使用 split(DT, by='grouper')
将我的 data.table
分成块,并使用 doFuture
foreach
%dopar%
来完成这项工作。速度还挺快的。
我有一个超过 10 亿个观察值的大数据,我需要执行一些很慢的字符串操作。
我的代码就这么简单:
DT[, var := some_function(var2)]
如果我没记错的话,data.table
在用 by
调用时使用多线程,我正在尝试利用它并行化此操作。为此,我可以制作一个临时石斑鱼变量,例如
DT[, grouper := .I %/% 100]
并做
DT[, var := some_function(var2), by = grouper]
我尝试使用少量数据样本进行基准测试,但令人惊讶的是我没有看到性能提升。所以我的问题是:
data.table
与by
一起使用时是否使用多线程?- 如果是,是否有启用/禁用多线程的条件?
- 有没有一种方法可以让用户“强制”
data.table
在此处使用多线程?
仅供参考,我看到当我导入 data.table 时我的一半内核启用了多线程,所以我想这里没有 openMP 问题。
我从 data.table github 的 data.table
开发人员那里得到了答案。
总结如下:
查找
by
变量组本身总是并行化的,但更重要的是,如果
j
上的函数是通用的(用户定义的函数),则没有并行化。如果函数是 (gforce) optimized,则
j
上的操作被并行化(j 中的表达式仅包含函数min
、max
、mean
,median
,var
,sd
,sum
,prod
,first
,last
,head
,tail
)
所以,如果j
上的功能是通用的,建议手动并行,但不一定能保证速度增益。 Reference
==解决方案==
在我的例子中,当我简单地使用 DT[, var := some_function(var2)]
时,我遇到了矢量内存耗尽,即使我的服务器有 1TB 的内存,而数据占用了 200GB 的内存。
我使用 split(DT, by='grouper')
将我的 data.table
分成块,并使用 doFuture
foreach
%dopar%
来完成这项工作。速度还挺快的。