मुझे एक सिमुलेशन (फोरट्रान में लिखित) से तापमान वितरण का प्रतिनिधित्व करते हुए एक 512 ^ 3 सरणी मिलती है। सरणी एक बाइनरी फ़ाइल में संग्रहीत है जो आकार में लगभग 1 / 2G है। मुझे इस सरणी का न्यूनतम, अधिकतम और मतलब जानना होगा और जैसा कि मुझे जल्द ही फोरट्रान कोड को समझने की आवश्यकता होगी, मैंने इसे एक बार देने का फैसला किया और निम्नलिखित बहुत आसान दिनचर्या के साथ आया।
integer gridsize,unit,j
real mini,maxi
double precision mean
gridsize=512
unit=40
open(unit=unit,file='T.out',status='old',access='stream',&
form='unformatted',action='read')
read(unit=unit) tmp
mini=tmp
maxi=tmp
mean=tmp
do j=2,gridsize**3
read(unit=unit) tmp
if(tmp>maxi)then
maxi=tmp
elseif(tmp<mini)then
mini=tmp
end if
mean=mean+tmp
end do
mean=mean/gridsize**3
close(unit=unit)
यह मेरे द्वारा उपयोग की जाने वाली मशीन पर प्रति फ़ाइल लगभग 25 सेकंड लेता है। इसने मुझे लंबे होने के नाते मारा और इसलिए मैंने आगे बढ़कर पायथन में निम्नलिखित काम किया:
import numpy
mmap=numpy.memmap('T.out',dtype='float32',mode='r',offset=4,\
shape=(512,512,512),order='F')
mini=numpy.amin(mmap)
maxi=numpy.amax(mmap)
mean=numpy.mean(mmap)
अब, मुझे उम्मीद थी कि यह तेजी से होगा, लेकिन मैं वास्तव में उड़ा दिया गया था। यह समान परिस्थितियों में एक सेकंड से भी कम समय लेता है। इसका मतलब मेरे फोरट्रान रूटीन से मिलता है (जिसे मैं 128-बिट फ़्लोट के साथ चलाता था, इसलिए मैं किसी तरह इस पर अधिक विश्वास करता हूं) लेकिन केवल 7 वें महत्वपूर्ण अंक पर।
सुन्न इतनी तेजी से कैसे हो सकता है? मेरा मतलब है कि आपको इन मूल्यों को खोजने के लिए किसी सरणी की प्रत्येक प्रविष्टि को देखना होगा, है ना? क्या मैं अपने फोरट्रान रूटीन में कुछ ज्यादा ही बेवकूफी कर रहा हूं ताकि इसे अधिक समय लग सके?
संपादित करें:
टिप्पणियों में सवालों के जवाब देने के लिए:
- हां, मैंने भी 32-बिट और 64-बिट फ्लोट्स के साथ फोरट्रान रूटीन को चलाया, लेकिन इसका प्रदर्शन पर कोई प्रभाव नहीं पड़ा।
- मैंने उपयोग किया है
iso_fortran_env
जो 128-बिट फ़्लोट प्रदान करता है। - 32-बिट फ्लोट्स का उपयोग करना, मेरा मतलब काफी हद तक बंद है, लेकिन सटीक वास्तव में एक मुद्दा है।
- मैंने अलग-अलग क्रम में अलग-अलग फ़ाइलों पर दोनों रूटीन चलाए, इसलिए मेरे अनुमान की तुलना में कैशिंग उचित होना चाहिए था?
- मैंने वास्तव में सांसद को खोलने की कोशिश की, लेकिन एक ही समय में विभिन्न पदों पर फ़ाइल से पढ़ने के लिए। आपकी टिप्पणियों और उत्तरों को पढ़ने के बाद लगता है कि यह वास्तव में बेवकूफी भरा है और इसने दिनचर्या को बहुत लंबा बना दिया है। मैं इसे सरणी के संचालन पर एक कोशिश दे सकता हूं, लेकिन शायद यह भी आवश्यक नहीं होगा।
- फ़ाइलें वास्तव में आकार में 1 / 2G हैं, यह एक टाइपो था, धन्यवाद।
- मैं अब सरणी कार्यान्वयन की कोशिश करूंगा।
संपादित करें 2:
मैंने उनके जवाबों में @Alexander Vogt और @casey को लागू करने का सुझाव दिया है, और यह उतनी ही तेजी से है, numpy
लेकिन अब मेरे पास एक सटीक समस्या है क्योंकि @Luaan ने कहा कि मुझे मिल सकता है। एक 32-बिट फ्लोट सरणी का उपयोग करके गणना sum
20% से कम है। करते हुए
...
real,allocatable :: tmp (:,:,:)
double precision,allocatable :: tmp2(:,:,:)
...
tmp2=tmp
mean=sum(tmp2)/size(tmp)
...
समस्या हल करता है, लेकिन कंप्यूटिंग समय बढ़ाता है (बहुत अधिक नहीं, बल्कि विशेष रूप से)। क्या इस मुद्दे को हल करने का एक बेहतर तरीका है? मुझे फ़ाइल से एकल को डबल्स में सीधे पढ़ने का कोई तरीका नहीं मिला। और इससे कैसे numpy
बचा जाता है?
अभी तक मदद करने के लिए सभी को धन्यवाद।