気持ち早めに帰着。
ちょろり調べ事。
早くも無く遅くも無く。
POV-Rayの 3.7 RC4が来ていたり。
RC3から1年以上経ってたりするのですが、まだRCというステータスな模様。
リリースされない理由は何なのかしら?
少し使ってみたのですが、テクスチャファイルをみつけられなくてエラー。
RC3以前だと特に問題無くレンダリングできたので、指定の方法が変わった
のか何かしらバグっているのか。
あまり読まずに積んであった「BINARY HACKS」というオライリー本。
80bit浮動小数点の件で少し文書があったので読み直していたところ、
セキュアプログラミングの章でValgrindと
いうツールの存在を知ったり。メモリリークなどを検出できるという
自動検査ツールという感じ。残念ながらWindows向けの公式な移植は
無い模様。Fedoraでは使えたので、gdcでコンパイルしたバイナリをvalgrind
に食わせてみた所、phobos内のあちこちに何やら色々怪しげな点がありそうな
旨のメッセージが出たり。エラーの見方とかがイマイチよく判らないのが
ヘボなのですが、これ、うまく使えないかなぁ?と思ったり。
早くも無く遅くも無く。
ちょろっと調べ事をして終了。
昼ごろ起床。
昨日の深夜にやってた作業のまとめ。
gdcのsetupスクリプトを実行する時に、
Mercurial SCMのhgコマンドが
使えるならば、RevisionやIDをワークセットから取得して、バージョン表示に組み込む
仕掛けが入ってます。
TANEの使っているMinGW環境ではhgコマンドが使えなかった訳ですが、
それを使えるようにしてみたり。
基本的にはこのページ
を参考に進めたり。まずはPythonで書かれているという事で、Pythonの2.7を
インストール。Cドライブのルートにインストールされるのがちょっとアレな感じ
ですがまぁ良しとしよう。パスが通っていないので、MinGWのシェル上で追加したり。
続いてMercurialのソースアーカイブをダウンロード。無難にmercurial-1.9.3を使用。
説明書通りにやってもビルドできないらしいので、参考ページに従って、
python setup.py build --force -c mingw32 python setup.py install --force --skip-build
#!/bin/sh export PATH=/c/Python27:$PATH python /c/Python27/Scripts/hg $@
$ gdc -v Using built-in specs. COLLECT_GCC=C:\MinGW\gdc031_2057_462_b\bin\gdc.exe COLLECT_LTO_WRAPPER=c:/mingw/gdc031_2057_462_b/bin/../libexec/gcc/mingw32/4.6.2/lto-wrapper.exe Target: mingw32 Configured with: ../configure --build=mingw32 --with-arch=i686 --enable-languages=c,d --prefix=/mingw/gdc031_2057_462_b --enable-threads --enable-fully-dynamic-string --enable-libstdcxx-debug --enable-version-specific-runtime-libs --disable-nls --disable-win32-registry --disable-symvers --disable-werror --enable-sjlj-exceptions --with-bugurl=https://bitbucket.org/goshawk/gdc/issue --disable-bootstrap --disable-shared Thread model: win32 gcc version 4.6.2 20111026 (gdc 0.31 - r795:87241c8e754b, using dmd 2.057) (GCC)
昼ごろ起床。
そういや、DMDのwritef()でreal型の表示桁数が gdcと異なる件。
DMDのwritef()で double型を表示するとどうなるんだ?と思い
表示してみたり。使用したコンパイラはDMD2.058。
writef("%3d %1.60e\n",i,elem) ; writef("%3d %1.60e\n",i,cast(double)(elem)) ;
3 3.333333333333333333400000000000000000000000000000000000000000e-01 3 3.333333333333333148200000000000000000000000000000000000000000e-01
早くも無く遅くも無く。
並列破壊の件。最小コードで再現させてみたり。
import std.parallelism ; import std.datetime ; import std.stdio ; import std.string ; import std.math ; void main(){ auto buf1 = new real[480]; auto buf2 = new real[480]; writef("cpus=%d, PoolThreads=%d\n",totalCPUs,defaultPoolThreads()) ; StopWatch sw; sw.reset() ; sw.start() ; serial(buf1) ; sw.stop() ; writef("serial times:%s\n", sw.peek().msecs) ; sw.reset() ; sw.start() ; parallel(buf2) ; sw.stop() ; writef("parall times:%s\n", sw.peek().msecs) ; int chkres=0 ; for( int i=0 ; i<buf1.length ; i++ ){ if( buf1[i]==buf2[i] ) continue ; writef("diff %3d:%1.60e %1.60e\n",i,buf1[i],buf2[i]) ; chkres++ ; } if( chkres!=0 ){ writef("compre error!!!!!!!\n") ; } } void serial(real[] buf) { foreach(i, ref elem; buf) { elem = 1.0/cast(real)(i) ; // synchronized{ writef("%3d %1.60e\n",i,elem) ; } } } void parallel(real[] buf) { foreach(i, ref elem; taskPool.parallel(buf)) { elem = 1.0/cast(real)(i) ; // synchronized{ writef("%3d %1.60e\n",i,elem) ; } } }
OK : gdc0.31 on Fedora13(VMware(2CPU設定)) ; gdc-revision=a92d4b1f144d OK : DMD2.057 on WindowsXP(論理CPU数=2) OK : DMD2.058 on WindowsXP(論理CPU数=2) NG : gdc0.31(MinGW) on WindowsXP(論理CPU数=2) ; gdc-revision=11ae589b9a71
gdc(MinGW) : 3 3.333333333333333333423683514373792036167287733405828475952148e-001 gdc(Fedora): 3 3.333333333333333333423683514373792036167287733405828475952148e-01 DMD2.05[78]: 3 3.333333333333333333400000000000000000000000000000000000000000e-01
早くも無く遅くも無く。
並列化破壊の件。Webで検索していると、80bitFPUレジスタが一度メモリに
ストアされると64bitに丸められて結果が変わる事があるというのを知ったり。
でも、これは結果をdoubleに格納した場合。real型は10バイトでストアする
fstpt命令を使っているので問題無いような気が。
スレッドのコンテキスト切り替え時のレジスタ退避方法がまずくて
リストアしたときにdoubleに丸められてしまう場合があるとか??
早めに帰着。
並列化破壊の件。gdbで命令単位のステップ実行を行ってみて
動きを見てみたり。スレッドによって全く違う命令列を実行している
ような事は無いってのは確認できたのですが、変になっている現場を
押さえる所までには至らず。あと、real型はFPUレジスタであるところのst[0-7]
レジスタ上は10バイト(80bit)で、info regs ...で表示する事が可能
なのですが、メモリ上のreal型を表示する方法が無くて、レジスタ上の
値がメモリにどうストアされてるのかがイマイチよく判らなかったり。
因みに、gdc上は real.sizeof の値は12を返します。4byteにアライメント
されているのでこういう事になっている模様。
早くもなく遅くも無く。
並列化破壊の件。少し変な感じが見えたかも?
マンデルブロ集合の複素平面上の座標を計算するのですが、
その計算結果が怪しい感じになっている事が判ったり。
y= 0 C=-1.161029157483502693200966282560671061219181865453720092773438e+000, -2.991753325200145996161718575656607299606548622250556945800781e-001 y= 60 C=-1.161029157483502771697203570511192083358764648437500000000000e+000, -2.991753325200143809325936672394163906574249267578125000000000e-001
y= 0 C=-1.161029157483502693200966282560671061219181865453720092773438e+000, -2.991753325200145996161718575656607299606548622250556945800781e-001 y= 60 C=-1.161029157483502693200966282560671061219181865453720092773438e+000, -2.991753325200143645340358083961618262947013135999441146850586e-001
ra/rb= 3.333333333333333333423683514373792036167287733405828475952148e-001 da/db= 3.333333333333333148296162562473909929394721984863281250000000e-001
y= 0 C=-1.161029157483502771697203570511192083358764648437500000000000e+000, -2.991753325200146029771985922707244753837585449218750000000000e-001 y= 60 C=-1.161029157483502771697203570511192083358764648437500000000000e+000, -2.991753325200143809325936672394163906574249267578125000000000e-001
早めに帰着。
並列化で絵が壊れる件を少し追いかけてみるも尻尾を掴めず。
あまりの眠さに急速停止。
昼ごろ起床。
MPFRを使う為にD用にポーティングを用意してみたり。MPFRをCで使えば、
mpf2mpfr.hなる便利なヘッダが存在していて、本体コードは一切いじらずに
mpf系関数をmpfr系関数に置き換えてくれる様ですが、Dではそういうのは
できない(?)ので、手で本体コードをMPFRに対応する感じだったり。
結論から言うとやっぱダメ。シングルスレッドで実行すれば一応期待通りの
絵を描いてくれるので、マルチスレッドがダメという感じ。
mpfr_buildopt_tls_p() というTLSサポートでビルドしているか否かを
返す関数は non_zero を返す(即ちTLSサポート有りでビルドされている)ので、
何かしらバグってるか、Dとの相性が悪いか、その他色々原因があるのかも
知れません。でも追いかけきれず(^^;
GMP/MPFRを使わない方のマルチスレッド化。拡大率を上げていくと、
何故かスレッドによって結果が少し変わったり。元々GMP/MPFRを使わないと拡大率を
上げた場合に浮動小数点数解像度限界によりモザイク模様になる場合が
あるのですが、受け持つスレッドによって解像度限界に達している場合と
そうでない場合とがあったり。シングルスレッドだとどのピクセルも
モザイク模様にならないので、マルチスレッドによりどこか壊れている
ような気がしたりも。うーむ、なんかうまくいかないなぁ。
起きたら午後もいい時間。寝すぎ。
みすず学苑のTVCM。以前、電車の窓に広告が貼ってあったのを見たのですが、
あまりの謎さ加減に首を傾げた覚えがあったのを思い出したり。
先日のstd.parallelismを使う実験の続き。ちょっと勘違いしてましたが、
taskPool.parallel()を使うのは、MinGWのgdc-0.31でコンパイルしてもリンク
に失敗しないし実行してもSegfaultしませんでした。
そんな訳で使用するスレッド数を変える方法などを調べたり試したり。
マンデルブロ集合プログラムをマルチスレッド化してみたり。
単純に1ライン(画像の横幅)分の計算を行うメソッドを用意して、それを
taskPool.parallel()で画像の高さ分を並列化するという感じ。
ひとまずGMPを使わないD言語ネイティブな方は並列化できて、それとなく
CPU使用率100%で動作するようになったのですが、GMPを使う方がダメっぽい。
そもそもスレッドセーフじゃないのかもと思ったのですが、GMPと
マルチスレッドを組み合わせて使っている例がWebを検索しても見当たらず、
マルチスレッドが いけるのかいけないの情報も得られず。
んー、コードをあれこれいじって挙動を調べてみたのですが、
やっぱりGMPはスレッドセーフじゃないような気が。
GMPとMPFRの関係について勘違いをしてました。GMP内には
多倍長浮動小数点演算を行うmpf_*系の関数というのがあります。
これの上位(?)機能版がMPFRという事でした。Dのポーティングでは
GMPだけしか行っていないので、MPFRは使っていないという事に
なります。
そんな訳で、マンデルブロ集合プログラムはMPFRは使ってなくて、
GMPだけの使用になってますので、UseMPFRというスイッチは
正しくはUseMPF が正解です(^^;;;;
で、話はスレッドセーフに戻るのですが、GMPもMPFRもMinGWで
gcc/gdcをコンパイルするようになった時に入れたきりなので、
GMPは4.x、MPFRは2.xでした。現在はGMPは5.0、MPFRは3.1になっている
のですが、MPFRの方はTLSを用いてスレッドセーフになっている
らしいというのが判ったり。因みに、ここんところを探っていて、
GMP内mpfとMPFRの違いに気づいた訳です(^^;
早めに帰着。
アバター観たり。CM入るの結構邪魔に思ったり。しかた無いですが。
早くも無く遅くも無く。
DMD2.058が来てたり。さて、gdcに来るかどうか.......
std.parallelismを使う実験。MinGWビルドではSegfaultでダメなのですが、
Fedoraの方では実行可能でした。
void serial(double[] logs) { foreach(i, ref elem; logs) { elem = log(i + 1.0); } }
void parallel(double[] logs) { foreach(i, ref elem; taskPool.parallel(logs)) { elem = log(i + 1.0); } }
早めに帰着。
あまりの眠さに急速停止。
早めに帰着。
並列化を行うのを支援するphobosのライブラリに、std.parallelismなる
ものがあるのですが、DMD2.053で追加された物のため、日本語訳がありません。
サンプルをコンパイルしてみたのですが、gdc031だとリンクに失敗したり。
例のgdcバグの変種だと思われます。
gdc030の最終版ではリンクに成功。でも、実行するとSegfaultしたり。
うまくいかないなぁ。
DMDの2.058はまだ出てません。gdcも2.058に追従してくるかはまだ不明。
gdcも大分壊れている気がしなくもありませんが、2.058の取り込みで直る
だろうか?
早めに帰着。
ちょろり調べ事をして終了。
AM中に目が覚めつつも、もそもそしてたら午後もいい時間。
そういや録画に使っているHDDの空き容量が無くなったのですが、
自動削除で古い順に消えていってます。このとき、古いんだけどまだ一度も
見ていない物がどうなるか?と思っていたのですが、見ているかどうかに
関係無く古い順に消えてくというのが判ったり。それにしても2TBも
あっという間に埋まってしまうもんなんだなぁ(^^;
起きたら午後もいい時間。寝すぎ。
gdcにAndroid対応がマージされてたり。
早めに帰着。
あまりの眠さに急速停止。
気持ち早めに帰着。
OpenGL描画をGDIなBITMAPに行う方法を調べてました。一応できる事は
判ったのですが、OpenGLの
glGetString(GL_RENDERER)とglGetString(GL_VERSION)が、「GDI Generic 1.1.0」を
返していて、シェーダーとかは使えないという感じだったり。
GDIを使うと文字表示など割と自由になるので、用途によっては
使い勝手がかなり上がると思うのですが、描画性能はかなり落ちる
ようです。なかなか良いとこ取りにはならないと言ったところでしょうか。
少し早めに帰着。
ちょろっと調べ事。
気持ち早めに帰着。
ちょっと調べ事。
気持ち早めに帰着。
今週はgdcの動きが無いな。
そういや、以前、
std/socketstream.dが変なシンボルを要求してリンクに失敗する
というのがありましたが(てかありますが)、それとほぼ同じ
リンクエラーについての報告がgdcの掲示板に
挙がっていたり。
これで正式に直るであろう。
AM中に起床。
少しマシになった所で洗濯したり買出しに出たり。
「ONEPIECE(65)」。なるほどこういう展開になりますか。
最後はどう決着が付くんだろう。続きが気になります。
一日中寝てたり。
ちょろっと起きては、しんどくなって寝ての繰り返し。
早めに帰着。
あまり回復せず急速停止。
早くも無く遅くも無く。
絶不調で急速停止。
気持ち早めに帰着。なんか喉の調子が悪いかも。
gcc-4.7.x対応のMinGW gdcでコンパイルした実行バイナリがずっこける件を
少し調べてみたり。rt/dmain2.d というコードの中の unittest実行で
ずっこけている事が判ってみたり。更に追いかけてみると
foreach( m; ModuleInfo ){...} というコードがあり、mがnullでなければ
m.unitTestが実行されてモジュール毎にunittestが実行されるという仕掛け
のようです。で、この m に謎の値が入っている場合があって、
Segfaultするという流れ。ModuleInfoをgdbで表示できるのかな?と
思ったのですが表示できず。うーむ。