Gem Parallel gem 实现从 3 个数组中分别取值进行科学计算的问题

paulshu · 2017年09月27日 · 最后由 paulshu 回复于 2017年10月06日 · 713 次阅读

背景情况:

本人新人一枚,最近在做一个项目,需要从三个数组中(每个数组4.6-6万组数据),每个数组分别代表直角坐标中的X,Y,Z,这里以x_arr, y_arr, z_arr说明。需要一次同时遍历三个数组,分别按顺序取出相应的X,Y,Z值后,代入到另一个函数进行计算。完成这样一次遍历要1分钟左右。

问题:

因时间花的比较多,为提高效率,想利用好计算机的多核CPU的能力。因此,我找到了Parallel这个Gem, https://github.com/grosser/parallel

单线程我是这样写的

x_arr.zip(y_arr,z_arr) do |x,y,z|
  calculation(x,y,z)
end

然后我使用了Parallel,但无论如何也只能实现从其中一个数组中取值,首先将x_arr拆分成:x_arr1, x_arr2, x_arr3

多线程我是这样写的

Parallel.map([x_arr1, x_arr2, x_arr3]) do |x|
  calculation(x)
end

实测,会自动用到到三个核去计算,时间确实缩短了。但是问题来了 前面只取到了一个数组的值,但“y_arr, z_arr”没有取到,怎么试也不行,难道要重写GEM吗?还请大家分享一下经验,有什么办法可以解。十分感谢!

共收到 7 条回复
Parallel.map_with_index(x_arr) do |x, i|
  calculation(x, y_arr[i], z_arr[i])
end

这样试试

试了一下,确实可以,感谢啊! map_with_index和each_with_index 在Parallel中的用法主要区别在哪呢?

paulshu 回复

其实就是 map 和 each 的区别,with_index 就是在遍历的时可以获取当前索引

但我实际测试时,发现这两个还是有区别的。each_with_index 要配合使用in_threads: 5 ,(数字可以修改),才能同时取到索引,而map_with_index就不需要,具体原因我不是很清楚。而且each_with_index在使用时还经常出现一些奇怪的问题,而使用map_with_index就比较正常一些。

问题已全部解决,测试ok,分享一下经验 http://paulshu-blog.logdown.com/posts/2737227

向量化计算可能 SciRuby 是更好的选择,不过我一般用 Python 的 numpy,对应的 SciRuby 的 gem 应该是 https://github.com/SciRuby/rb-gsl

Python是有很多成熟的包, numpy之前有学习过,效率相当高,网上的资料也比较多,但 SciRuby用的人好像并不多,在ruby上做科学计算的人太少了。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册