パスワードを忘れた? アカウント作成
931703 journal
日記

t-nissieの日記: 【電脳】FFTWのOpenMP並列でいまいち3次元r2c, c2rの速さが出ない【その2】 1

日記 by t-nissie

以下のようなプログラムでいろいろ試しています。
topで見るかぎりあまり並列化されていないようです。
フーリエ変換する三次元配列のサイズが小さいせいか
あまり並列化しないほうが速いのかもしれません。
FFTW_PATIENTだとdfftw_plan_dft_r2c_3dなどで
planを作るのに数分かかります。以下で試したところ
fftw3_threadsライブラリを使うよりfftw3_ompを
使うほうが速いようです。16-bit alignmentはされて
いるようなのでSSE2は使われているものと思います。
どんなplanになったかを表示する関数はないのかしらん。
fftw_describe(plan), fftw_show(plan)みたいな。
これから、OpenMPでネストして速くなるか検証する
予定。

$ for i in `jot 9`; do OMP_NUM_THREADS=4 ./r2c_3d_test_omp 32 32 160 1000 4 | grep ends; done ; \
  for i in `jot 9`; do OMP_NUM_THREADS=4 ./r2c_3d_test_threads 32 32 160 1000 4 | grep ends; done
FFT ends   3.17200
FFT ends   3.02300
FFT ends   3.19100
FFT ends   3.06800
FFT ends   3.23800
FFT ends   3.12100
FFT ends   3.20900
FFT ends   3.24900
FFT ends   3.19000
FFT ends   4.69000
FFT ends   4.56500
FFT ends   4.61900
FFT ends   4.64000
FFT ends   4.63200
FFT ends   4.62900
FFT ends   4.65000
FFT ends   4.60900
FFT ends   4.69600

# -*-Makefile-*- for testing FFTW3
##
FC = gfortran
FFLAGS = -Wall -ffree-form -O3 -pipe -fopenmp -fopenmp
all: r2c_3d_test_threads r2c_3d_test_omp
r2c_3d_test_threads: r2c_3d_test.o address.o
        gfortran $(FFLAGS) -lfftw3 -lfftw3_threads -o $@ $^
r2c_3d_test_omp:     r2c_3d_test.o address.o
        gfortran $(FFLAGS) -lfftw3 -lfftw3_omp     -o $@ $^
clean:
        rm -f *.o

! r2c_3d_test.F -*-f90-*-
! Time-stamp: <2011-11-28 20:21:46 t-nissie>
!!
#if defined(__PGI) || defined(SR11000) || defined(__sparc)
#  define command_argument_count iargc
#  define get_command_argument getarg
#endif
 
program r2c_3d_test
  implicit none
  real*8,     allocatable :: r(:,:,:)
  complex*16, allocatable :: c(:,:,:)
  integer*8               :: plan_r2c, plan_c2r, address, count0, count1, count_rate
  character(len=30)       :: str
  integer                 :: Lx, Ly, Lz, M, NTHREADS, i, j, ireturn
  real*8                  :: N_inv
# include "fftw3.f"
 
  call get_command_argument(1,str); read(str,*) Lx
  call get_command_argument(2,str); read(str,*) Ly
  call get_command_argument(3,str); read(str,*) Lz
  call get_command_argument(4,str); read(str,*) M
  call get_command_argument(4,str); read(str,*) NTHREADS
 
  N_inv = 1.0d0 / Lx / Ly / Lz
 
  call dfftw_init_threads(ireturn)
  call dfftw_plan_with_nthreads(NTHREADS)
 
  allocate(r(0:Lx-1, 0:Ly-1, 0:Lz-1))
  allocate(c(0:Lx/2, 0:Ly-1, 0:Lz-1))
  write (*,'(a,z16.16)') 'Address of r = 0x', address(r) ! Check 16-bit alignment,
  write (*,'(a,z16.16)') 'Address of c = 0x', address(c) ! or SSE2 won't be used.
 
  call dfftw_plan_dft_r2c_3d(plan_r2c, Lx, Ly, Lz, r, c, FFTW_PATIENT)
  call dfftw_plan_dft_c2r_3d(plan_c2r, Lx, Ly, Lz, c, r, FFTW_PATIENT)
 
  r(:,:,:) = 0.1d0
 
  write(6,'(a)') 'FFT starts'
  call flush(6)
  call system_clock(count0)
 
  do i = 1, M
     call dfftw_execute(plan_r2c)
     !$omp parallel do
     do j = 0, Lz-1
        c(:,:,j) = c(:,:,j) * N_inv
     end do
     !$omp end parallel do
     call dfftw_execute(plan_c2r)
  end do
 
  call system_clock(count1, count_rate)
  write(6,'(a,f10.5)') 'FFT ends', dble(count1-count0)/count_rate
 
  call dfftw_cleanup_threads(ireturn)
end program r2c_3d_test
 
!Local variables:
!  compile-command: "make -k && ./r2c_3d_test 32 32 160 100 4"
!End:

unsigned long address_(void *x)
{
  return (unsigned long)x;
}

typodupeerror

普通のやつらの下を行け -- バッドノウハウ専門家

読み込み中...