Pandas ใช้numexpr
ภายใต้ประทุนเพื่อคำนวณการดำเนินการบางอย่างและnumexpr
ตั้งค่าจำนวนสูงสุดของเธรดสำหรับ vml เป็น 1 เมื่อมีการนำเข้า :
# The default for VML is 1 thread (see #39)
set_vml_num_threads(1)
และจะได้รับการนำเข้าโดยนุ่นเมื่อdf+df
ถูกประเมินในexpressions.py :
from pandas.core.computation.check import _NUMEXPR_INSTALLED
if _NUMEXPR_INSTALLED:
import numexpr as ne
อย่างไรก็ตามการกระจายงูใหญ่ยังใช้ VML ฟังก์ชันการทำงานสำหรับการทำงานเช่น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
ตอนนี้เราสามารถใช้numexpr
เพื่อเพิ่มจำนวนของ vml-threadsเช่น:
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
ตอนนี้มีการใช้หลายคอร์!