gpt4 book ai didi

python - Pandas 和 Numpy 中关于多线程的奇怪错误

转载 作者:行者123 更新时间:2023-12-01 07:34:07 27 4
gpt4 key购买 nike

Numpy 的大部分功能都会默认启用多线程。

例如,我在 8 核英特尔 CPU 工作站上工作,如果我运行脚本

import numpy as np    
x=np.random.random(1000000)
for i in range(100000):
np.sqrt(x)

linux top将在运行期间显示 800% 的 CPU 使用率,例如
enter image description here
这意味着 numpy 会自动检测到我的工作站有 8 个内核,并且 np.sqrt自动使用所有 8 个内核来加速计算。

但是,我发现了一个奇怪的错误。如果我运行一个脚本
import numpy as np
import pandas as pd
df=pd.DataFrame(np.random.random((10,10)))
df+df
x=np.random.random(1000000)
for i in range(100000):
np.sqrt(x)

cpu使用率是100%!!
enter image description here 这意味着如果你在运行任何 numpy 函数之前加上两个 Pandas DataFrame,那么 numpy 的自动多线程功能就会毫无预警地消失! 这绝对不合理,为什么Pandas dataFrame 计算会影响Numpy 线程设置?这是一个错误吗?如何解决这个问题?

PS:

我使用 Linux 进一步挖掘 perf工具。

运行第一个脚本显示

enter image description here

运行第二个脚本时显示

enter image description here

所以这两个脚本都涉及 libmkl_vml_avx2.so ,而第一个脚本涉及额外的 libiomp5.so这似乎与openMP有关。

由于 vml 意味着英特尔矢量数学库,所以根据 vml doc 我猜至少下面的函数都是自动多线程的

enter image description here

最佳答案

Pandas 使用 numexpr 在引擎盖下计算一些操作,以及 numexprit is imported 时,将 vml 的最大线程数设置为 1 :

# The default for VML is 1 thread (see #39)
set_vml_num_threads(1)

它在 df+df 时被 Pandas 导入在 expressions.py 中评估:
from pandas.core.computation.check import _NUMEXPR_INSTALLED

if _NUMEXPR_INSTALLED:
import numexpr as ne

但是,Anaconda 发行版也使用 vml-functionity 来实现 sqrt 等功能。 , sin , cos等等 - 还有一次 numexpr将最大 vml 线程数设置为 1,numpy 函数不再使用并行化。

这个问题很容易在 gdb 中看到(使用你的慢脚本):
>>> gdb --args python slow.py
(gdb) b mkl_serv_domain_set_num_threads
function "mkl_serv_domain_set_num_threads" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (mkl_serv_domain_set_num_threads) pending.
(gbd) run
Thread 1 "python" hit Breakpoint 1, 0x00007fffee65cd70 in mkl_serv_domain_set_num_threads () from /home/ed/anaconda37/lib/python3.7/site-packages/numpy/../../../libmkl_intel_thread.so
(gdb) bt
#0 0x00007fffee65cd70 in mkl_serv_domain_set_num_threads () from /home/ed/anaconda37/lib/python3.7/site-packages/numpy/../../../libmkl_intel_thread.so
#1 0x00007fffe978026c in _set_vml_num_threads(_object*, _object*) () from /home/ed/anaconda37/lib/python3.7/site-packages/numexpr/interpreter.cpython-37m-x86_64-linux-gnu.so
#2 0x00005555556cd660 in _PyMethodDef_RawFastCallKeywords () at /tmp/build/80754af9/python_1553721932202/work/Objects/call.c:694
...
(gdb) print $rdi
$1 = 1

即我们可以看到, numexpr将线程数设置为 1。稍后在调用 vml-sqrt 函数时使用:
(gbd) b mkl_serv_domain_get_max_threads
Breakpoint 2 at 0x7fffee65a900
(gdb) (gdb) c
Continuing.

Thread 1 "python" hit Breakpoint 2, 0x00007fffee65a900 in mkl_serv_domain_get_max_threads () from /home/ed/anaconda37/lib/python3.7/site-packages/numpy/../../../libmkl_intel_thread.so
(gdb) bt
#0 0x00007fffee65a900 in mkl_serv_domain_get_max_threads () from /home/ed/anaconda37/lib/python3.7/site-packages/numpy/../../../libmkl_intel_thread.so
#1 0x00007ffff01fcea9 in mkl_vml_serv_threader_d_1i_1o () from /home/ed/anaconda37/lib/python3.7/site-packages/numpy/../../../libmkl_intel_thread.so
#2 0x00007fffedf78563 in vdSqrt () from /home/ed/anaconda37/lib/python3.7/site-packages/numpy/../../../libmkl_intel_lp64.so
#3 0x00007ffff5ac04ac in trivial_two_operand_loop () from /home/ed/anaconda37/lib/python3.7/site-packages/numpy/core/_multiarray_umath.cpython-37m-x86_64-linux-gnu.so

所以我们可以看到numpy使用vml的 vdSqrt的实现使用 mkl_vml_serv_threader_d_1i_1o决定是否应该并行进行计算,并查看线程数:
(gdb) fin
Run till exit from #0 0x00007fffee65a900 in mkl_serv_domain_get_max_threads () from /home/ed/anaconda37/lib/python3.7/site-packages/numpy/../../../libmkl_intel_thread.so
0x00007ffff01fcea9 in mkl_vml_serv_threader_d_1i_1o () from /home/ed/anaconda37/lib/python3.7/site-packages/numpy/../../../libmkl_intel_thread.so
(gdb) print $rax
$2 = 1

注册 %rax具有最大线程数,为 1。

现在我们可以使用 numexprincrease the number of vml-threads , IE。:
import numpy as np
import numexpr as ne
import pandas as pd
df=pd.DataFrame(np.random.random((10,10)))
df+df

#HERE: reset number of vml-threads
ne.set_vml_num_threads(8)

x=np.random.random(1000000)
for i in range(10000):
np.sqrt(x) # now in parallel

现在使用了多个内核!

关于python - Pandas 和 Numpy 中关于多线程的奇怪错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59445147/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com