पर एक मुखौटा सरणी जोड़ने का सबसे प्रभावी तरीका मेरे पास एक "मुखौटा सरणी" है जिसे मैं किसी अन्य सरणी में जोड़ना चाहता हूं - दूसरे शब्दों में, मेरे पास 3 एरे, A
, B
और mask
हैं। मेरा सवाल यह है कि मास्क को स्टोर करने के लिए सबसे प्रभावी (निष्पादन समय के मामले में) क्या है (लॉजिकल सरणी के रूप में, लोगों और शून्यों की वास्तविक सरणी के रूप में)?किसी अन्य फोर्टन
program main
implicit None
include 'mpif.h'
integer, parameter :: ntry=10000
integer, parameter :: asize=1000000
real,dimension(asize) :: A,B,maskr
logical,dimension(asize) :: mask
real*8 :: dd,dt,dtave,dtbest
integer i
do i=1,asize
maskr(i)=mod(i,2)
mask(i)=.False.
if(mod(i,2).eq.0) mask(i)=.True.
enddo
A=1.0; B=1.0
dtbest=1d33
dtave=0.0
do i=1,ntry
dt=mpi_wtime()
call add_arrays_logical(asize,A,B,mask)
dt=mpi_wtime()-dt
dtbest=min(dt,dtbest)
dtave=dtave+dt
enddo
print*,"==== logical ==="
print*,"Average",dtave/ntry
print*,"Best",dtbest
A=1.0; B=1.0
dtbest=1d33
dtave=0.0
do i=1,ntry
dt=mpi_wtime()
call add_arrays_real(asize,A,B,maskr)
dt=mpi_wtime()-dt
dtbest=min(dt,dtbest)
dtave=dtave+dt
enddo
print*,"==== Real ==="
print*,"Average",dtave/ntry
print*,"Best",dtbest
A=1.0; B=1.0
dtbest=1d33
dtave=0.0
do i=1,ntry
dt=mpi_wtime()
where(mask) A=A+B
dt=mpi_wtime()-dt
dtbest=min(dt,dtbest)
dtave=dtave+dt
enddo
print*,"==== Where ===="
print*,"Average",dtave/ntry
print*,"Best",dtbest
end
subroutine add_arrays_logical(n,A,B,mask)
integer n
real A(n),B(n)
logical mask(n)
do i=1,n
if(mask(i))then
A(i)=A(i)+B(i)
endif
enddo
end
subroutine add_arrays_real(n,A,B,mask)
integer n
real A(n),B(n),mask(n)
do i=1,n
A(i)=A(i)+mask(i)*B(i)
enddo
end
मेरे परिणाम:
(gfortran -O2)
संपादित
यहाँ (यदि आप mpif77 है) आप के साथ चारों ओर खेल सकते हैं एक खिलौना कार्यक्रम है
==== logical ===
Average 1.52590200901031483E-003
Best 1.48987770080566406E-003
==== Real ===
Average 1.78022863864898680E-003
Best 1.74498558044433594E-003
==== Where ====
Average 1.48216445446014400E-003
Best 1.44505500793457031E-003
(gfortran -O3 -ffast-गणित -funroll-लूप)
==== logical ===
Average 1.47997992038726811E-003
Best 1.44982337951660156E-003
==== Real ===
Average 1.40655457973480223E-003
Best 1.37186050415039063E-003
==== Where ====
Average 1.48403010368347165E-003
Best 1.45006179809570313E-003
(pfg90 फास्ट) - एक बहुत पुरानी मशीन पर
==== logical ===
Average 5.4871437072753909E-003
Best 5.4519176483154297E-003
==== Real ===
Average 4.6096980571746831E-003
Best 4.5847892761230469E-003
==== Where ====
Average 5.3572671413421634E-003
Best 5.3288936614990234E-003
(pfg90 -O2) - एक बहुत पर compilers उदाहरण के लिए छोरों vectorize करने की क्षमता - - पुराने मशीन
==== logical ===
Average 5.4929971456527714E-003
Best 5.4569244384765625E-003
==== Real ===
Average 5.5974062204360965E-003
Best 5.5701732635498047E-003
==== Where ====
Average 5.3811835527420044E-003
Best 5.3341388702392578E-003
बेशक
, कुछ चीजें हैं जो इस को प्रभावित कर सकता है, इसलिए वहाँ कैसे कुछ इस तरह हासिल किया जाना चाहिए के बारे में एक सामान्य नियम के है?
जिस कोड के साथ मैं काम कर रहा हूं वह f77 है (मेरी पसंद नहीं) - इसलिए मैं उस कारण से 'कहां' से परहेज कर रहा हूं। – mgilson
और हाँ, मेरा मतलब फ़ंक्शन में बिताए गए समय के संदर्भ में है। मैं संपादित करूंगा। – mgilson
मैं उत्तर दे सकता हूं जो 'gfortran' का उपयोग कर तेज़ी से है क्योंकि यह एकमात्र संकलक है जिसकी मुझे वास्तव में आसान पहुंच है - लेकिन कोड सभी प्रकार के प्लेटफार्मों के साथ सभी प्रकार के प्लेटफार्मों पर चलने वाला है, इसलिए मैं सोच रहा था कि क्या इस तरह की चीज़ के लिए अंगूठे का नियम है। अगर अंगूठे का नियम नहीं है, तो शायद इसके बारे में चिंता करने योग्य नहीं है ... – mgilson