Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x 函数运行时间的增加抵消了Ray多处理的好处_Python 3.x_Multiprocessing_Ray - Fatal编程技术网

Python 3.x 函数运行时间的增加抵消了Ray多处理的好处

Python 3.x 函数运行时间的增加抵消了Ray多处理的好处,python-3.x,multiprocessing,ray,Python 3.x,Multiprocessing,Ray,我有一个传递6个字典、两个字符串和一个整数的函数。此外,还会传递一个“元素”ID列表,函数通过一个简单的for语句循环通过该列表。字典包含许多“元素”的结果(浮点值),其中键是“元素”标识符,值是包含6个浮点值的列表。字典的大小各不相同,但可以包含多达150万个键/值对 函数的第一部分查询字典,查找与“element”ID相关的结果,并将它们提取到Numpy数组中。这些被放大,并进行一些简单的算术计算。请注意,这两个字符串和整数用作计算的附加标识符和起始id。函数返回一个字典,其中包含每个元素的

我有一个传递6个字典、两个字符串和一个整数的函数。此外,还会传递一个“元素”ID列表,函数通过一个简单的
for
语句循环通过该列表。字典包含许多“元素”的结果(浮点值),其中键是“元素”标识符,值是包含6个浮点值的列表。字典的大小各不相同,但可以包含多达150万个键/值对

函数的第一部分查询字典,查找与“element”ID相关的结果,并将它们提取到Numpy数组中。这些被放大,并进行一些简单的算术计算。请注意,这两个字符串和整数用作计算的附加标识符和起始id。函数返回一个字典,其中包含每个元素的计算结果

函数(每个元素)的平均运行时间约为1.2秒(初始提取为0.2秒,Numpy计算为1.0秒)。因此,元素的数量可能多达15000个,因此需要一个不重要的运行时间

因此,我一直在研究各种多处理模块,试图加快运行时间(
多处理
/
Dask
/
joblib
),老实说,没有多少成功。我还没有找到任何一个模块来减少串行运行时间。 我现在主要关注的是
Ray
模块,下面是调用函数的代码部分(已使用
@Ray.remote
对其进行了修饰)

我正在使用
ray.put()
为字典/字符串/整数创建共享内存对象。 然后使用
calc\u crit\u prin\u stress.remote()
调用该函数,该函数包括一个包含在列表“
reqd\u elements
”中的所有元素ID(
elm
)的循环。 结果通过
ray.get返回

注意:我使用的是本地Win10/32内核/128Gb Ram桌面

代码执行正常,我可以看到所有内核在任务管理器中工作,我也得到了预期的结果,但我只看到运行时间的相对较小的减少。下图显示了所执行测试的实际运行时间,改变了CPU的数量(对于50个元素)。循环运行时的基线序列<代码>为59秒。使用具有4个内核的<代码>射线<代码>可以发现类似的时间。但是,进一步将内核增加到8/16/32,显示出明显的递减回报,即从4个内核增加到32个内核只会减少15秒的运行时间(约25%)

然后,我向函数中添加了一些简单的代码,以输出函数中执行提取和Numpy计算所花费的时间(注意:这不会显著影响总体运行时间)

提取时间:0.206s(x4芯)0.649s(x32芯)系数3.15

Numpy计算1.129s(x4芯)7.777s(x32芯)系数6.89

总计1.335s(x4芯)8.426s(x32芯)系数为6.31

因此,尽管内核数量增加了8倍,但函数实际运行时间的增加几乎抵消了任何好处。
我知道在设置多处理时会涉及额外的开销,但这些时间都在函数本身内?当我们在这里讨论多处理时,这是否仅限于将多个循环分配给不同的核,还是函数本身的执行在不同的核之间分割,导致更多的循环开销和增加的运行时间?我的代码中是否有导致这种情况的原因


我非常感谢您的指导。谢谢您,如果我能看到实际工作的串行和并行代码,我会更加准确。从我看来,您很可能是通过IPC一次分配一个任务。因此,当您有很多流程时,他们会花很多时间互相限制,试图获取信息使用共享队列,当然,对于许多使用者,他们处理这些光线的速度可能比主进程分配新任务的速度快

有两种简单的方法可以减少这种情况,一次发送多个任务,比如说100或1000个任务,具体取决于你有多少任务以及计算它们需要多长时间,或者使用共享内存(不那么容易)。计算机非常擅长复制大量数据,但在有效控制共享数据的访问方面却非常糟糕

如果你真的想让它快一点,你可以用共享内存做一些事情,尽管这需要python不太适合的比特摆弄类型的操作,并序列化所有你想“发送”的数据项对于消费者来说。我并不经常使用numpy,因为您的数据可能已经很合适了。基本上,我们的计划是用空格(或一大块)存储所有数据在共享内存中,Python从3.8开始就支持共享内存。然后将该表的范围分配给不同的进程,当它们通过队列或类似的东西完成时,让它们发出信号。您不需要将所有内容都放入共享内存中,您可以将批移到共享内存中,并在每个批完成后或甚至有不同的批后将它们移入移出与不同进程关联的nt区域。这非常类似于通过队列使用更大的批处理,但如果传输大量数据,速度会更快。这要复杂得多,工作量也更大,因此我会先通过队列执行批处理方法


我不太熟悉您目前在装饰器中使用的技术,如果您使用带生成器的多处理池,您可以分配批处理大小,它将为您处理所有事情。

如果我可以看到实际工作的串行和并行代码,我将能够更加准确。从我所看到的情况来看,您看起来像是我一次只分配一个任务
mech_arg = ray.put(mech_iru_out_ult_all)
wbap_arg = ray.put(wbap_iru_out_ult_all)
thermal_arg = ray.put(thermal_out_ult_reduced)
fp_arg = ray.put(fuel_pressure_out_ult_int)
ptol_arg = ray.put(ptol_out_ult_all)
pnl_supp_arg = ray.put(panel_support_out_ult_ret)
family_arg = ray.put("IRU")
condition_arg = ray.put("ULT")
start_id_arg = ray.put(70000001)

result = [calc_crit_prin_stress.remote(mech_arg,
                                       wbap_arg,
                                       thermal_arg,
                                       fp_arg,
                                       ptol_arg,
                                       pnl_supp_arg,
                                       family_arg,
                                       condition_arg,
                                       start_id_arg,
                                       elm) for elm in reqd_elements]

results = ray.get(result)