<<前の10件

2010-2-5[金] Win環境でのSTLport 5.2.1のインストールのメモ.

前回の試しで、STLportの結果がよさげだったので VC以外のコンパイラでも試してみたくなり、とりあえず dmc 用を インストールしてみようとしたのだけどハマった。

VC用はググればインストール例あるし configure.bat --help やって、指示通りにすればできるようで一番お手軽だった模様.

まあ付属ドキュメント読まずに適当にやるでは不味かった. 読めば書いてた. でも英語なんで翻訳ソフトでちまちま... 悔しいので適当に気になるところだけ訳ぽくしてみた (わからないところを雰囲気で適当にしてたりするので、ちゃんと元のを参照のこと)
README.windows, README.msvc, README.mingw, README.dmc, build_system.txt,
(最近の修正が反映されてない文章もままあるので注意)

ようは、mingw,dmc,bcc 用を作る場合は、Msys 環境が必要. またmsys版でなくMingw32版のgnu make が必要そう. →dmc,bccが目的でもmingw入れちまうが吉かも.

  • コマンドライン版コンパイラが使えるコンソール窓を用意.
  • msys環境(sh)環境へ遷移(msysフォルダ下のmsys.bat実行)
  • STLport-5.2.1を展開したフォルダ直下の configue 実行
  • build/lib フォルダ下で ming32-make 実行. (できたライブラリを STLport-5.2.1/libへコピー)
  • build/test/unit フォルダ下でming32-make実行.
  • build/bin のテストexeを実行.
  • stlportを使うコンパイラ環境の設定.

て感じか.

以下、作業メモ. ただし、あまりうまくいってません。

※watcom c++ は未対応になってしまっている模様.

mingw,dmc,bcc共通

といいつつ基本 dmc しか作業できてないので...

configue実行だけど、MSys環境で

configure --use-compiler-family=???

な感じで ??? に gcc, dmc, bcc を設定.('='も忘れずに、と). 必要に応じてその他オプションも併記して.

configureやったあとに build/lib/ で

mingw32-make -f ???.mak clean
mingw32-make -f ???.mak depend
mingw32-make -f ???.mak ターゲット名

のような感じでメイク.
(bccの場合はmakeのほうがよい? 少なくともcleanは mingw32-make でエラーでて make を使えばokだた)

ターゲット名で install を指定すればallコンパイル&libへのコピーだが、dmcではエラー. また、all は dll(shared)版しかコンパイルしないようなので、結局自分の必要なものを 指定するのが無難そう. (このへんコンパイラごとに事情が違う)

mingw32-make -f ???.mak release-static dbg-static stldbl-static

な感じに、必要なものを列挙してメイク(指定できるものはコンパイラごとに事情が違う).
できた obj/???/*.lib を STLport-5.2.1/lib/ とかにコピー.


あと、テストのコンパイルだけど、日本語環境だとソース中のフランス語文字が壊れたSJIS扱いで怒られるかもで、

ctype_facets_test.cpp 430 付近の'で囲まれた文字を'\xE7'に書き換え

ておく(怒られたのは vc だっけ)

build/test/unit/ に移って

mingw32-make -f ???.mak

で、STLport-5.2.1/bin/にテストプログラム生成、 できた exeを全て実行、出力でエラーがなければok ...なんだが、 エラーでてるかも. ロケール関係ぽいので、とりあえず、あきらめ.


stlportのヘッダや出来たlibを利用するる場合は、 各IDEやコンパイラごとの環境設定するなり、 makefileやプロジェクトファイルごとに設定するなり.


適当に端折ってるので、不味かったらいろいろ試す、で.
ちゃんと使う場合は、configure時のオプションや、 ソースのconfigヘッダ等で、いくつか環境にあわせた設定をしたほうがそさそうです.
(テスト試すところまでで、力尽きた)

dmc

dmcは、ビルドする前に、 dm/bin/ にある link.exe, lib.exe をコピーして
dm_link.exe, dm_lib.exe
を作り、pathの通ったところにおいておく必要がある.

また、makefile の修正が若干必要かもで、
build/makefile/gmake/dmc.mak 111行付近の -p128 を書き換えて

release-static : AR += -p256

のようにする. (256は適当にえらんだ. これでもおこられるならさらに大きくか)

リンク時に文字化けした警告がでてるのが気になるが、libできてるようなんで 気にしないでおく.

ただコンパイル途中で

nbytes=65664, ph_maxsize = 65520
Internal error: ph 1854

なんてエラーがでるかもだが... 出たらあきらめ orz
(-HPでおおきな値設定しても駄目だった)
test/unit でのメイクの hashテストか何かで発生した.
ので、test/unit未確認.

stldbg-shared のコンパイルでも出るかもだが、 dll版は興味ないので放置した (先に static 版のコンパイルをしてあると コンパイル通ったかもだが、それでいいのかで)


コンパイル環境の設定については、dm/bin/sc.ini の INCLUDE,LIBの先頭に

INCLUDE=c:\STLport-5.2.1\stlport;…元の文字列…
LIB=c:\STLport-5.2.1\lib;…元の文字列…

みたいな感じに追記するのも手.
(CD版の dmc の場合、DMが配布している4.5.? の stlport が入っているかもだが、 バージョン違ってファイル名等微妙に違うので、下手に上書き等はしないのが無難)

あるいは、己は、元のと新規とを使いわけたいので 元のsc.iniでは行末に置かれていた %INCLUDE%と%LIB%を先頭にもってきて

INCLUDE=%INCLUDE%;…その他の元の文字列…
LIB=%LIB%;…その他の元の文字列…

のようにして、コンパイラ環境設定のバッチで INCLUDE,LIBの設定を切り替えるようにしてみた.


で、とりあえずいけるはずなんだが... 試しにコンパイルしてみたら .lib が見つからないと怒られた. リンク時の引数で stlport_static.lib とかを指定したらとりあえずリンクできたが、 自動リンクされなかった. ヘッダみるかぎり.libは自動リンクされるはずなんだが. なにか設定抜けてそうだが未調査.

mingw

とりあえず上記でstatic版のみ作れた. dll版は、 リンクエラーがでたので放置. (使ったmingw環境の設定等があわなかったのか?)

test/unitのはコンパイルできて実行できたと思う.

できたlibを使ってのテストは何もしていない状態.
(パスとかオプション設定とか README.mingwみてると面倒そうなんで)

bcc

bccの場合は bcc32.cfg と ilink32.cfg の -L に psdk のpath(???/lib/psdk とか)が 抜けていたらそれを追加.

とりあえずdll版は作成できるけど、tlibで怒られてしまいstatic版は作れてない(未調査) でもって bcc v5.5.1 のせいかテストでコンパイルできず.. 面倒になったので挫折. (readme.bccもちゃんとみてないので)

その他のテキスト

インストールに関係ないけど、気になった文章の適当訳も.

README.utf8, stlport_namespaces.txt,


Academic Free License ("AFL") v. 3.0 なファイル

makefile 弄ってたらふと、ファイル先頭に、ライセンスとして Academic Free License 3.0 となっていて、検索すると、stlportヘッダフォルダでも
 type_traits

ファイルが、このライセンスになっていた.

これは c++0xから増えるヘッダで、v5.2.1では、これ単体で, 他の部分では Boost 発祥の type_traits がincludeされているため、 このtype_traitsファイルさえ使わなければ、気にしなくていいのだけど...

最近の STLportの git リポジトリからとってきたものをみると、 他のソースもこの type_traits ファイルinclude するようになっていて 結構影響する状態のよう.

実質が今のライセンスと かわるのかどうか...

Wikipediav2.0の和訳をみてると、 微妙に面倒くさそうに思える...(読解力無くて読み違えてるかも...)





2010-2-4[木] sprintf,string,stream のメモ.

去年だか一昨年ぐらいから、もうそこそこパワーあるのだから、と、 ターゲット環境でc++で string 系を使ってたのだけど、 そのとき不精して、デバッグログでも使い始めたら やたら処理落ちする箇所の原因になってしまったことがある.

ログといっても シリアル とか USB とか LAN とか経由しない、 数十KBのメモリに溜め込むだけの処理だったんで、 開発中は release コンパイルでも有効にしていて、 多少重くなるといってもI/Oからまないから大事ないと思って 見過ごしてしまっていたのだった. たしかに想定してた使用量を超えたルートができていたけれど、 それ以上に酷い重さに化けていた.

もちろんログをとってることが問題ではなくて、 string系の文字列をつかって記述で楽して

dbgmsg = strFmt("%s (%d) :",fname,line) + msg + '(' + a + ")\n";

のような感じに + 等使って、テンポラリ変数発生、メモリーアロケート発生、 が山ほど起きていたのが敗因. (↑は今適当に書いたので実際のじゃない)

文字列専用にアロケータ用意してフラグメンテーション対策はほどこして いたけど、当然速度的にはよろしいもんじゃなく. わかってみればあたり前だけど、思い込んだら、でなかなか気づけなかった.

そのときは、デバッグログからstring系一層してsprintf系で やりすごしたのだけど、 たとえば + でなく += を使えばテンポラリ無くなり アロケート頻度は落ちるし、 キャパシティをある程度コントロールしてアロケート発生させなければ、 書式なしの文字列連結ならsprintfより速くなる 可能性だってあるはず.

文字列連結を一個一個指定することになって記述が面倒だけど ... iostream系の << なんかはやってること的には += と似たようなものの はずなんだよね.

などと思うと、stream関係って、実は速度的に 悪いもんじゃないかも、って気がしてきたのだった.

て、ことで、例のごとく、ちょっと計測してみた.


test1:

    sprintf(buf, "%s(%d) : test> %s", fname, line, msg);

sprintf だとこんな感じになる処理を、ポインタ操作+mem系, str系, std::string, stringstream, strstream, カスタムstream 等で書いて計測.
表示ルーチンぽくしているが、計測では表示しないので、文字列生成が主な時間.

ソースはこれ, これ, これ

数値→文字列化を持っていない処理では、ltoaを用いて文字列化している.

CharAryStream は、固定サイズのchar配列に結果を書き込むだけにしたカスタムstreambufを使ったもの.
strstreamとほぼ同じだが、その存在を失念していた.で、気づいて計測しなおしたが、vc9付属のはバグがあるようなので、CharAryStreamも残してるしだい(endsの件もあるし).

string, stringstream, CharAryStream では、ローカル変数として関数内に持つ場合と、static変数にして、初期化を一度きりにしたものを試してる.
stringの場合はローカルでの使い方が普通だろうが、streamに関しては static かはともかく、まとまった出力をしている間は1つのインスタンスをずっと使いまわすようなコードになると思うので.

ということで、phenom2 3GHz環境で、vc9 と mingw g++4.4.0 での結果.
100000回の平均. 単位:μ秒.

  vc9[A]vc9[B]mingw[A]mingw[B]
sprintf 0.5401.1710.5071.036
ポインタ操作+memcpy+strlen 0.0580.2130.0740.221
strcpy+strcat 0.0870.3670.0830.298
std::stringで'+'使用 0.7272.0330.9641.270
std::stringで領域予約で'+=' 0.3390.4860.4100.544
std::string↑の変数をstatic化 0.2060.3470.1220.278
stringstreamローカル変数 2.2153.1002.1232.141
stringstream static変数 1.4602.2670.7740.852
strstreamローカル変数 1.8912.3611.3491.400
strstream static変数 0.530---0.3460.408
CharAryStream ローカル変数 1.8622.1990.9841.047
CharAryStream static変数 1.0111.3940.2860.342

[A][B] は、test_sprintfに与える引数の文字列長の違い. 文字列長が違うと、差のありようもかわるので. (一例の結果だけみて、何倍の差があるとか早とちりしないように:)

やっぱり、ポインタ活用や、strcatを用いたものはそこそこ早く. アロケートの(ほぼ?)発生しない stringの '+=' やstream系の<<も まあ早く.
(てか g++ の strstream や CharAryStream の速度ならば、 もう Cできりきりに書かなくていいやん、と)

stringstream も、多少気になるかもだが(毎度ローカル変数生成のような)下手な 書き方さえしなければ、悪い速度じゃなさそう. (VCの stream 実装がいまいちぽいが)

というか、そもそも printf 系の処理はそんな速いものでもなく...


あと、vcでの strstream は [B]の段階で[A]の文字列のままだった. seekp(0,ios::beg)が効いていない模様. 仕様把握してないので言い切れるか微妙かもだが、バグだろう. 速度的には、自前のCharAryStream と大差ないし、 strstreamを追求したいわけじゃないので放置.


test2 : 浮動小数点数を使ってみる

sprintf(buf, "%s(%d) : test (%7.5f,%7.5f)%c %s"
           , fname, line, d1, d1, ch1, msg);

s_stringstream << fname << '(' << line << ") : test (" 
               << d1 << ',' << d1 << ')' << ch1 << ' ' << msg;

double を使ってみた例. ↑で%7.5fにしてるのはstreamでのデフォルトに合わせるため.
面倒なんで sprintf, CharAryStream, stringstreamだけ、だが、vcのstlの出来がいまいちっぽいのでSTLport(5.2.1)もためしてみた.

ソースはこれ

で結果( 100000回の平均. 単位:μ秒 )

 vc9mingwvc9+STLport
sprintf 2.5832.0622.460
CharAryStream 5.0474.1222.164
stringstream 5.8463.9952.553

vc,mingwとも stringstreamがsprintfの倍くらいにばけてる. test1の結果からすると、必要以上にオーバーヘッドがある気分.
stringstream のかわりに CharAryStream(strstream) を使うのは 若干の固定費削減って感じで劇的は無し、というとこか.

で、STLport版、sprintfと大差なく... なんか速い.
仕様のオーバーヘッドじゃなくて実装の差、てことになる、か.

細かいことはあとにして、とりあえず、次.

test3 : 幅指定等

sprintf(buf, "%-24s(%10d) : test %#016llx\n", fname, line, val);

s_stringstream << setw(24) << left << fname << right
               << '(' << setw(10) << line
               << ") : test "
               << setfill('0') << setw(16) << hex << showbase << val
               << '\n';

真打:-)
printf系で楽に書ける書式が、どうしようもなく面倒になることがstream系を使いたくない 大きな理由だけれど、まあ stream への愚痴は後回しで、

ソースはこれ

で結果(100000回の平均. 単位:μ秒).

  vc9mingwvc9+STLport
sprintf 1.2351.1991.183
CharAryStream 2.1580.5290.647
stringstream 2.9391.4741.105

stream、記述のゴツさに、つい比例してしまいそうな印象をもってしまうが、 書式解析がコンパイル時の型チェックでまかなわれているため、 sprintfより速くなる、可能性がある ... vc標準は無視、したいなぁ:)

stringstreamは STLport が がんばっている、って、ことだろうけど.
(string側の出来もいいってことかな?)


test1改 : アロケート頻度.

test1 において、お手軽な範囲で、無理やり、include関係での malloc や new を乗っ取って、使用数を計測してみた. (ソースこれ追加)

ライブラリ.lib 部分になっているのは手がだせてないので、不正確すぎて、判断するには危険だが、大雑把な目安にはなるかも、で.

といっても、ヘッダのみなんで、vcは値でたけど、mingwはひっかからず.

以下vcでの1回表示のときの、表示部分でのmalloc:freeの呼び出し数.

  [A]malloc:free[B]malloc:free
std::stringで'+'使用 2:211:11
std::stringで領域予約で'+=' 1:11:1
std::string↑の変数をstatic化 0:00:0
stringstreamローカル変数 14:68:8
stringstream static変数 3:25:5
CharAryStream ローカル変数 3:33:3
CharAryStream static変数 0:00:0

vc の string 処理は 16バイトまでならstring内にバッファがあるため、 文字列長でアロケート回数が変わる.

stringstream の[A](初回)の値が多かったりfree数が合わないのは、 ライブラリ側の処理とか、あと、バッファ以外にも、 stream処理のサブクラス等の初回生成が含まれているためだろうか.

処理順の都合、stringstreamでアロケートされているけど、 CharAryStream, stringstreamの順に計測すると、CharAryStream側の 回数増えたりするので、可能なものは共通化されてるよう.

で、stringと CharAryStream のstatic変数版が 0回になっているので アロケートを極力回避しようと思えばできる、って感じ.
(面倒なんで表にしてないけれど、double使った test2 でも 0回)

stringstream は、static版でも アロケートが発生しているので、 vc版の測定結果が遅い原因だろう.

逆にいえば、g++や STLportのものは、メモリーアロケート発生させてない、 ということでよいか.


test1 追加 : WTL::CString, STLportのstd::string, の追試

やっぱり STLportのstd::stringが気になったので、test1の追試. ついでに WTL::CString の結果も. (test1書き直し面倒なんで... vc9,mingwの測定値が若干違うのも面倒で)

STLportは v5.2.1 (staticリンク), WTLは8.1のもの.

  vc9[A]vc9[B]mingw[A]mingw[B]vc+stlp[A]vc+stlp[B]
std::stringで'+'使用 1.1761.9930.9651.1970.3260.907
std::stringで領域予約で'+=' 0.4940.4400.4120.5480.2810.480
std::string↑の変数をstatic化 0.1710.3310.1260.2900.1270.355
WTL::CStringで+使用 0.8080.946----
WTL::CStringで+=使用 0.3240.463----
WTL::CString Format使用 0.8751.314----

STLport std::string の '+' での結果がこれって、何だ? って感じだ.

STLportはメモリー確保関係工夫してるようなことどっかに書いてあったと思うけど、 いいなあ.


WTL::CString は ある意味順当かな. std::string のシガラミないし設計の方向性が違い (1core環境じゃ)軽めの処理だろうで. (参照カウンタのわりと素直?な実装だし)

static 変数版を試してないのは実装的にメリットないからだけど、 かわりに Format メンバーを使ったものを併記.
Format()の実装はソースみると自前でprintf系実装しているのではなく、 ラッパー. メモリー確保のために、そこそこformat解析してサイズを求めているので、 速度的には確実に sprintf より遅くなるのだけど.(使い勝手のものだから).


結、というか、雑感

たったこれだけのお試しで結論するのも不味いという気もなくはないし、 使い慣れてない iostream系は何かぽかってないか不安もあるけど、 とりあえず.

iostream系は、それだけなら速度パフォーマンスのそう悪い仕組みでない、といったところか.
併用される他の要因で結果的に遅くなりやすいかも、だけど.

でも、実装は工夫が必要なんだろう. vcやg++のものが工夫が足りてない、というより、 STLport ががんばっているんだろうし.

stream よりも string のほうが速度ペナルティが多くなりそうだ. += じゃなくて + で楽したいんだし.

少なくとも string 使ってる奴が速度パフォーマンスを理由に stream系にケチをつけちゃいけないだろう(自戒:)

ただ stringstream は 無様に思えてきた.

strstream は完全に捨て去る必要ないよなあ、で.
strstream は ends の手間が嫌らしいだけで、 str()時、あるいはc_str()なりを新設して、取り出し時に '\0'を付加する モードさえあれば、かなり状況改善されてたんじゃなかろうか. 原理主義的な人たちは滅ぼしたい代物だろうけど、 C文字列を無視できない人間に stream 系売り込むにはベターな存在だったのかも.

vc標準の奴の性能があれなんで躊躇しちゃうけど、 速度を気にするならstrstream(かその代用品)使うのも手かも、と.
※test2,test3はコンストラクタを追い出した状態の結果なので、 コンストラクタの頻度があがるとtest1でのローカル変数版の結果に近づく わけだから気をつける必要はある.


printf系は速くないってのを再認識かな.
書式解析やargvな処理を思うと原理的に... 実装の差もあるだろうけど (大昔のbc遅い実装だった覚えが). 今回は vc, mingw ともprintf系は MS の実装が使われてるはずなので 違うsprintfだとまた違う印象になった可能性もあるだろう.

まあ速くないといっても、この程度の差で困ることは今時まず無いので 気にしないか. (printf系の使用を避けて速度アップを実感できたのは8bit,16bit機時代くらいか).

今回の結果はまさに50歩100歩といったところだし.
ただ、メモリーアロケートの発生をさけた結果なので、 それが頻発する状態はやっぱり気にしたほうがいいとは思う.

デバッグ処理で極力メモリーアロケートなんて起きて欲しくないわけだし.

もちろん、printf系だって全くメモリーアロケートしないかというと 実装しだいだし書式によってはありえるのだけれど. ただ通常極力しないように作られてるし、 デバッグで通常出す程度ならまず起きないし、で.


あと今回は文字列処理をメインにしてたから、ためせてないけれど、 コンソール出力等でiostream系が遅くなる(かもしれない)要因の一つは endl 時にバッファフラッシュの動作が含まれていることだと思う. これも今時のPCでは気にするほどのこともないだろうけど. でも、'\n'と endl を意図的に使い分ける意味もある、ってのは 忘れずに、と.



今回のソース関係のzip : [download]






2010-2-2[火]

箕面(imax)でアバター見てきた。 お話はともかく、映像は気持ちよかったです。 とくに1/1スケールくらいで表示される時は心地よく。 スケールの違うバストアップに切り替わってああ映画だったなあ、と。 (手に届きそうなウォーカーマシンがうれしく)





2010-1-26[火] xorshift乱数のメモ

XorShift乱数は、こちらとかのように短い関数で紹介されるけれど、たいていシード固定で書かれていて、シードを外部から与えたい場合はどうしたら、と悩んでしまう. もちろん、ちょっとぐぐったらシード設定できるソース載せてるサイトあるし、 おおもとのpaper に all 0でなければよいようなことかいてあるようだけど、 どの程度適当でよいのか不安にもなる. で、今さらながら2chの擬似乱数2 をみたら76に解説&seed設定付ソースがあった. シードは極端な設定をすると不自然な部分列が出力されるからMTのを参考にしたとある. ありがたく、これ流用させていただくことに... と、よくよくみれば、ここの初期化とほぼ同じ(改良版)のよう.

その他、検索したときのサイトメモ.

mt-lite実行速度に xorshiftを含む各種乱数の速度比較あり.

良い乱数・悪い乱数に XorShiftと他の乱数との速度比較とかSSE2使ったバージョンとかがある. 同サイトの こちらにもいろいろなコンパイラでの測定比較あり.

xorshift.pdf 上記サイトで、"問題があると書かれている" とあったのでみた(翻訳ソフトでわからないなりに). 元のpaperより突っ込んだ性能テストをして、通過しないテストがいくつか(も)あるよう. (XorShiftは3つのシフト数の有効な値の組み合わせがいくつか(も)あるけれど、 組み合わせによって性能にばらつきがあるよう) あと改良版として256ビット版が載ってる. (周期のビット数だけでなく、計算でのシフト数も増やして精度をあげている)

XorShift乱数の速度

擬似乱数2の 42 に 周期 32,64,96,128,160,192 ビット版のソースがあったので、 ちょっと速度比較してみた.

ソースは コレコレコレ. (zip)

96ビット版が要修正だったり64ビット版は出力も64ビットだったり だったので 結局 paper みて修正. あと、xorshift.pdfの256ビット版追加. (シード設定可のクラスにしたりでエンバク不安あり. 64,96,160版はA,B,Cの選択がこれでよいのか自信なし).
で paper の160のソース、>>Aになっているけど <<Aの誤記だと思われる. 他と比べてもだし、別のチェックで結果がメタメタになった.

結果は以下. 環境は基本Phenom2 3GHz (玄箱HGは PowerPC 266MHz).
100000000回実行の平均. 単位:ナノ秒.

 vc9
(32bit)
vc9
(64bit)
mingw
g++3.4.5
mingw
g++ 4.4.0
dmc8.51owc 1.8bcc 5.8.2玄箱HG
g++4.1.2
XorShift 32 3.4112.6623.3292.99710.4803.3555.01023.100
XorShift 64 2.0162.1671.8421.9965.1593.0003.73434.700
XorShift 96 2.3354.3451.6672.0415.7733.0233.51238.500
XorShift 128 2.3313.9632.4191.9955.4443.2303.68546.200
XorShift 160 2.3344.2062.3382.0266.2313.0023.18746.200
XorShift 192 2.5843.8742.8762.3368.1153.1573.56646.200
XorShift 256 7.3976.2646.3276.49117.2246.1847.197134.800
線形合同法の乱数 1.5091.3361.6645.7843.5811.3293.15423.200
clib rand 18.55914.17415.08014.7206.5345.2363.231461.900
MT Rand 5.4525.6797.9965.86931.2999.2898.280127.200

下3つは比較用. MT乱数(mt19937ar-cok.c)と 線形合同法を使った乱数とC標準ライブラリのrand()を使ったもの.

コンパイラごとに癖はあるけれど、大筋は似た傾向.

paperの例では1.8GHzで4〜6ナノ秒とあったので、 3GHzの環境(vcやg++)で 2〜4ナノ秒は、そんなものかもしれない.
なお、これら(の速い値)はインライン展開されている(はず). 関数呼び出しになっている場合は、(vcにて) 3〜6ナノ秒台だった (テストルーチンで乱数をファンクタにせずワンクッション関数を噛ましてたとき)

全体に周期32ビット版は他より遅くなっているのは、たぶん(アウトオブオーダーとかのレベルの)命令の並列化ができないためだろうか.

速度的には、 大筋ビット数が増えれば遅くなるけれど、32-192の範囲では 増える周期(質の改善)に比べ時間の増加はさほどでもないので、 どうせなら128でなく160や192あたりを使うのも手かもしれない.

256ビット版はプログラムが少々複雑になっているせいか 時間増加のよう. 128ビット版にくらべ2〜3倍... MTと対して変わらない速度(場合によっては負ける)なので出番はないだろう.

でinline展開で速いのはいいけれど、 ビット数が大きいほど(ささやかとはいえ)コードサイズが膨れやすくなるので、 乱数の質が高くなくていいなら、ビット数少ないのを選ぶのもよいかもしれない.
でも線形合同法でいいなら、(inline展開されたら)そっちのほうが速いか.

サイズきになるならinlineしない形に書いて160,192あたりを... もっとも、このソースの64,96,160(,192)は使ったパラメータがほんとにこれがいいのかわかっていないので 結局 128 を選んでおくのがベターな気はする.


あと、XorShiftの件とはずれるが、vcやg++でのcライブラリの rand()の速度が遅いのは、 マルチスレッド対応のオーバーヘッドのためだろうか. インライン展開された線形合同法の乱数の10倍前後なのは ペナルティが大きいとも、10数ナノ程度ならば大抵たいしたことないとも、どちらとも. 結局使用量/使用箇所しだい、だけれど、どっちにしろ精度のことを思えば、 とっとと XorShiftなりMTなり用意して用途別にインスタンスを管理したほうが、 楽になれると思う.

(参考サイトにある SIMD版のSFMTとかが使える環境なら, そっちのほうがいいだろうな)


追記

乱数の精度の評価についてはさっぱりなんですが (自分が使った処理において出目に不都合があるかどうかくらいなら、ともかく)、 同根のtest2をしたときの結果はあまりよいという感じではなかった.(この場合のテストとして適切かどうかもわかってないけど)

まあ、たいていの場合の乱数の利用頻度や精度を思うと 普通は MT を選んどくのが無難だと思う.

この程度の速度差(時間差)やプログラムサイズ差が ネックになるような利用頻度(仕様)やターゲット環境なんて ゲームでもまずないだろうし.
どちらかというとライブラリ化でのオーバーヘッドのほうが 気になる可能性があるかも. (この程度のサイズのルーチンなんだから、わざわざメーカー提供のライブラリ使わなくてもいいよね、とか)





2010-1-23[土]

今日は睡蓮を堪能。 ぎりぎりについたらぎっしり。 思いのほか男性客がいた、って女性ボーカルなのだから当然か. (それでも女性のほうがおおそうだけれど) 高い人の後ろになったため正面のボーカルと左側はあまり見えず. けど右側はみえた(満足)。 MCを大人気なく邪魔したり最後に一言置いていったりと こんなカワイイ人だったんだなあ。 たのしかったけどちょっと短く... おかげでキャンセルしてた 某氏の誕生日オフ会(という名の新年会)に合流できたので 吉としとこう(無理がたたって後ボロボロだったけど)





2010-1-11[月] 安定ソートについてのメモ(sort test その5)

しつこくソートネタ.遣り残してた、というか、自分としては本題だった 安定ソート についてのメモ.

安定ソートだと、ソート対象の値が、同じ値だったときに元の順番を維持した状態でソートできる.

安定ソート としては 挿入ソートマージソートビン(バケット)ソート基数ソートバブルソート 等がある. アルゴリズムとかの詳しいことは wikipediaとか、 このへんとか、 適当に検索するなりして調べて.

今回のテストルーチンは、 マージ基数quick (y)その他のソートテスト本体 で一組.
[ソース,exe,実行結果ログのzip]

本題以外のソートも混ざってて、ごちゃごちゃしてるけれど、 本命は、マージソートと基数ソート.

マージソートは

  • 最内側(一定個数以下)のソートとして挿入ソートを使っている.
  • おそらく、汎用的な安定ソートルーチン(std::stable_sortとか)だと、
  • 数が少ないときは挿入ソート、多くなればマージソート、って感じだと思う. (追記:実際はも少しいろいろやってるかも)
  • データの個数の半分のサイズの作業メモリ(外部メモリ)が余分に必要になる.

基数ソートは

  • 速いけれど、使える局面が限られる.
    ソートキーを(符号無)整数値に変換できないといけない.
    今回のテストは基数ソートしやすいテストデータにしている.
  • 比較を単純化するため、テストデータは、負数無し(0と正数)にしている.
  • このテストルーチンでは基数ソートの基数は8bit(0〜255)で扱っている.
    なので、
  • int(4bytes)だと4分割して4回処理することになるし、 double(8bytes)だと8分割して8回処理することになる.
    (分割した処理ごとに範囲チェックをしてるので、入力が0〜255ですめば1回+αの処理ですみバケットソートに近くなる)
  • 浮動小数点数データについては、今時の一般的なIEEE な仕様であることを前提に、
  • ビットイメージをそのまま符号無整数値として扱っている.
  • データの個数分の作業メモリ(外部メモリ)が余分に必要になる.


実行結果

とりあえず、その実行結果としては、

 【phenom2 945 vista64 vc2008:32bit】  【phenom2 945 vista64 mingw】  【vaio-c1 win2k vc2008】  【玄箱HG debian4 gcc4.1.2】

(※他のコンパイラでの結果等はzipに同根)

いくつか抜粋してみると、(単位はμ秒)

phenom2 945(vista64)+vc2008(32bit)で int 配列をソートした場合.

個数100個1024個10000個100000個1000000個10000000個
回数(結果は平均)( 1000回)( 98回)( 10回)( 1回)( 1回)( 1回)
バブル SORT 12.4401557.466150125.77015098726.584------
挿入 SORT 3.148267.28824947.2702500147.295------
vector insert 9.242192.0699526.0991133735.433------
std::stable_sort 3.48352.740739.9829859.912119201.8821492833.656
マージ SORT 2.40342.339564.8137241.42391783.5231102430.407
基数 SORT 5.77834.457312.8893309.77837145.294406029.607
QUICK SORT(非安定) 2.10433.574439.8055471.64566066.008794235.790

phenom2 945(vista64)+vc2008(32bit)で double 配列をソートした場合.

個数100個1024個10000個100000個1000000個10000000個
回数(結果は平均)( 1000回)( 98回)( 10回)( 1回)( 1回)( 1回)
マージ SORT 3.78064.883865.57811134.446141526.0181726543.597
基数 SORT 14.11690.035841.4278860.623106789.9691096515.828
QUICK SORT(非安定) 3.68557.659750.5429295.246113065.8371363336.262

玄箱HG(PowerPC 266MHz)+gcc4.1.2で、int配列をソートした場合.

個数100個1024個10000個100000個1000000個
マージ SORT 36.000448.9807600.00096000.0001344000.000
基数 SORT 68.000285.7144400.00072000.0001024000.000
QUICK SORT(非安定) 28.000367.3475600.00064000.000836000.000


表のstd::stable_sortはコンパイラ付属のstlライブラリを使った場合. たぶんマージソート(with挿入ソート)がベースだろうと思うけれど(追記:実際はも少しいろいろやってるよう)、 実装の違いからか、ちょっと差が現れている模様. (vcのには勝ってるけど、gccのには量が多いと負ける)

quick ソートは安定ソートではないけれど、実行速度の比較のために並べている. (※実行ログでは、quick(+挿入) になっているモノ)

基本的にマージソートはクィックソートより遅くなるが、 基数ソートは条件が揃えばクィックソートよりも速くなりえる.

だいたい説明サイトの説明にあるとおりの状況、かな. (どの程度の性能差があるかを見てみたかったので今回のテスト)

ただ、基数ソートは仕組み上、ソート値のビット数が多い(値の範囲が広い)場合、処理が重くなるので、 int(4bytes)だと飛びぬけて早いのに、double(8bytes)だと微妙な差になっている.

また、phenom2(3GHz 2次cache 512KBx4 3次 6MB)環境だと、 テストで使ったデータ数やデータサイズ・CPU(キャッシュ容量)が 基数ソートに有利に働いた面もあるようで、 クィックソートよりも十分早くなれるが、 玄箱HG(PowerPC 266MHz cache:16+16KB)の場合は 1024個,10000個では速そうだけど、 それ以上ではクイックソートのほうが速くなっていて、 基数ソートが必ずしも速いというわけでない模様.


基数ソートは、個数が少ないときは、処理のオーバーヘッドが大きすぎて割にあわない. もっともクィックソートにしろマージソートにしろ、数が少ないときは実質、挿入ソートになっているので、 実際に基数ソートを使う場合も一定数以下はマージソートを使う、のようにするだろう.

ただ、他の実行環境(CPU)やソート対象のサイズ等により、効果的な境界値が大きくばらけるので、 汎用的な決めうちは、やりにくい.

基数ソートは条件揃えば倍速以上になるとはいえ、 手間を思うと、よほどのことがないかぎり、 安定ソートはマージソート、 非安定ソートでよければクィックソート、 でいいかな、というのが結論.というか、普通を再確認しただけとも.


upper_boundを用いた vector への insert

先の結果のvector insertの行は、vector<Hoge> hoge_vec; でデータを保持しているとき、

hoge_vec.insert(std::upper_bound(hoge_vec.begin(),hoge_vec.end(), val), val);

のような感じに安定ソート状態を維持したまま新規の値 val を挿入するもの.

テストルーチンでは、他のソートと関数仕様あわせたため、(実使用からすれば) 余分なアロケート時間やコピー時間が混ざっていて、 他のソートと比較するのにはフェアな状態ではない.

が、回数に対する時間の増え方からすれば、効率はあまりよくないだろう.

これを用いるメリットは、

  • データ追加の機会がまばらにあって、かつ、絶えず整列状態を維持しないといけないとき
  • 余分な作業メモリ(外部メモリ)を必要としない

といったところか.

作業メモリについては、挿入ソートも作業メモリ不要なので、追加回数しだい... どちらにしても、量が多いときの速度ペナルティが大きいので、数があるときは メモリの折り合いつけてマージソートとかを使うほうがよいだろうけど.


しかし、余分に作業メモリ(外部メモリ)が必要になる、というのは、 場合(ターゲット環境)によっては面倒かもしれない.
というか、std::stable_sort で勝手にアロケータを使われること、 が環境によってはつらかった.

なので、最大数わかってる場合に固定の作業メモリを与えられるマージソート・ルーチンがほしい、というのが、今回のテストルーチン作成の理由のひとつ(実際に使う機会があるかは別として)

あと、後述のSmpClassの例からすると登録順番も保持し比較対象にすることでクィックソート(std::sort)を用いるというのも、動的アロケート回避、という意味では有りな選択かもしれない.


※ 基数ソートで、符号無し整数として比較を行っているけど、他のソートは 型どおりに行っている.
当然、条件を満たした状態だから、他のソートでも符号無し整数で比較することは可能なので、 そのように比較すれば、他のソートもも少し早くなるはず. (面倒だからやりなおさないけど)

Class/Structのソート

テストルーチンで、SmpClass を使ったものについて.
(前回のスマートポインタのソートの補足というか書き漏れ)

[1] SmpClass1           [2] SmpClass2          [3] SmpClass3
8バイトの構造体.        SmpClass3へのポインタ  128バイトの構造体.
class {                 (4バイト)              class {
    float    key_;      ※比較はSmpClass3の        float    key_;
    unsigned no_;         ものを使う               unsigned no_;
};                                                 unsigned rsv_[30];
                                               };

のようなデータのソートを行ってみる.
[1]については、テストの都合unsigned no_ になっているが

class {
    float  key_;
    Hoge*  pHoge_;
};

のようなソートキーと実体へのポインタの組み合わせ、を想定している.
(面倒なので話を32bit環境に限定)

また、quickソートにおいて、登録順も比較対象にすることで[1]と同様の安定ソートを実現するため

[4] SmpClass4
12バイトの構造体
class {
    flaot    key_;     // 比較対象
    unsigned no_;      // 比較対象
    unsigned rsv_[1];  // Hoge* pHoge;のようなのを想定.
};

も用意.
これらのデータをソートした結果は(phenom2 945 vc2008環境)

10000個の場合 (単位:μ秒)

[1](8bytes)[2](ポインタ)[3](128bytes)[4](12bytes)
マージ SORT 1188.4891362.14213398.148---
基数 SORT 364.0762304.5256199.210---
QUICK SORT 893.4451171.8676468.636954.360

100000個の場合 (単位:μ秒)

[1](8bytes)[2](ポインタ)[3](128bytes)[4](12bytes)
マージ SORT 15242.09124420.003179135.267---
基数 SORT 4175.60147205.162107197.703---
QUICK SORT 10910.04626117.91473457.52011795.913

のような感じ.

[1]の場合はソート対象のコピー量は増えるけれど比較コストは増えない. [2]のようにポインタだけの場合はコピー量は最小になるけれど メモリにあるポインタを経由して比較用のキーにアクセスするため 比較時間(コスト)が増加する. で、CPUキャッシュ等の都合から、今時の環境だと[1]のほうが有利なことが多そう.

なので、[1]のようにできるならば、そうしたほうが構造体等のソートは 速くなると思われる.
(実体の並べ替えが必要な場合は、まずポインタをベースにこれでソートしておいて、 その結果を元に(作業メモリ使って)コピーし直しても元が取れそう)

で、どうせ、ソート用のテーブルを作るならば、登録順番も控えることで クィックソートを使えるようにするのも一考.

ソート対象が8バイトから12バイトに増えるが、 マージソートや基数ソートは 余分に外部メモリを必要とするので、 メモリ使用量的には同等か有利ということになる. (マージソートだと総数の半分、基数ソートだと総数分)

今回の例では、基数ソートに対しては全くだけれど、マージソートと比べるとよい結果となっている. もっとも[4]はIEEEなfloatの正数であることを前提にキーと登録順を合わせた64bit整数にして 比較を軽くしているので、このように出来ず比較コストが上がると、また違う結果になるだろう.

(今回の場合マージソート側は floatのまま比較しているのでフェアでないかも.試しにキーをビットイメージのunsiged値にしたところ[1]の結果は10000回1170.596μ秒, 100000回13034.268μ秒. 多少縮むが、一応上記を書き換える必要はなさそ)


バケット(ビン)ソート

基数ソート以上に利用条件厳しいけれど、条件があえばバケット(ビン)ソートのほうが当然速い. で、一応、用意してみた(これ)
といっても工夫してないので整数のみの対応.

基数ソートのようにgetkeyを与えられるようにすればいいのだけれど、 ただ、基数ソート・ルーチンは、 入力の値がすべて0〜255までなら1回+αで処理打ち切ることになりビンソートに近い状態になるので (多少オーバーヘッドが多いけれど)、 その結果をみれば大体の雰囲気はつかめると思う.

ということで、乱数の値を0〜255にして試した結果は、コレ
…他のテスト(SmpClass)は整数型にしてなかったので、結局intテストしか意味がなかった.

抜粋すると、

100個1024個10000個100000個1000000個
QUICK SORT 2.11032.696359.9203716.04540616.405
マージ SORT 2.43342.029497.8855679.42366518.720
基数 SORT 2.08911.584106.1381293.11114738.046
BACKET SORT 1.8459.29981.253859.95611884.890

のような感じ.場合によっちゃ、やっぱりバケットソート専用も意味あるかな.

その他諸々

当然、それなりに測定誤差がある.
細かい数値ままにしてるけれど、上位1,2桁ぐらいの感覚でみるのがよさそう.

前回以降にCPUを換装してしまい、今回分と前回分を単純に比較できなくなってしまったので、 テストでは、安定ソートだけでなく、前回試した他のソートもいくつか試している.
ついでに前回やりそこねてた シェルソートも追加(思ったより速い処理だった).
std::vectorと同様に無理やり multisetに挿入した場合も追加 (安定なわけじゃないし、ソートとしてはやっぱり遅いけれど)

前回のテストでは、quick_sortのtemplate版が内部でイテレータのアドレス比較してて 実質、配列のソートにしか対応してなかった. で、オフセット値を用いて修正してみると、 Bidi版と大差なくなってしまった. 厳密にはBidi版のほうがまだ1変数多くなるので、比較処理によっては差がありえるけど、 これくらいなら利便のほう優先して、今回のテストのquickソートは前回のBidi版をベースにした.
(けど、classのソート等で、一旦、ポインタを集める場合は配列になるだろうで、 それなら配列版のほうがよいという考えも)

前回の結論に基づき、quickソート内部の挿入ソートを Bidirectional Iterator を 受け付ける形でやねう版にしてみたはいいけど、性能出なかった. よくよく考えれば、 やねう版挿入ソートは、無駄な代入を減らせる可能性が高まる代わりに、比較回数が1回増えてる. 比較処理がコピーよりも十分にコストが安いことが前提なわけで、 比較のコストが高くなる場合は当然不利だ. ただ、元のソースは、ループで1回無駄に比較をしている状態でもあるので、その1回分の比較を 回避することで改善した...が、ソースが結構酷い状態に.
改善できたといっても普通のとどっこいどっこいな結果だったので、 結局、マージソートともども、普通のを用いることにした.

基数ソートルーチンは、実は dmc でコンパイルすると int 版の結果が不正になってしまっていた. こちらのバグかもしれないけれど、深く追求せず. 他にも玄箱でTYPE_SMPCLASS=4でコンパイルするといくつかのソートで実行結果が不正になるが、これも放置.

このテストのクィックソート等再帰を用いた処理は当たり所が悪いとスタック溢れがあるよう. (乱数を0〜255にしたら駄目なモノがあった... 個数減らして回避. 追記:下記に修正版)

open watcom c++ (v1.8)の場合、std::stable_sort, std::upper_bound が未実装だった. 辻褄あわせして通したけれど、他にもテンプレートの特殊化ができなかったり、と、 まだ使うにはつらい感じ.

今回linux環境で使ったタイマーはwinに比べての精度がよくなさそう(4ミリ秒単位くらい?). ただ、他のプロセスの時間を含まない値なので、そういう面では楽かも.

追記

実際のstl(stlport)のものをみると std::sortやstd::stable_sortはも少しいろいろ工夫してるよう. (std::sortは、イントロソート等工夫してるらしく)
(もちっと、ちゃんと調べてから書くんだったと後悔...)

このテストのquick sort は、中間値のコピーをローカル変数にとるため値のサイズが大きいと再帰中のスタック消費がはげしくなってしまっていた.
(merge_sort 同様に)再帰関数から該当部分を関数分離してスタック消費をおさてみたのがこれ
一応上記で溢れた件は大丈夫になったが、実使用で気になる差ではないけれど、やっぱり計測上は若干遅くなった.
まあ、これをしても量と当たり所が悪いと溢れるだろうで、スタックのこと思えば素直にstlを使う、と.




2009-12-24[木] mg.exe LFN対応

今更ながら mg.exe を LFN対応してみた.(これ)
ちょっと試すだけでも 8.3 形式はうざく、つい、カッとなった.

が、msdos player はLFN未対応だったらしく..orz

vtdosのほうは、動いてくれた.
以前 vtdos がうまくいかなかったのは command.comをちゃんと入れてなかったからのようだ.

command.com は、PC DOS J7.0/V のCD発掘できたので、それを利用.
win95以降, freedos 1.0, dr-dos7 あたりの command.comは、 駄目だった.

しかし、ドキュメントを読む分には素でも動きそうなのだが. ドキュメントやCOMSPECを見ると vtdcmd.exe というものを実行していそうだが、 配布物の中にそのexeファイルはなく. 仮想名かもと思うが、動かないとこみると、やっぱり必要なのかも? ...が、とりあえず command.com 入れて動いたのでよしとしておこう.


(追記)
オプション指定せずとも dos環境がLFN対応しているかどうかを判別するように修正してみた.

といっても、ax=71a7h; int 21h (win32なファイル時間をdosファイル時間に変換するLFN用システムコール)を実行してみて、エラーがax=0x7100になるかどうかを 見てるだけ.
(※I/Oアクセスが発生しないLFNシステムコールならなんでもいい)
例によってろくに確認してない.

あっと、lfnのシステムコールは こちらを参考にしてます.





2009-12-20[日] 古PC復活メモ

(遅延書込)

最近、古い5インチFDDや3.5インチMOをサルベージしたく バラしたままだった古PCを1台復活させたが、 この手のことはやってるときは楽しく、 つい他の古PCの復活もやってしまったのだった.

pen3 800MHz前後

まずは、NetVista6842(pen3 866MHz i810E mem512MB hdd:120GB) とか NetVista6881(celeron 700MHz i810 256MB 80GB)とか Mate MA07H(pen3 800MHz 810 256MB 80GB)とか (昔中古で安いからと買いすぎた代物).

NetVistaは家用サーバーで使っていたのを引退させたものだから、 いまさらそんなモノにするのもつまらなく、 デスクトップな linux ディストリビューションを 試すことにした. あと、PCI付のNetVistaにはPCIのRivaTNT(やG400)が残っていたので、 それをつけてみた.

結論から言えば、このスペック程度でデスクトップ利用するのに 一番いいOSは、やっぱり Win2K、だろうというのが実感.

最新のwin7(rcだけど)をNetVista6842 に入れたら、
 CPU 1.3, Mem 1.4 gra 1.0 game-gra 1.0 HDD 4.6
といった感じだった.
グラフィック関係は、古くて遅い上にドライバーないのが致命的.

linux等フリーosも、グラフィックアクセラレータ対応ドライバーの有無がネックだろうか.
というか手持ちのボードや周辺機器がどの程度使えるかどうかが.
枯れたハードならlinuxとかのほうがずっとサポートされてるような 幻想をいだいてしまっていたけれど、 それはチップ情報がオープンになっていて、 かつ、それをサポートしてくれる人がいての話.

nVidiaの古いチップは、オープン(あるいは解析済)というわけでは ない模様. メーカー製ドライバは古いxに対応のものは存在しているが、 最近のXorgには未対応のよう. このために古いディストリ入れるのも楽しくないので、 また810は多少はアクセラレーション効くのかAGPx2なのがPCIよりも有利に 働くのかマシな状況だったため、結局TNT(PCI) はお払い箱にした.

ちなみに ATIのだと、数年前に情報オープンになってて最近 よくなってきているらしく、 Radeon9600gtをつけた別のマシンで試しに ubuntu(gnome) いれたときは、アクセラレーション有効になるとまずまずの感じだった (それでも検索するとメーカー製ドライバのほうがよいような記述も みかけたが、インストールの面倒を思うとフリー版でよいかと)

と思っていたら こちらの記事からすると、 Kernel 2.6.33 あたりでnVidiaの古いチップ対応がマージされるらしい? ということはもう数ヶ月まてばマシになるのかもしれない. というか、Fedoraだと今、対応済みってことなのだろうか? 気力ができたら試そう (debian系に慣れたため、他を弄る気が薄く...)

ただ、グラフィックドライバーの問題を抜きにしても ubuntuは pen3 866MHz 512MB程度のスペックで使うには重かった. (不要なプロセスも多少殺したが、いまいち)

メモリ256MBのほうに, debian+lxde や u-lite(ubuntu+lxde) を 入れたときは結構よく思えたので、 じゃあとgnome版を試したのだが、レベルが違った. あきらめたほうがよさそうだ.

日本語対応を思うと ubuntuは魅力的なんだが... u-liteになると結局日本語関係いまいちな感じになるので、ううむ.

その他 ReactOSは、うまくインストールできず. 他にもLiveCDモノもいくつか..でpuppyは結構よい感じだった(後述). 日本語整備されたものをみちゃうと、堕落してしまう

ただ結局のところ、512MBのPCはdebian入れてサーバー的にLAN接続、 他はpuppyとか入れっぱなしで放置という結果になった (放置分だれか引き取ってくれないかしらん)

puppy linux

軽いといううわさの Puppy Linux も HDDにFULLモードで入れてみたが、たしかに軽いようだ.

先のlxdeな環境に比べても、頭一つ抜き出ている印象をうける. jwmというのも軽いのだろうが、全体で上手く調整されているのだろうな. (窓移動で中身表示せず枠だけってのは遅いマシンでは嬉しい. みっともない窓描画みせられるよりか、ずいぶん印象がよくなる)

なにより日本語対応が思いのほか行われていたのがうれしい.
入っているソフトで十分なら これは、かなりいい選択なりそう.

ただ個人的には標準のファイラが好みでなかったのが痛かった.
ワンクリック動作については、こちら等いくつもの サイトでダブルクリック設定かかれていて対処可能だし、 その他の表示も調整すればマシになるが... やっぱり微妙だ.

パッケージシステムも、 基本的に1CD起動、RAMディスク運営のシステムとして 調整されているものだから、 そもそもdebianやubuntuと比べるのはお門違いなのだが、 なまじまとまったシステムのせいか(まあ面倒だし)、 ソース落としてきてまでインストールという気にもなれず.

RAMディスクベース用にロードモジュールを用意するのは、 os-9のロードモジュールを連想してある意味楽しいそうなんだが.

x,gtk+?

ubuntu(9.10)の外観の設定、では視覚効果の指定で3つの状態が選べるが、 radeon9600gtを入れたPCで試していると、 効果無しを選ぶとアクセラレーションが効いていないようにみえる. 逆に通常効果(追加効果)を指定したほうがきびきび動いてるようだ (810だと通常効果を選べなかった).

あとdebianで、ためしにmac4linを入れたのだが(窓まわりはそれらしくなったけどドック関係は失敗)、非常に激重になった. 使い物にならないのでアンインストールしたが、元どおりにならず、マシになったとはいえ描画が非常に重い状態. よくみると、窓に半透明影が残っている...非力でないPCでubuntu動かした ときはmac4linいれるまでもなく影付きなので、元々の機能でon/offできるのか? こちらをみてて

> gconftool-2 --type boolean --set /apps/metacity/general/compositing_manager FALSE

でoffできた. offできると今度はインストール前よりも速いような?気も. (アクセラレーションがきいた? わからない)

xとかgtk+,gnomeの設定がちゃんとしてあげられたら 非力なマシンでももっとよくなるのかな? このへんのところ調べたほうがよいのだろうが...疲れた.

DynaBook GT475

msdos playerとかに触発されたこともあって、 調子乗って、十数年前の win95 なnote機 DynaBook GT475(486 75MHz 24MB) も弄ってしまった.
これでも16MB増設した状態だけれど、 メモリの24MBってのは微妙だ. win95でも使うのがしんどいスペックだった. (元々は親が使っていたもの)

linux等でコンソールのみだとしても、よほど古いディストリ等でないかぎり 辛いサイズに思う(一度入れたが日本語使えないのはやっぱり嫌で)

もちろん dos/v 入れる分にはそこそこ十分だ.
実際 こちらのFreeDOS/V入れて無事起動.

HDDは元の500MBのものから、余ってた30GBのモノに付け替えた. マシンのばらし方はこちらのサイトがまだあったのでありがたく. E-IDE と表示されてるので 8G までいけるとおもいきや BIOS的には 500MBまでなのか、GT475につなげて fdisk等すると 誤った容量が表示されそのまま作業すると不味い状態.

まあBIOS で大容量HDDをちゃんと認識できなくても、 起動したosがサポートしていれば通常で利用できることが多いので、 あらかじめ 別PC で freedosにて fdisk&format (念のため起動ドライブは8GB以内の4GBに設定) してから GT475につなげたところ 4GB,24GB にアクセスはできて一安心.
※BIOSのためか fdisk だけでなくformat も大容量に対してエラーになるので 別PC側でformatまで済ませておく必要アリ.

折角だからとパーティションきってlinux等もいれようとしてみたけれど、 biosが想定外なのか grubやliloを使っても2つ目以降のパーティションからの起動が 無理のよう. ブートできないシリンダだとおこられる. 2つ目のパーティションが500MB以内にくるように 1つ目のパーティションを100MBにした状態でも駄目. なので複数インストールはあきらめて一つだけにした.

で、結局いれたのは、Win98...orz
別のマシンでHDDにインストールしたあと、 そのhddにインストールCDの中身もコピーして、 GT475につなげなおして、ハード再設定でなんとか. (swapファイルを64MB固定設定にしたり).

FreeDOS関係でなんとかしたい、と思ったが、 lfnのサポート具合のこともあるし、 ネット関係を思うと、 LANカードのドライバー等はなんとかなるにしても、 LAN内の他のPCとのやり取りの利便を考えれば 結局win機がベターなのだった. (ただwin95無印はfat32無しだしその他ドライバーが見つからず... win98で自動認識されてインストールというのが吉だった)

また、せめてtelenet端末として、と思う場合も、 utf8が使えるdos/v用の端末ソフトがあるや否や、 で、移植や改造が頭によぎりバカらしくなり.

とりあえずwin98ならば teraterm 動作ということでok.
(ほんとはMIYAZAKI師匠のrloginがよかったがnt系用だし puttyごった煮版はwin98だとstatic labelの文字化け激しく, 対処方法で示されてるフォント指定でも効かずで).

*

まあ、使えないマシンを復活させるのは楽しくここ2週間ほどちまちま弄ってたけど、 ふと我に代えると非常にむなしいもので…… 次またやってしまう率を減らすためにメモといったところ.

思い返すと古PCは osお試しインストールすることこそが 目的なのかもしれないと思えてくるが...

最近は、 メモリもCPU速度もありisoイメージ直インストールできる メインマシン上の VirtualBox での作業するほうが吉だものな.





2009-12-18[金] 夢にみたソフト

xp64で64ビットwinに移行して以来、自宅メインPCでは 16ビットdos用の exeが使えなくなっていて、 それもあって win7bisのxp付はちょっと魅力的だったりしたのですが. (いやイザとなればサブPCはw2kだし、virtualpcでwin9xという手もあるけれど)

最近ごそごそ別件で検索してたら

なるMSDOSコンソールなエミュレータが2つも開発されていた模様.

双方公開されて日が浅く... というかwin7(64)で16bit exe使えず 不便だからと作られたもののよう.

ハードのエミュレートじゃなく、dos(+α)部分のみで 入出力が仮想ドライブじゃなくて通常のドライブ(環境)のままで、 まさに、かって欲しかった(作れなかった)ソフトそのもの.

MSDOS Playerのほうは msdos.exe hoge.exe files のように単発実行できるもの. lccコンパイラ使うためってことらしく他の32ビットツールとの連携もやすそう.

VTDOSのほうはv-text環境込みのdos窓(shellコンソール)みたいなもののよう. v-text(dos/v)版のvzやfdも使えるらしい. こちらも16ビットexeだけでなく32ビットexeも呼び出せる模様. (それもあってか設定がちょっと面倒そう...己は上手くいってませんorz)

で、まあ、双方のサンプルに mg.exeって記述があって思わず笑ってしまったのでした。 (今でも触って下さってる方がいるなんてありがとうございますです)

ただ、喜んだのはいいのですが、すっかり16ビットdosツールとは 疎遠になってしまっていて、これを機に16ビットツール環境復活...したいけど,どこにバックアップしまったやら. (試すためにこのサイトの16bit-dosツールからmg.exe落としたりとちょっと間抜け)


で、折角だからfreedosからとってきたcommand.comと、こちらのos9/6809 L1 エミュレータ(v1.1)とを組み合わせて

C:\Users\myname\OS9>msdos command.com /c echo hello | os9l1 place \* world
hello world
 world

て具合に msdos(8086) と OS-9/6809 の夢の競演をさせてみました.
ほんと、どうでもいい無理やりですが^^;

※結果がみっともなく余分に worldがついてるのは、DOSの改行はCRLF,os-9はCRのみでplaceが余分なLFを最後の余りだから1行扱いしてるせいかな.
※os9l1はcygwinでコンパイルしたもの. os9l1は標準入出力以外の通常のファイルアクセス等未サポートだから、まともに動く実行ファイルがほとんどなかったり...おかげで、たったこれだけのことするのに酷く手間取ったorz





2009-12-17[木] CPU換装→AMDLLD64青画面

どうもPC組立やパーツ差替のたびにトラブルってるような... ソフマップの特価につられつい CPUを PhenomII945に換装したら、 vista起動ログイン直後に必ずブルースクリーンになってしまうのでした. (前回は9月頃MBのBIOS更新に失敗してMB交換. でもそもそも BIOS更新した理由はMBで不具合のでるGカードを買ったせい)

いやsafeモードだと問題なく.メモリテストも問題なく. BIOSはちょっと古かったので更新かけたけど変わりなく.

青画面のメッセージには amdlld64.sys(AMD Low Level Device Driver) の中のアドレスが表示されていて、こいつが犯人ぽい.

ググッたところ日本のサイトでは見つからなかったけれど、海外にちらほら. 初っ端に見つかる こち が正解のよう.

MBの種類は違うけれど、症状は同じ.
どうも vista64 にて、 AM2+なMBにAM2なCPUをつけてた人が、AM3なCPUに乗せ変えた時に遭遇 しているって感じか?

対処は、
 safeモードで立ち上げて \windows\system32\driver\AMD64LLD.SYS を削除
するだけ. 起動し直すと、とりあえずブルースクリーンはでなくなった.
( あとシステムのプロパティ→デバイスマネージャでAMD Low Level Device Driver(だかAMDLLD64だか近い名前のもの) に黄色マークがついていればそれも削除)

AMDLLD64.SYSがなくていいのかは わからないけれど、起動できないよりは、で (?別のドライバに置き換わってるのかも?).





<<前の10件