Last update: Saturday, 04-Jun-2011 17:29:45 JST |
_ というわけで、いろいろあってまる一日費やしてしまった、昨日ゲットしたジャンクカードの調査結果。
_ RAGE II+。動作せず。
_ GD5428。動作はするものの、RGBコネクタの接触不良か赤色が出ず。
_ ET4000。か〜な〜り〜設定に苦労したが、なんとか動いた。問題なし。うひ〜遅いわ・・・。
_ Stealth Pro。問題なし。おお、これがISAのカードかと思えるほどGDIは速い・・・。
_ ついでにベンチマーク計測。HDBENCHでなく、最近開発中の自作品。GDIのみ抽出してみた。数値は単位時間あたりの作業量なので、大きいほど高速ということになる。
●640x480 8bit TEXT: TEXTAA: LINE: BOX: CIRCLE: PATBLT: BLT8: BLT16: BLT24: SCROLL: 2142: 2129: 16026: 160734: 26652: 4979: 1136: 335: 175: 4976: AGP: Rage Fury 531: 419: 12800: 52226: 21877: 2484: 637: 392: 168: 2492: AGP: Reality 334 456: 341: 14643: 33925: 18661: 2485: 635: 394: 128: 1831: PCI: PW968PCI 172: 76: 5934: 9259: 571: 1725: 59: 59: 21: 581: ISA: Stealth Pro 63: 51: 697: 564: 568: 160: 59: 59: 21: 17: ISA: ET4000 40: 34: 591: 425: 484: 44: 44: 44: 17: 15: ISA: OAK 18: 16: 248: 94: 128: 206: 19: 19: 19: 55: ISA: GD5428 ●640x480 16bit TEXT: TEXTAA: LINE: BOX: CIRCLE: PATBLT: BLT8: BLT16: BLT24: SCROLL: 2153: 106: 15754: 102115: 26638: 4979: 1028: 569: 412: 4973: AGP: Rage Fury 470: 352: 13428: 35532: 18372: 2471: 431: 375: 270: 1617: AGP: Reality 334 156: 74: 5546: 4857: 439: 872: 29: 29: 29: 300: ISA: Stealth Pro ●640x480 32bit (Reality 334は24bit) TEXT: TEXTAA: LINE: BOX: CIRCLE: PATBLT: BLT8: BLT16: BLT24: SCROLL: 2097: 92: 15399: 58096: 22248: 4980: 690: 400: 305: 4977: AGP: Rage Fury 433: 312: 2427: 25629: 8581: 2485: 294: 204: 245: 1671: AGP: Reality 334 324: 228: 9655: 9784: 10233: 1231: 270: 150: 212: 467: PCI: PW968PCI
_ Rage FuryはPIII-733MHz機でW2K、それ以外はK6-266MHz機でWin98SEだから、本当は単純比較してはいけないことに注意。
_ PW968PCIで16bitの結果を採り忘れたのは失敗だったなぁ・・・なお、これはWin98SE標準のS3 968ドライバでなくカノープス製Win95用ドライバで計測している。標準品より1〜2割速い。
_ PATBLTとSCROLLは、さまざまな事情*1により理論最大値が5000。Rage Furyのそれは事実上振り切っていると思っていい。
*1: 短期間に大量にPATBLT/SCROLLを発行すると、Windows本体のタイマー処理がキューに溜まったまま処理されない状態になってしまう。すなわち処理時間の計測が不可能になってしまう*2。このため、これらは1度の実行につきSleep(1)(1msec停止)している。これでも、いくつかのビデオカードでは正しく計測することができず、どうしたものか思案中。
*2:
この現象が起こる場合、HDBENCHでも正しく計測ができない。SCROLLでいつまで経っても終了しないという事態になる。そのせいか、Ver.3系では消滅したっけ・・・。
_ ・・・なぜか追加物件。
_ どうにも画はダメそうなのは分かっていたんだけど、なんとなく・・・^^;。実際、RIVA128に非常に酷似した出力具合。暗めで、白黒のエッジがぼや〜っとする感じ。1024x768まではなんとか我慢して使えるが、それ以上では使う気にならない。
_ まぁ、どっちも安カードだから、チップだけじゃなくてアナログ周りが足を引っ張っている気がせんでもないが。最近のGeForce系もこんな感じなのかなぁ・・・。
_ というわけでベンチ。速度もやっぱこんなもんか・・・。
●1024x768, 32bit(Millenniumは24bit) TEXT: TEXTAA: LINE: BOX: CIRCLE: PATBLT: BLT8: BLT16: BLT24: SCROLL: 900: 110: 16889: 28694: 19845: 4044: 559: 386: 294: 1744: PCI: TNT2M64 919: 113: 9776: 16480: 17013: 4984: 501: 360: 322: 704: PCI: Millennium 2155: 118: 13854: 41584: 22179: 4980: 669: 390: 297: 4902: AGP: RAGE Fury ●1600x1200, 16bit TEXT: TEXTAA: LINE: BOX: CIRCLE: PATBLT: BLT8: BLT16: BLT24: SCROLL: 992: 129: 9086: 50430: 25261: 4984: 548: 527: 386: 4984: PCI: TNT2M64 1091: 112: 10712: 73567: 38396: 4710: 626: 451: 354: 942: PCI: Millennium 2124: 129: 13277: 76052: 26339: 4984: 988: 543: 391: 4354: AGP: RAGE Fury ●1600x1200, 32bit TEXT: TEXTAA: LINE: BOX: CIRCLE: PATBLT: BLT8: BLT16: BLT24: SCROLL: 672: 111: 5880: 16196: 13676: 2120: 551: 348: 288: 979: PCI: TNT2M64 2035: 92: 10757: 30331: 18694: 4088: 697: 400: 306: 2006: AGP: RAGE Fury
_
ユーフォリーは酒井さんの持ち込みだったのか・・・知らなかった^^;。X68キャメルトライでしばらくご一緒したことがあるんですが、それは聞いたことがなかったな・・・。\
void GetMonthName( int month, char *retbuf ) { char *monthname[] = { "", "Jan", "Feb", "Mar", "Apr", ... }; strcpy( retbuf, monthname[month] ); }
_ これだと、わし的にはマイナス。fineな答えだと、こう。
void GetMonthName( int month, char *retbuf ) { static char *monthname[] = { "", "Jan", "Feb", "Mar", "Apr", ... }; strcpy( retbuf, monthname[month] ); }
_ どう違うかは、アセンブラソースを吐かせて確認するべし。答えはこちら\。
_ 何やらとんでもない話になってきました・・・(藁。いや別にウォッチャーしているわけじゃないんですが・・・^^;。
_ 現状では、どうあってもプラエセンス不利・・・つーか自ら首締めたよな・・・。
_
ああ、トップページのタイトルが変わったな・・・こっちも対応。正式名称と「愛称」ということで。
staticの話。この場合、「static char *monthname[]」のstaticが目的としているものは、「char const *monthname[]」と同義です。やり方が違うけど、塩兄ちゃんとこも参照。
_ ROM化まで考えるなら、constを使うほうが正しいです。それも「char const * const monthname[]」と書くべきです。こう書くことで、「"Jan"・・・」とそれを指すポインタの配列の両方がROMに置かれ、アクセスはそのROMアドレスをアクセスするだけになる、というコードが出ます。
_ ですが、手持ちのコンパイラ(bcc32とcl)で試したところconstでは目的のコードは出なかったんです。どっちもROM化は考慮されていないから当然かも知れんけど(笑)。・・・と思ったら、monthstr[]の定義を関数内スコープじゃなくてグローバルスコープに置かないといけないんですな。
_ 種明かしを。staticがない場合、関数は「monthname[]に各ポインタ値を再ロードする」という初期化をまず実行します。定義付きローカル変数は関数の開始時に初期化されますから、配列の中身も毎回初期化されるということです。
_ 具体的には、monthname[]は、
_ というアクセスのされ方をします。staticが付くと、
_ となります。実行時間・メモリとも当然消費量が減ります。
_ グローバル変数として「char const * const monthname[]」と書いた場合は、
_ となります。誤って「char const *monthname[]」と書いた場合は、
_ となってしまいます。「書き換え可能データセグメント」をRAM、「書き換え不可データセグメント」をROMと読み替えると、よくわかるかと。
_ ポインタでなくstrcpyして返したのは、「引数で渡されたchar*型にstrcpyした」と書かれていたのを仕様として従ったまでです。本チャンのコードなら、必要に応じて添字範囲チェックやバッファオーバーフローチェックをする(strncpyを使う)のは当然のことです。ただ、「実処理コードよりチェックコードの方が大きくなって本来の内容がぼやけてしまう」のはよくあることで、今回はまさにそれで、内容からするとチェックコードを入れる必要はないだろうという判断で省きました*1。
*1:
でも、「配列を12個確保して添字を[n-1]にする」というセコい方法を今回とらなかったのは、ポカミス回避のひとつの方法。この手の関数の月を示す引数に誤って0を渡してしまうのはよくあるミスで、このとき[n-1]を叩いてしまうと配列外を叩くコードになってしまう。しかもこの手のバグはコードが大きくなってくると発見が困難になりがち。それなら添字1つ分余計に確保して確実に空文字列を返すほうがまだ安全。
添字チェックをちゃんとすればこんなことは考えなくてもいいんだけど、それと同時に「同程度の打鍵数でよりバグを出しにくい、あるいは出ても発見しやすいようにコードを書く」という手抜き技も重要。
実際のところ、チェックコードを的確に入れるのはかなり面倒で、わし自身は「わし以外が作用する可能性がある」部分、つまり入出力UIやpublicな関数の引数にしかチェックコードを入れないことがほとんど。もちろんライブラリやデバイスドライバのような(一般アプリでない)コードには大量のチェックコードが入ることになる。
_ しかし、最近はデータ領域どころかスタックさえ知らずにCで開発する人も少なくないからなぁ・・・^^;。\
_ 「自業自得」ねぇ・・・わしには、そもそも「仕返しや報復」に相当するようなものを受けたようには見えないんだが。「ああ、やっと買ってくれたか。しかもつまらん方法で。しょうがないなぁ」という感じにしか見えない。
_ いくら毒づこうが、そんな言葉は飾りでしかない。モノを作ってしまうこと、そしてできてしまったものが最大の「毒」のはず。紳士的に言葉を発したところで、変わりはないんじゃないかと。
_ 本家「ペルソナウェア」は、いわば外部リソースから与えられたテキストを出力するデスクトップアクセサリ。いわゆる「仮想人格」部分は端末上で存在を示す「アクセサリ画像」がフキダシという「ウィンドウ」に「文章」を出力する形で作られる。この部分と、いくつかのイベントハンドラを外部開発者、いわゆる「ベンダ」が追加できることで、バリエーションを生むことができる。
_ 対して「偽春菜」(愛称)は、人工無能による文章生成、語彙の選択による人工無能の性格付け、うにゅうという「相方」の提供による「会話」の模倣、任意のwebサイトの文章を得る追加プログラムやローカルプログラムからの文章を受けて出力あるいは人工無能への情報の提供、そして最終的にこれらで得られる文章を「アクセサリ画像」がフキダシという「ウィンドウ」に表示するという機能を持ったデスクトップアクセサリ。
_ 実は、この2つにおいて同じ点は「アクセサリ画像」が「ウィンドウ」に「文章」を出力する、という点しかない。「ペルソナウェア」はこの部分のみを実装して事実上開発を「終えてしまった」のに対し、「偽春菜」は「そのような環境があったら何を表現するか」というところから開発が始まっている。この差は大きいのではないか。
_ そうでありながら、競合でなく、自ら「偽」という名前を冠することで影となる。自ら影になることは、普通ありえない。それが実体より優れていると思えばなおのこと。一般的に、影は実体より低価値で存在の薄いものとされ、また逆になることは実体にとって最大の恐怖。
_ とはいえ、恐怖のあまり叫んでしまったら負けなわけで、また影と実体が逆になってしまっても負け。しょせん影は影でしかないと思い知らせるしか、実体を維持させる方法はないはず。
_
ああ、そういえば、本家の「春菜」は「ペルソナウェア」というアプリケーションの一人格としての実装であり、外部ベンダにはこの人格部を作成する開発キットによる新しい人格の提供を「求めている」のだが、この姿勢と「偽ペルソナウェアあれ以外の何か」という別アプリケーションの一人格である「偽春菜さくらと呼ばれるもの」の人格(キャラクタ)が「似ている」と主張して配布停止を要求する姿勢は、どこかかみ合わない妙なものを感じるのだが。というか、それより前にあの2つの人格が「似ている」とは、到底思えないのだが・・・(笑)。
_ 「偽春菜」の毒吐き機能は、それが「『偽春菜』という人格に負わせた個性」だからだと思いますが。あの機能はエンジン部でなく、人格形成部で実装されている機能です*2。
*2:
"#enemy*"のスクリプトオーバーライドで回避できます。スクリプトオーバーライド参照。こんな感じか。
[SAKURA] #enemyexists count1 #enemyexists0 \s4‥‥\e #enemycome count1 #enemycome0 \s4‥‥\e #enemyremove count1 #enemyremove0 \s4‥‥\e #enemytalking count1 #enemytalking0 \s4‥‥\e
_ あと、件のメールにはwebや『偽春菜』上で「ペルソナウェアについて不当な評価を下した」とは示されていません。その点を問題にするなら、必ずこの項は含まれるはず。そもそも、あるソフトが別のソフトを忌避すること自体は珍しくもなんともないことです。
_ そもそも、人気の理由のひとつにはこの「性格に大きな毒を持たせた」キャラクタ作りそのものにあると思っています。それが嫌いなら使われないはずですが、それでも人気があるということはやはり「毒が欲しい」人は少なくないということじゃないですかね・・・。
_ とか言いつつ、結局出発。
_ ちょうど昼ころ、建物前に到着。ん〜150人くらい並んでますか? 2時間くらいかかりますか?
_ やあ3と合流して行列開始。10分くらいで建物内へ通された・・・と思ったら階段並び。そこからさらに20分くらいでようやく入場。なんだ2時間もかかんないじゃん。
_ ・・・甘かった。入場してからトプカの列を探して最後尾について、そこから1時間でようやく店内。
_ とりあえず、いつものムルギを大盛で。4〜5分で来た・・・早いな。開店セール中につきスープはないらしい。やあ3も同じ。
_ 完食。大塚のより、ややコクが薄い気が。その分酸味と甘味が強めになっているようで、バランスはとれているかなーと。ウマシ。
_ 遅着してわしらの後ろに並んでいたかけーんを待ちつつダベってたり、制服見学だったりしつつ。
_ で、結局出たのが3:00PM過ぎ。下のゲーセンでかけーんがちょっとヒーローだったらしい(笑)。
4:30AM充電開始、0:00PM再起動。
_ なんかいろいろ買ったまま書き忘れてるなー・・・。
メールはこちらへ...[後藤浩昭 / Hiroaki GOTO / GORRY / gorry@hauN.org]