Tôi có một "mảng mặt nạ" mà tôi muốn thêm vào mảng khác - Nói cách khác, tôi có 3 mảng, A
, B
và mask
. Câu hỏi của tôi là cách hiệu quả nhất (về mặt thời gian thực hiện) là gì để lưu trữ mặt nạ (như một mảng logic, như là một mảng thực của những cái và số không)?Cách hiệu quả nhất để thêm một mảng mặt nạ vào một fortran
EDIT
Dưới đây là một chương trình đồ chơi bạn có thể chơi xung quanh với (nếu bạn có mpif77):
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
kết quả của tôi:
(gfortran -O2)
==== 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 -funroll-vòng -ffast-math)
==== 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 -fast) - trên một máy rất cũ
==== 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) - trên rất cũ máy
==== 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
Tất nhiên, có một vài điều mà có thể ảnh hưởng này - khả năng biên dịch để vectorize các vòng ví dụ - như vậy là có một quy tắc của ngón tay cái về làm thế nào một cái gì đó như thế này cần đạt được?
Mã tôi đang làm việc là f77 (không phải lựa chọn của tôi) - vì vậy tôi tránh 'ở đâu' vì lý do đó. – mgilson
Và có, tôi có nghĩa là về thời gian dành cho chức năng. Tôi sẽ chỉnh sửa. – mgilson
Tôi có thể trả lời nhanh hơn bằng cách sử dụng 'gfortran' vì đó là trình biên dịch duy nhất mà tôi có quyền truy cập dễ dàng - nhưng mã có nghĩa là chạy trên tất cả các loại nền tảng với tất cả các loại trình biên dịch, vì vậy tôi đã tự hỏi có một quy tắc chung cho loại điều này. Nếu không có quy tắc chung, có lẽ không đáng lo ngại về ... – mgilson