जब 2d-array (या nd-array) C- या F-contiguous होता है, तो 2d-array पर किसी फंक्शन को मैप करने का यह काम व्यावहारिक रूप से उसी तरह होता है, जैसे कि 1d-array पर किसी फंक्शन को मैप करने का काम। इसे इस तरह से देखना है, उदाहरण के लिए np.ravel(A,'K')
।
उदाहरण के लिए 1d-array के संभावित समाधान पर चर्चा की गई है ।
हालाँकि, जब 2d-array की मेमोरी सन्निहित नहीं होती है, तो स्थिति थोड़ी अधिक जटिल हो जाती है, क्योंकि यदि कोई गलत क्रम में धुरी को संभाला जाता है, तो संभव कैश से बचना चाहेंगे।
Numpy में पहले से ही सर्वोत्तम संभव क्रम में कुल्हाड़ियों को संसाधित करने के लिए एक मशीनरी है। इस मशीनरी का उपयोग करने की एक संभावना है np.vectorize
। हालांकि, खाँसी के दस्तावेज में np.vectorize
कहा गया है कि यह "मुख्य रूप से सुविधा के लिए प्रदान किया गया है, प्रदर्शन के लिए नहीं" - एक धीमा अजगर फ़ंक्शन पूरे संबद्ध ओवरहेड के साथ एक धीमी अजगर फ़ंक्शन रहता है! एक और मुद्दा इसकी विशाल मेमोरी खपत है - उदाहरण के लिए इस एसओ-पोस्ट को देखें ।
जब कोई सी-फंक्शन का प्रदर्शन करना चाहता है, लेकिन सुपी की मशीनरी का उपयोग करता है, तो इसका एक अच्छा समाधान है, उदाहरण के लिए, ufuncs के निर्माण के लिए सुंबा का उपयोग करना:
# runtime generated C-function as ufunc
import numba as nb
@nb.vectorize(target="cpu")
def nb_vf(x):
return x+2*x*x+4*x*x*x
यह आसानी से धड़कता है np.vectorize
लेकिन यह भी जब एक ही फ़ंक्शन को संख्यात्मक-सरणी गुणन / जोड़ के रूप में प्रदर्शन किया जाएगा, अर्थात
# numpy-functionality
def f(x):
return x+2*x*x+4*x*x*x
# python-function as ufunc
import numpy as np
vf=np.vectorize(f)
vf.__name__="vf"
समय-माप-कोड के लिए इस उत्तर का परिशिष्ट देखें:
नुम्बा का संस्करण (हरा) अजगर-कार्य (यानी np.vectorize
) की तुलना में लगभग 100 गुना तेज है , जो आश्चर्य की बात नहीं है। लेकिन यह भी सुपी-कार्यक्षमता की तुलना में लगभग 10 गुना तेज है, क्योंकि सुन्न संस्करण को मध्यवर्ती सरणियों की आवश्यकता नहीं है और इस प्रकार कैश का अधिक कुशलता से उपयोग करता है।
जबकि सुंबा का ufunc दृष्टिकोण प्रयोज्य और प्रदर्शन के बीच एक अच्छा व्यापार है, लेकिन यह अभी भी सबसे अच्छा नहीं है जो हम कर सकते हैं। फिर भी किसी भी कार्य के लिए चांदी की गोली या एक दृष्टिकोण सबसे अच्छा नहीं है - किसी को यह समझना होगा कि सीमा क्या है और उन्हें कैसे कम किया जा सकता है।
उदाहरण के लिए, ट्रान्सेंडैंटल फ़ंक्शंस (उदाहरण exp
के लिए sin
, cos
) सुंबा , खसखस पर कोई लाभ नहीं प्रदान करता है np.exp
(कोई अस्थायी सरणियाँ नहीं हैं - गति का मुख्य स्रोत)। हालाँकि, मेरा एनाकोंडा इंस्टालेशन इंटेल के VML का उपयोग वैक्टर के लिए 8192 से बड़ा है - यह सिर्फ ऐसा नहीं कर सकता है यदि मेमोरी सन्निहित नहीं है। इसलिए इंटेल के VML का उपयोग करने में सक्षम होने के लिए तत्वों को किसी सन्निहित मेमोरी में कॉपी करना बेहतर हो सकता है:
import numba as nb
@nb.vectorize(target="cpu")
def nb_vexp(x):
return np.exp(x)
def np_copy_exp(x):
copy = np.ravel(x, 'K')
return np.exp(copy).reshape(x.shape)
तुलना की निष्पक्षता के लिए, मैंने वीएमएल के समानांतरकरण को बंद कर दिया है (परिशिष्ट में कोड देखें):
जैसा कि एक बार देखा जा सकता है, वीएमएल एक बार किक मारता है, नकल का ओवरहेड क्षतिपूर्ति से अधिक होता है। फिर भी एक बार L3 कैश के लिए डेटा बहुत बड़ा हो जाता है, लाभ कम से कम होता है क्योंकि कार्य एक बार फिर मेमोरी-बैंडविड्थ-बाउंड हो जाता है।
दूसरी ओर, सुंबा इंटेल की SVML का उपयोग कर सकता है, जैसा कि इस पोस्ट में बताया गया है :
from llvmlite import binding
# set before import
binding.set_option('SVML', '-vector-library=SVML')
import numba as nb
@nb.vectorize(target="cpu")
def nb_vexp_svml(x):
return np.exp(x)
और समानांतर उपज के साथ VML का उपयोग करना:
सुंबा के संस्करण में ओवरहेड कम है, लेकिन कुछ आकारों के लिए वीएमएल अतिरिक्त नकल के बावजूद एसवीएमएल को हरा देता है - जो कि थोड़ा आश्चर्य की बात नहीं है क्योंकि सुंबा के यूफंक्स को समानांतर नहीं किया गया है।
लिस्टिंग:
बहुपद समारोह की A. तुलना:
import perfplot
perfplot.show(
setup=lambda n: np.random.rand(n,n)[::2,::2],
n_range=[2**k for k in range(0,12)],
kernels=[
f,
vf,
nb_vf
],
logx=True,
logy=True,
xlabel='len(x)'
)
बी की तुलना exp
:
import perfplot
import numexpr as ne # using ne is the easiest way to set vml_num_threads
ne.set_vml_num_threads(1)
perfplot.show(
setup=lambda n: np.random.rand(n,n)[::2,::2],
n_range=[2**k for k in range(0,12)],
kernels=[
nb_vexp,
np.exp,
np_copy_exp,
],
logx=True,
logy=True,
xlabel='len(x)',
)