しとしとと氷雨の降る師走の土曜日。今日もシコシコプログラムを作る。
Pthreadを使って,Fedora Core 1を突っ込んだP4 2.8C GHzのマシンでベンチマークテストをする。多倍長でやってみると,どうも倍精度よか性能向上がいいようである。うーむ,これはすげぇ。多倍長だと内積計算でもmulti-thread化の効果期待できそうである。MPIBNCpackが一段落ついたと思ったら,大本のBNCpackを改良しなきゃならんのかぁ。全く高速化技法って尽きることがないよのう。
で,気がついたのだが,このマシンで2threadsを使ったプログラムを走らせて,timeコマンドを使って時間計測をすると
real 1m28.966s
user 2m55.700s
sys 0m0.200s
などという結果になる。最初見た時は,松田優作ではないが,「なんじゃこりゃー」と叫んでしまった。どうやら2thread走らせると,それぞれのthreadのuser timeを合計した値が出てくるらしい。実際にはrealの時間で処理が終わっている。
で,times関数をmanしてみると,案の定であった。しかもLinuxの場合,こちとらThreadを使った気になっていても,KernelではProcessとして認識しているようである。実装がそうなっているからなんだそーだが,これって手抜きなの?
ためしに,メイン処理からtimes関数を呼び出してみると,開始時点では
User Time : 109
System Time: 14
CUser Time : 1029
CSystem Time: 1
となっているのに対して,終了時には
User Time : 113
System Time: 14
CUser Time : 17457
CSystem Time: 4
という有様である。この時走った2threadのそれぞれで同じくtimes関数を呼び出してみると,thread 0では
Thread 0 開始時
User Time : 0
System Time: 0
CUser Time : 0
CSystem Time: 0
Thread 0 終了時
User Time : 8206
System Time: 1
CUser Time : 0
CSystem Time: 0
となり,thread 1では
Thread 1 開始時
User Time : 0
System Time: 0
CUser Time : 0
CSystem Time: 0
Thread 1 終了時
User Time : 8222
System Time: 2
CUser Time : 0
CSystem Time: 0
となっている。つまり,メイン処理部ではtms構造体のうちcutimeが,それぞれのThreadに費やされたutimeの合計値を保持するようになっている。これでは1 CPUで行ってきた時間計測手法が全く通用しない。
結局,実時間をgettimeofday関数を呼び出して計測することにしたが,おかげでBNCpackの時間計測関数がまた増えてしまった。今までは1CPUマシンでしか動かしたことがなかったので,times関数を使うget_sec関数という奴しか実装してなかったのである。今回,新たにgettimeofday関数を使う,get_real_sec関数なるものを実装したのである。ああめんどくさ。
しかし時間計測はやっかいである。今回生じたMT環境での事柄もそうだが,大体,ベンチマークなんぞ,実行するたんびに微妙に食い違うのはざら,というより当たり前のことである。バックで様々なプロセスが蠢いているためでもあろうし,割り込みが入るタイミングも違うであろうし,何よりPCのハードウェアタイマなんてどこまで当てになるのやら。信頼性があるようなら,NTPなんて無くなっていいはずである。で,NTPなんぞマジメにインストールしようモンなら,そこで修正される時間も問題になろうし,ニュースにもならない「うるう秒」も入り込むかも知れないし,大体,今こうやってプログラムを動作させている3D空間中の「時間」とやらが完全に一体化しているのかどうかも怪しい。ああもぉキリがないのである。故に時間計測なんぞにうつつを抜かしてはいけない,という結論を得る。
今日で一仕事終える予定だったのに,またぞろやることが増えてしまった。ストレスを新たに抱え,明日に備えて「わしズム Vol.9」を読みながら寝ることにする。