この文章はFFTW3の使い方を説明するものではない。
- gcc
- gfortran
- OCaml(
yum install ocaml
とかでインストールできる。) - autoconf
- automake(
apt-get install autoconf automake libtool
とかでインストールできる。) - libtool
- fig2dev(MacPortsなら
port install transfig
でインストールできる。) - w3m(Firefoxなどのブラウザでも可。
wget
やcurl
ではリダイレクトのせいでうまくいかないようだった。)
$ git clone https://github.com/FFTW/fftw3.git fftw3
$ cd fftw3
$ git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/experimental-simd
remotes/origin/master
$ git checkout -b mybranch origin/master # そのorigin/masterからmybranchをブランチ
$ git branch -a
master
* mybranch
remotes/origin/HEAD -> origin/master
remotes/origin/experimental-simd
remotes/origin/master
$ ./bootstrap.sh --enable-openmp --enable-sse2 --enable-avx2
$ make -j4
CPUとアセンブラが対応していれば、version 3.3.5から有効になるであろうオプション--enable-avx2
が使える。
--enable-fma
は--enable-avx2
の場合は自動的に有効になる?
倍精度の実数⇆複素数の3次元FFTで使ってみる。上の『準備』に続けて、
$ git clone https://gist.github.com/bf784a5bc070a6f60a76.git SoA
$ echo SoA >> .gitignore
$ echo '*dft/simd/avx*-128-fma/*.c' >> .gitignore
$ git status
$ cd SoA
$ w3m https://sourceforge.net/p/loto/code/HEAD/tree/feram/branches/z_star_r/src/feram_fftw_SoA_out.F?format=raw
$ w3m https://sourceforge.net/p/loto/code/HEAD/tree/feram/branches/z_star_r/src/feram_fftw_wisdom_timing.F?format=raw
$ make -j3
$ for len in 1 2 3 4 5 6; do OMP_NUM_THREADS=2 ./feram_fftw_SoA_out_len 100 64 64 64 1 $len FFTW_PATIENT 2> /dev/null; done
はじめにこのgistをcloneし、次にw3m
コマンドでferam
のリポジトリ
https://sourceforge.net/p/loto/code/HEAD/tree/feram/branches/z_star_r/src/ から
feram_fftw_SoA_out.F
とferam_fftw_wisdom_timing.F
とをダウンロードしている。
最後の実行結果は2.5 GHz (i5-3210M) dual-core Intel Core i5 Ivy Bridge processorでは
100 1 64 64 64 1 262144 out 2 0.175 13.5
100 2 64 64 64 1 262144 out 2 0.534 8.8
100 3 64 64 64 1 262144 out 2 0.729 9.7
100 4 64 64 64 1 262144 out 2 0.971 9.7
100 5 64 64 64 1 262144 out 2 1.205 9.8
100 6 64 64 64 1 262144 out 2 1.468 9.6
となる。最後がGFLOPS値。 このようにSoA (Structure of Array) でAarryの数を1より大きくすると遅くなるので、 FFTW3の内部の変更で全部が最高の値 (13.5) になるようにしたい。 簡単なはずだが、敷居が高い。
americium02でperfでプロファイリングした。
何回かferam_fftw_SoA_out_len
を実行して、最速になるwisdom_SoA
をwisdom
として残す。
$ mkdir perf_len1_8k_96x96x96_1
$ cd perf_len1_8k_96x96x96_1
$ numactl --cpubind 1 ../feram_fftw_SoA_out_len 1000 96 96 96 1 1 FFTW_PATIENT
$ numactl --cpubind 1 ../feram_fftw_SoA_out_len 1000 96 96 96 1 1 FFTW_PATIENT
$ mv wisdom_SoA wisdom
$ numactl --cpubind 1 ../feram_fftw_SoA_out_len 1000 96 96 96 1 1 FFTW_PATIENT
$ sh ../../tools/fftw-wisdom-to-conf < wisdom # I do not know if it helps you or not.
10秒前後になるようにイテレーションの回数を調節してperfでプロファイリングする。
$ numactl --cpubind 1 perf record ../feram_fftw_SoA_out_len 8000 96 96 96 1 1 FFTW_PATIENT
feram_fftw_SoA_out_len.F:30: Successfully imported FFTW wisdom in current directory.
feram_fftw_SoA_out_len.F:63: flags = FFTW_PATIENT
8000 1 96 96 96 1 884736 out 12 8.312 84.1
[ perf record: Woken up 59 times to write data ]
[ perf record: Captured and wrote 15.258 MB perf.data (~666622 samples) ]
$ perf report > perf.report
なお、kernel云々のperfがエラーを出したら、
# echo 0 > /proc/sys/kernel/kptr_restrict
とする。