C语言 什么时候知道Python并行性是否足够?

kognpnkq  于 4个月前  发布在  Python
关注(0)|答案(2)|浏览(41)

我对Python并行性的基础知识(CPU绑定,使用多处理,IO绑定,使用线程)有一点了解,但我想知道并行化几乎所有时间都花在库代码中的函数的最佳方法是什么。我的具体用例是并行化训练数千个XGBoost模型。重要的是,我并不真正关心通过n_jobs参数并行化每个模型。粗略地说,

for col in col_list:
   train_xgboost(col, target)

字符串
我尝试过同时使用多处理和多线程,

with concurrent.futures.ProcessPoolExecutor() as pool:
    pool.map(train_xgboost, col)

with concurrent.futures.ThreadPoolExecutor() as pool:
    pool.map(train_xgboost, col)


我看到这两种方法都有显著的加速效果,但我想知道在低级语言中并行化是否有用,因为几乎所有的train_xgboost都只是调用C++代码。我知道Python并行化可能会有很大的开销,但我不确定这些开销是否适用于这种情况。重新编写代码以使用XGBoost C API和OpenMP会有什么作用吗?我知道有时唯一的方法就是基准测试,但不幸的是,我几乎不知道C,在我尝试进入一个全新的语言之前,我希望得到一些指导。
多谢了,多谢了

yi0zb3m4

yi0zb3m41#

我知道一些Python并行性的基础知识(CPU绑定、使用多处理、IO绑定、使用线程)
这是一条不错的经验法则,但深入一点会得到一条更具预测性的法则,尽管这条法则可能更难评估:

  • 需要全局解释器锁才能继续:使用多处理
  • 大多数情况下不需要GIL来取得进展:使用线程

IO绑定通常福尔斯后一类。如果计算(大部分)是在纯Python* 中完成的,则CPU绑定属于前一类 *;但如果计算大部分是在本地代码中完成的,则可能属于后一类。
我想知道,如果train_xgboost几乎所有的功能都只是调用C++代码,那么在低级语言中进行并行化是否有用。
大概不会吧。
我知道Python并行性可能会带来很大的开销,但我不确定这些开销是否适用于这种情况。
所有的并行处理方法都有开销。但是,如果您的train_xgboost()只调用一次本地代码,然后等待该调用返回,那么我看不出有多少空间来削减开销。顺便说一句,这属于“大多数情况下不需要GIL来取得进展”的范畴。如果本地代码频繁地回调Python,情况可能会有所不同。或者存在对本机代码的许多调用的更复杂的模式。
重新编写代码以使用XGBoost C API和OpenMP会有什么作用吗?我知道有时候唯一的方法就是进行基准测试,
很难说这是否 * 可以 * 提供显著的性能提升,但我的猜测是,不会有太多的好处。
无论如何,这......
我几乎不认识C
...提供了一个很好的理由来假设,这种方法可能带来的任何性能提升对您个人来说都很难实现。

xytpbqjk

xytpbqjk2#

一般来说,如果你必须向函数调用传递大量数据,(我不知道你的train_xgboost函数)最好避免Python中的多处理。Python使用pickle序列化参数,这可能会导致性能开销。进程也不会共享任何内存空间,因此,您可能还需要考虑(如果您正在考虑在进程之间共享任何类型的数据)
如果你打算使用多线程,你可能需要考虑更多的事情:

也就是说,如果使用得当,这两种技术都会带来明显的性能提升。然而,根据我的经验,编译语言(C,C++或Go)总是表现得更好。Go也有一个优秀的并发模型。但是如果性能需求不是绝对的瓶颈,你可以继续使用Python的并发实现。

相关问题