<< (newer post) (older post) >>     

Julia の整理してない情報を突っ込んでおくメモ


線形計算はデフォルトでは OpenBLAS を使っているが,問題によって適切な thread 数が異なるので、きちんと設定しないとかえって遅いことが多いかも.

設定は Julia の中で blas_set_num_threads() に thread 数を入れることで行う. 本気で大きな計算をする前に、適した thread 数をその状況に合わせて調べておくと良さそうだ.こんな感じのコードでチェック可能.

N = 10
A = randn(N,N);
eigvals(A); # JIT などの影響で一回目の計算だけ遅いかもしれない.よって測定なしで一回計算しておく.

N = 1000
A = randn(N,N);

@time eigvals(A); # デフォルトではどれくらいの時間か測定

println()

for i in 1:8 
  blas_set_num_threads(i) # thread 数を変えてみてチェックする
  @time eigvals(A);
end

小さい問題だと thread 数が 1 の方が速かったりする. juliabox.org で試してみると、N = 2000 だと num = 4 が最速だが、N = 1000 では num = 1 が最速になる.やはり規模に依存するなあ.

手元の PC だと、N = 1000, 2000 のいずれも num = 1 が最速だったが、N = 4000 では num = 2 が最速になる.しかもデフォルトは num = 5 か num = 6 になっている気配. こちらで設定しないと、どうも内部的な情報をもとに自動で動的に変えているようだが、あまり上手な自動設定ではないということのようだ.

あと、出力をみるときに、かかった全体時間のみに注意がいきがちだが、ガベージコレクションにかかった時間がどうなっているかもきっと重要なのでよく見ておくべし.


v0.5 では package ApproxFun の最初の using での precompile で失敗する.これは julia 本体の blasfunc コマンドが @blasfunc に変わったため.

よって,ApproxFun のソースの中で blasfunc を使っている箇所(この時点で は src/LinearAlgebra/hesseneigs.jl に 4箇所程度あった) を @blasfunc に書き換えれば using できるようになる.


v0.5 で package ApproxFun を上の処方箋に従って precompile に成功するも、roots コマンドを実行しようとするとで hseqr64_ なる命令は知らないとしてエラーになる件

これはやはり src/LinearAlgebra/hesseneigs.jl にある、@blasfunc 周辺で起きる問題.

どうやら、hseqr64_ ではなく、DHSEQR64_ (頭に D がついている)を渡さないといけないのに、D が欠けてしまうのか、最初からついていないか、それとも @blasfunc コマンド内部の原因で, ともかく、うまくこの文字列になってないらしい. そこでとりあえず、この 57 行目を

ccall(( $("DHSEQR64_") ,LAPACK.liblapack),

とハードコードで修正すると動く(openblas を使っている場合).感心しないなあ.

ccall(($(BLAS.@blasfunc("DHSEQR")),LAPACK.liblapack),

などと変更しても良いいんじゃね?と思ったが、残念ながらこちらはエラーで落ちる. どうも、D が欠ける欠けない以前に、@blasfunc の中でなにかチェックしていて、これにバグがあるような気もする. ソースをこれ以上おっかけるのは面倒なのでまあいいや.

とりあえず、上の修正でごまかそう(openblas でない場合は、”DHSEQR” とすれば良さそうだ).


v0.5 で package Gaston を using しようとするとエラーが出て動かない件

gnuplot を呼び出してグラフを描く package である Gaston は、積極的に使いたい package だが、あまりメンテされてなくてそのままでは v0.5 では動かない. これは、 Gaston/src/gaston_types.jl の 161 行などにある、Range1 という type は今の Julia では古すぎて使えなくて、 UnitRange という名前に直さないといけないためだ. 他のファイルも含めて全部で 3箇所ほどにこれがあるので、これらを直せば良い.

あと、using Gaston のあとに gnuplot の term を設定しないと結局動かないかもな. よって

using Gaston
set_terminal("wxt")

などと最初にしてから、例えば

gaston_demo()

とすればデモも問題なく動く. ただし、このデモは 20枚ものグラフを別ウィンドウで出すので、ちょっと壮観というか、うざいかもw

Gaston は速い!

gnuplot に慣れているならば、実は plot 系 package としてはこれが一番スムースで爆速な気がする. 3D plot を掴んでグリグリ回せるしね.

cygwin が入っている場合、gnuplot として cygwin の gnuplot が呼ばれると、うまく動かない.

これは、cygwin の gnuplot が wxt を含む多くの window 系 terminal を持っていないせいである. コンパイルしなおしてもいいが、windows 用バイナリが既に存在するので、そちらを使ったほうがいい. よってこの場合は、次のいずれかをやっておく.

  1. cygwin のものを名前を変えるなどして呼ばれないようにして、windows 用 の gnuplot が呼ばれるようにする.
  2. windows 用の gnuplot を呼ぶように Gaston のソースをいじる.
  3. (command prompt の) path を設定して、windows 用の gnuplot が先に呼ばれるようにしておく.
  4. (command prompt の) path を見て、path の「先に読まれる場所」に windows 用の gnuplot をコピーしておく.

私は結局 4 にしたが、まあどれでもいいだろう.

WARNING はうざいほど出る.そのほぼ全てが、Gaston が古い Julia の文法を使っているせいだ.

一括して直しておくといいんじゃないかなあ.

Gaston のマニュアルは

https://bitbucket.org/mbaz/gaston/downloads

にある.なんか未完成な匂いがするぞ.


Julia の起動にかかる時間、コンパイルにかかる時間、プログラム実行にかかる時間

シェルから

time julia -e 'exit()'

とすれば、起動にかかる時間がおおよそ見積もれて、例えば 自分の cygwin/Windows8.1/PC(T7500) 環境だと

real  0m4.313s
user  0m0.000s
sys   0m0.046s

という感じで、体感的には juila の起動にかかる時間は約 4.2-4.3 秒程度になる. (exit() もコンパイルされているかもしれんが)

そして、

  1. 全実行時間 = 起動にかかる時間 + JITコンパイルにかかる時間 + プログラム実行にかかる時間
    であることと、
  2. プログラム実行にかかる時間 は tic(), toc() で測れる

ことから、コンパイルにかかる時間とプログラム実行にかかる時間も見積もれる. ある小さなプログラムで

time julia hogehoge.jl

としてこれをやってみたところ、全実行時間のための time の結果が

real 0m4.711s
user 0m0.015s
sys  0m0.031s

で、tic(), toq()(toc()の寡黙版) で測ったプログラム実行時間が

 0.514969... seconds

だったので、JIT コンパイルにかかった時間はほぼゼロに見えるほど小さいということになる.

う~ん、他の数字に比べるとそれにしても julia 自身の起動が遅い.もっと速くなんねーかな.そうすると小回りの効くスクリプト的な使い方も気軽にできて便利なんだが.

もちろん、Julia の REPL から

include("hogehoge.jl") 

などとしてプログラムを起動してもいいんだけど、STDOUT/STDIN の扱いが変わってしまうしなあ. まあ真面目に file を指定して書き込むか.


グローバル変数で変更のないものは const をつけるべし!

例えば、変更をうけない

L = 2.0

なんていう変数があるなら、

const L = 2.0

とすべき.

こうした変数に const をつけるだけで、プログラムの実行が 10-20倍 も速くなることがあった.正直驚いた…


プログラムを(シェルから)実行する際のオプション

例えば hogehoge.jl を動かすとして、通常は

julia hogehoge.jl

として実行するのだが、「もうバグはないぜ、へへへ」「IEEE 規格にはこだわらないぜ」というスタンスなら

julia --check-bounds=no --math-mode=fast hogehoge.jl

として実行すると、10-20% ぐらい実行が速くなることが多い.

ちなみに、最適化オプションである -O を用いると何故か遅くなったりすることがあるので、試してみてから使うべし.

     << (newer post) (older post) >>