第58回 386ASMもちっとやる(カリカリプログラミング) 99/6/23
前回、ある関数のメンバ関数のオフセットが得れないとか書いてしまったが、クラスの関数テーブル(lpVtbl)におけるある関数ポインタへのオフセットがサクっと得られないだけであって、関数のアドレス自体は、クラス名がわかっていれば、
typedef void (ClassName::*FUNC)(void);
FUNC fp = ClassName::function;
のようにして、得ることが出来る。のではないかというご指摘をいただいた。確かにその通りなのだが、
1.クラス名が事前にわかっていなければならない。
それを避けるために、Hookするときに、関数ポインタとthisポインタだけを渡して、それを頼りにコールバックしてもらうとしても、
2.その関数を呼び出すためには、ポインタthisを切り替える必要がある。(ポインタthisはconstなclass*だからして変更が利かないのある。一般的に言って安全ではない)
ということで、今回のケースでは使えないという結論になったのである。残念。
さて、今回は、DirectDrawである。いま、画面のフェードアウトルーチンを作っているのだが、こいつがすこぶる遅い。もともと、256色パレットを利用していたのだが、65536色とかtrueカラーとかフルカラーにまで対応させる必要が出てきたので、ソフト的に色を減衰させるルーチンを書いていたのである。(ハードウェアパレットが使えるのは256色に限るため) そのうち、フルカラーどころか、富士カラーにまで対応させろ!とか言われそうで恐い。(それはフイルムだってば...)
DirectDrawを使ってんだから、サーフェースのメモリを得て、あとはアセンブラでカリカリ書くだけでないの?
そう簡単に言わんとってよー(笑) モードごとにBPP(bit per pixel)が違うから、それぞれのモードごとに減衰ルーチンを用意する必要があるのよ。
だからどうなの?
65536色なんか、RGBの配分が5bit:5bit:5bitとは限らない(6:5:5とか、5:6:5、5:5:6という4つのパターンが仕様の上では存在する)もんで、高速化のためには、それぞれ個別のルーチンが必要になってくんのよ。同様にtrueカラーもそうやね。そうなってくると...うーん。
アセンブラ化なんてやめればー?
君ぃ、そんなことゆうてもやねぇ、このCeleron366MHzで、フルカラーモードで、普段は100FPS(frame per second)も行ってたのに、フェードアウトをはじめたとたん、5FPSになっちまったのよ!もう泣くしかないね。もち、減衰テーブルは用意してあって、
for(int x=0;x<mx;x++){
*p = table[*p]; p++;
*p = table[*p]; p++;
*p = table[*p]; p++;
}
とかやって、ループチェックを3回に1回にしてるし、バイト単位のアクセスとはいえ非常にシンプルなのに、どこで人生を誤ったのかは知らないが、5FPS!!もう、俺は死ねっちゅーことか!?
これって、アセンブラで、
mov esi,es:[edi] ;
こんな命令あんのか?
movsb ; ES:[EDI++] = DS:[ESI++]
これでええのんか?
とかなって、2命令で済めば、1命令=1クロックの世界ならば、すんげー速い気もするのだが(もちろん、ワンラスター分×3回これをマクロ展開しとくんよ。それが無理ならば、32回分ほど展開としといて、最初に端数合わせのためのジャンプをかまして、あとは32回に一回ループのエンドチェックを行なうんよ!)、どうも、世のなか、そんなにうまくは出来ていないようである。
しかし、ホームページでアセンブラの話を延々と書いててええのんか?そのうちMMX最適化にまで走りそうな自分が恐い。そもそも、ここって誰が見てんの?親戚のおじいちゃん、おばあちゃん見てるー?やねうらおは元気だよー。蒸し暑い日が続くけど、干からびないでねー。(見てないって!!>親戚)
第59回 ああ神様!アホ学生達に救済を!(新プログラミング入門) 99/6/26
なんか、最近、有用なことしか書いていないような気がして、これではいかん!と思っている。中学・高校の数学の教育免状を持っていながらこんなことを言うのは気が退けるのだが、そもそも、啓蒙や教育というのは、でいっ嫌いなのである。だいたい、この連載、嘘が多いので有用かどうかは怪しいのだが...。ちょっと方向転換して、この業界の話について書いていくことにしたい。
まあ、プログラミングなんてもんは、自分で理解しないことには前に進んではいかんのである。誰かに教えてもらおう!なんてのがそもそもの間違いなのである。逆に、自分で理解しているならば、いくら進んでも良い。だからして、誰か先生がいて、自分は席に座って聞いているだけで、どこかへ連れてってもらえると思っているのは、勘違いも甚だしいのである。コンピュータ専門の学校に行くやつはだいたい、そういう甘えた連中なのだ。そんな態度だから、いつまでたっても賢くならんのである。本をちょっと読めばわかることをいちいち質問してきよる。尋ねればすぐにでも教えてもらえると思ってるんだから!専門教育ってのは、いま持ってる才能を伸ばすためのものであって、何の才能もないところに種をまいて水をやり栽培するための場所では無いのである。
「じゃあ勉強したけりゃ、学校なんて行かずに自分でやれってーの?だって何からやっていいかもわかんないんだよー。子供のころからゲーム好きだし、子供達に夢を与えるゲームを作れるプログラマになりたいんだよ!そのために専門学校に行って一から勉強したいと思ってるんだ。それが、そんなにいけないことなの?それがそんなに間違ってることなの?勉強をする気が無いんじゃないんだ。何を勉強して良いか、その方針がまったく見えないんだよ。だから、専門学校に行くんだ。何もかも教えてもらおうなって思っちゃいないよ」
真面目な顔でこういうことを言われると、やねうらおは、返す言葉を失ってしまう。何をやっていいかわかんないからどうしようもないという論理は、ときとして正論に見えるが、実は、自分の不遜を正当化するだけのものである。そもそも、書店に行けばプログラミングの本なんて山ほど並んでいるんだから、専門学校に払う学費の1割でもそれに充当するほうがよっぽど健全だと思う。どの本を買っていいかわからないだなんて理由にならない。JavaでもC言語でもVisualBasicでも何でも良い。とにかくスタートラインを切ること。そして、走り出すこと。走る前から、うまく走れなかったらどうしようだなんて考えても仕方がない。そして、どちらを向いて走れば良いかだなんて、問題ではない。それは、うまく走れるようになってから考えれば良いことであって、走り方がわからないだとか言って、ただ立ち止まっているだけの人間が考えるべきことではないのである。
「そんなこと言ったって、自分でいくらプログラミングの勉強したって、結局は就職できねえんだよ。ゲーム業界に就職するためには、ゲームの専門学校を卒業しただとかそういった学歴がまず必要なんだよ」
そう言われると、またもや返す言葉に困ってしまう。ある意味、事実でもあるからだ。しかしやねー、そしたらプログラミングに関して履歴書に書けるような資格・学歴も無いやねうらおが、学生時代からコンピュータ業界で働いていたんは一体なんやったゆうんや?プログラムゆうたら、出来ると出来ひんの二つに一つとちごたんか?出来るんなら、学歴なんてカンケーあらへんのとちゃうのんか?
「それによ、これからのゲームプログラミングってのはそんな甘いもんじゃねぇんだよ。たとえば、3Dでプログラミングやるなら、ただ回転行列の計算が出来ればそれでOKってわけじゃあない。ポリゴンモデラぐらい経験してなけりゃ、雇ってもらえねぇんだよ。大学教養レベルの数学の知識プラスαってのが大切なんだぜよ」
そんだけ理解してんなら、好きにせー!である(笑) でも、専門学校に行く奴でそこまで覚悟を決めてる奴って、クラスに一人か二人ぐらいしかいてないんだよなー。そういう奴って、最初っからプログラムがある程度できるの。で、就職のときにゲーム業界に就職するのも、そういう奴らだけ。あとは、親のあとを継ぐだとか(何のために学校行ったの??)、ゲーセンの店員になるだとか、普通の会社でコンピュータのオペレータをやるだとか、まったく当初の希望とは違うところに就職するのである。
どっちかっちゅーと、ゲームプログラマになりたいんなら、普通の大学行って、大学在学期間中に勉強すればー?という気がしないでもない。ままま。僕の個人的な意見だかんね。聞くも聞かないも自由よ。
第5A回 フルカラーって、なんでこんなに遅いんや?(もー、いやん) 99/6/29
☆ しかしMutexはそれほど遅くはなかった
ぷよーんさんにご指摘をたまわったのだが、毎回ハンドルを登録してたら遅いのは当たり前であるとのこと。そりゃそうか...。
☆ 5FPSは嘘
フルカラーモードだとフェードアウトするとき5FPSと書いたが、正確なFPSタイマを作って測定したところ、2FPSだったのよん(笑) やっぱし、バイト単位のアクセスってめっちゃ不利みたいやね。アセンブラでキチキチに最適化してもたぶん8FPSぐらいしか出す自信がない。trueカラーさえフェードアウトのときに15FPSぐらい出てるから、やっぱし、1ピクセル3バイトってのが、どうも386のアーキテクチャとは親和しないのかも知れない。つまりは、俺の負けか?これでは使いもんにならん。elのソース見たら、フルカラーのくせして、まずは32bpp(trueカラー)を試してだめなら24bpp(フルカラー)を試すという仕組みになっている。一般に、フルカラーモードは遅いようである。内部的には4バイト1ピクセルで実装されていてメモリアクセスごとに例外割り込みが発生してるのかも知れない。(余談だが、この開発用のNTマシンに載せているビデオカードはRageIICと言って、おそらく市場に出回っているもののなかで最低最悪のものである。ソーテックの安売りパソコンにも使われているんで、有名かも知れない)
原因はともかく、これだけ遅ければまずゲーム中に使えないことは必至である。フルカラーの場合はtrueカラーに切り替えるのも一策だが、CanBeなどではtrueカラーにビデオカード自体が対応していないが、そういうとき、フルカラーにすべきなのか65536色まで落とすべきなのか選択に迷ってしまう。やっぱユーザー様に選択させるべきだと思うんだけど、余計なインターフェースを実装しないといけない分、なにかと負担がかかる奴である。
とりあえず、いまのルーチンは、4バイトずつ読んでテーブル処理して、4バイトずつ書き出すようにはしている。以下が、そのプログラム。これで6FPSぐらい。まだ少しは最適化の余地はあるのだが、386のアセンブラなんて、パイプラインやら分岐予測やらで、どの命令がどの命令より速いのかさっぱりわからんからして、こんなもんでしょう。フェードアウトのためのピクセルの減衰って、結局は、掛け算だけだから、おもいっきしMMX最適化に向いていると思うのだが、そんなことをして遊んでいるばやいではない。まして、MMXのマニュアルをインテルのホームページから英文のものをダウンロードして読みあさっていた日にゃ、いつまでたっても出来やしねぇ。
// ワンラスターに対するオペレーション
_asm { push edi push esi lea edi,table mov esi,p mov ecx,LP // loop counter xor ebx,ebx lpp: // ワンループで4バイトずつ処理する mov eax,[esi] mov bl,al mov dl,[edi+ebx] mov bl,ah mov dh,[edi+ebx] mov [esi],dx shr eax,16 mov bl,al mov dl,[edi+ebx] shr eax,8 mov dh,[edi+eax] mov [esi+2],dx add esi,4 loop lpp pop esi pop edi }
そうそ。このプログラムは、プライマリバッファに転送するときに減衰をかけてるんではなく、セカンダリバッファ(バックバッファ)上で、直接減衰をかけるようにしてある。あまり効率が良いとは思えないけど、ウィンドゥモードだとWM_PAINTに応答して画面を表示する必要があり、そのときセカンダリバッファをどかーんと転送すれば良いだけの状態にしてあるほうが簡単だから、こういうのが好きなのである。こんな遅いビデオメモリの上でぐりぐりいじくり倒すより、素直にユーザーメモリ確保して、そっちでぐりぐりやったあとに一括して転送したほーが良いという気もするが、そんなことして遊んでばかりもいられないので、これで良しとしよう。良しとするんだってば!!だからして、文句のある者は放課後生活指導室まで来なさい!(生活指導室ってどこやねん!)
第5B回 サーフェイスの性能評価(DDSCAPS_SYSTEMMEMORYについて) 99/7/1
DirectDrawで直書きでぐりぐりいじり倒したときに遅い原因は、だいたいつかめかけている。やはり、仮想フラットフレームバッファの実装のためにページフォールトハンドラが使われているようである。試しに、システムメモリ上にバックバッファを作成してみると、フルカラーモードで以下のようになった。
VIDEO MEMORY | SYSTEM MEMORY | |
通常時 | 50 FPS | 40 FPS |
フェードイン時 | 4 FPS | 18 FPS |
フェードインに差し掛かると、ビデオメモリをぐりぐりやるほうは4FPSしか出ないのに対し、サーフェイスがシステムメモリであれば、通常時のおおよそ半分程度にしか落ちない。半分というと落ちすぎにも見えるが、実際のところ、バックバッファ上でフェードインのための減衰処理を行なっているにしては、ずいぶんといい数字のような気がする(アセンブラでリライトした効果が出た)
ついでに言えば、このビデオカードはずいぶんと安物なので、ビデオメモリを使ったときの数値が通常時でさえシステムメモリの1.2倍程度の数字しか出ていないが(普通にWin32のBitBltをしても30〜40FPSぐらいだろうから、このマシンでDirectDrawを使う価値はほとんど無いと言える)通常、ビデオメモリを使ったときの速度は、80FPS〜200FPSぐらいは出るはずである。一方、システムメモリを使った場合は、ひとえにマシンスピードがものを言ってくるわけで、開発に使用しているCeleron 366MHzでは、この40FPSなのである。Pentium166MHzぐらいでなら、25〜30FPSぐらいではないかと思う。あるいは、ビデオメモリのロックにWin16Mutexが使用されているとか聞くんで、ひょっとするとWindowsNTのほうがWindos95/98に比べて不利なんかなー?とか思ったりもするが、そのへんの事情には疎いので、まったくわからない。
じゃあ、SYSTEM MEMORYとVIDEO MEMORYとどちらを使えばいいの?って尋ねられそうだけど、こんな風に、ぐりぐりやるならばSYSTEM MEMORYしか選択の道はないでしょう。それ以外のゲームでも、選択できるようにしてあるほうが親切やねー。ちなみに、ハイカラー(65536色)では、ビデオメモリをぐりぐりやってもそれほど遅くはならない。これは、1ピクセルが1ワードになっている効果で、ページフォールト自体が発生していないか、そのハンドラがごくごくわずかな処理で済んでいるせいだろう。今後、すべてのゲームはハイカラーメインになってくるだろう。そうなってくると、うざったいパレットの問題もなくなって、なかなかにハイカラである。(なんのこっちゃ..)
何にせよ、ここ一年のCPUの低価格化には目を見張るものがある。一年前の最新パソコンが、いまや入門機にも劣っていたりする。いまやPentiumIIの450MHzクラスをガキんちょが持っていたりするし、それぐらいの性能さえあれば、DirectDrawなんて使わなくても十分だろう。そのレベルのマシンを誰しもが持つ時代はもうそこまで来つつある。ここの記事もWindows2000が普及するころには、「まったく馬鹿な奴がいたもんだ」と笑われるのかも知れない。僕はむしろそうなることを願っている。
第5C回 協調モードにおけるDirectSound(案外知られていない?) 99/7/3
以前、「いまDirectXを勉強中なのだがBM98は音が悪いのでソースを俺にくれたら修正してやる」という趣旨のメールを、受け取ったことがある。この人に限ったことではないが、くれくれ〜言ってくる人って、ちょっと何考えてんのー?と言いたくなることがある。
そんなもん、見ず知らずで初めてのメールで自己紹介もなーんもしてこず、いきなりソースくれくれーで、お前だれやねん?と言いたくなる特定個人に渡すぐらいなら、とっくの昔にオープンにしとるっちゅーねん!
おまけにやなぁ、音悪いって、それはDirectSoundを協調モードで動かして、サウンド再生周波数を変更しとらんからに決まってるやん?協調モードで動かす限りは、プライマリバッファを取得できんから、再生周波数は変更できんのよ。完全にフルスクリーンで動いてる分には、別に優先協調モードか排他モードにしても良さそうなものだが、実はウィンドゥモードに対応する予定があったから、それはそうなっとんのよ。排他モードにして、プライマリバッファ取得して再生周波数変更するぐらい数行書けば出来るに決まっとんがな。馬鹿にすな!っちゅーねん。あえてしてへんっちゅーことがなんでわからんかなー。それを修正してやると言われた日にゃあ泣きたくなるよ。自分、それでほんまにDirectX勉強中なんか?そもそも、君は共有モードでのDirectSoundのプライマリバッファが、ステレオ8ビット22KHzに設定されることを知っているのか?これを”音が悪いから修正”するんなら、ステレオ16ビット22KHzかステレオ16ビット44KHzぐらいなんだろうけど、そんなことしたら、音を重ねてる曲データではめちゃんこ重たいやん?それを承知で勝手に初期再生レートを変更して、ユーザーにそれを強要することが、君の言う修正なのか?それともオプションのメニュー選択部分までちゃんと”修正”してくれるのか?ついでに言えば、再生レートとデータのレートが違うとセカンダリバッファに読み込むときに変換に時間がかかって、非常に読み込みが遅くなるのため、そのへんを考慮して、ステレオ8ビット22KHzのデータを用意しておられるデータ作成者の方々は、どうなるんや?君は、そのへんをちゃんと”修正”できるのか?DirectSoundを使用する限り、バッファの再生周波数に合わせてデータを作成すべきだと思うし、そういう意味からしても、ユーザーにプライマリバッファの再生周波数の変更を許可するっちゅーのは、どうかとも思わんでもない。
第5D回 4で繰り上げる(こんなん常識?) 99/7/4
たとえば、ビットマップを操作していると、アライメント調整のために、DWORD単位に”繰り上げる”必要がある。
355円→360円ならば、「10で繰り上げる」とか言うから(言わない?)、これは、4で”繰り上げる”なのだ。
素直に(?)、組むなら、下位2ビットが0でなかったら、下位2ビットをクリアして4を足せば良いんだから、
if (D & 3) D = ...
はっきり言って、if文が入っている時点で、かなりダサイ。新入社員ならともかく、こんなプログラムを組んでいた日には、仕事がこなくなる。roundup by 10がinteger of (x+9)と等価であることを思い出せば、3を足してから下位2ビットを切り捨てるのを思いつくのは、難しくない。
D = (D+3)/4 *4;
まあ、こう書いていれば、及第点は差し上げよう。しかし、割り算と掛け算が入っているのがダサイ。まあ、2^nの掛け算と割り算は最適化でビットシフトに置換されるとしても...
D = (((D+3) >> 2) << 2);
うーん。やっぱ見づらいなあ(笑) そもそも、下位2ビットをクリアするのにビットシフトはないんでないのー?
D = (D+3) & 0xfffffffc;
これで、2回のビットシフトが1回の論理ANDで済む。しかし、プロたる者がこんなプログラムしか書けんのでは、ちょっと勉強が足りんなーと言わなければならないだろう。普通は、
D = (D+3) & ~3;
こうである。3の補数と論理ANDをとることによって、下位2ビットをクリアしている。なんか知らんが意外とこれが出来る人は少ない。最近のプログラマは、高級言語に慣れすぎて、基本的な論理演算をあまり理解していないような気がする。ついでに言えば、仮に、このあと8倍してビット数をカウントするとしても、
D = ((D+3) & ~3) << 3;
だから、美しいことに、+3、〜3、<<3と3が並んでいる。昔のアーキテクチャなら3をいったんレジスタに入れておくような最適化がかかって、非常に速そうである。ただ残念なことに最近のCPUは即値でもレジスタでも同じクロック数だろうから、あまり意味がない。
まあ、こんな細かいところをこだわっても仕方ないという話もある。確かにそうかも知れないが、日頃からこういう部分をきちっと考える習慣は大切だと思う。前フリは、これくらいにして(えっ?これが、前フリやったんか?)、86系のアセンブラに興味のある人は、是非、
http://www.intel.co.jp/jp/developer/vtune/cbts/contents.htm
から命令表(日本語PDFファイル)をダウンロードしよう。これさえあれば、アセンブラの本なんか不要だからして!
第5E回 シーン描画関数について(ゲームのフレームワーク) 99/7/5
やねうらおは中学のときから、数学の授業中は、「大学への数学」と「数学セミナー」を愛読しつづけていた。社会の時間は教科書にパラパラ漫画を書きつづけ、国語の時間は夏目漱石を山折り谷折りにして「笑ってる」などと言いながらけらけら笑い出すという、日本教育史上でも、たぐい希な問題児であったと言えるだろう。言うのも恥ずかしいのだが、当時は、東大すら眼中になかった。(かと言ってそれほど成績が良かったわけではない。特に暗記ものは生理的に受け付けなかった。そういう人って、結構いるよね?)そのくせ、
日本の大学は馬鹿ばっかだから、とりあえずMITかKunth先生のいるStanford大学にでも行こう!
と思っていた。ホント、なめたガキんちょだったのである。ちなみに、当時撮った卒業写真等は、すべてあさっての方向を向いている。カメラがどちらにあるかあまりわかっていなかったのかも知れないし、つねにあさっての方角しか見えてなかったのかも知れない。いま、思い返すに、かなりのドアホだったと言えよう。
さて、今回のお題は、シーン描画関数である。これはメッセージ処理中に、シーン描画のために呼び出される。シーン描画というのは、ある瞬間のゲーム画面のことである。ゲーム自体をシーンという構成単位にフラグメント(断片)化して、それを堆積していくようなスタイルはあまり好きではないのだが、たまには、そんなんもええんちゃうか?と思って、そないしてみた。
ところで、次のシーンに移るためには、次のシーンの番号ではなく、関数ポインタを
ysFrame.SetNextScene(Scene2); // void Scene2(int __SceneControl);
こんな感じでフレームワークを介して設定してやることで、そのシーン描画が終わると、次に呼び出されるのは、Scene2になっているというわけである。なかなか、スマートだ。(<そう思ってんの俺だけ?)
問題は、まずシーンの初期化である。すなわち、ビットマップファイルの読み込みとかそういった類のものである。それをどこで行なうかと言うと、やっぱりシーンの頭で行ないたい。そうなってくると、そのシーンを最初に呼び出されたのかどうかを判定するための方法が必要になってくる。
大丈夫。シーン描画関数がパラメータをとっているのがわかると思うが、こいつがミソである。そのシーンに切り替わって、初回に呼び出されるときには、こいつが1になる。最終回(?)に呼び出されるときは、こいつが2になる。これによって、安全にポインタをnewして、deleteする手段が提供されることになる。まあ、このへんはマクロを用意するので、それほど不格好ではない。
あとは、シーンをCallするというのもある。こいつは、呼出しをCSceneArrayに記憶しておく。こいつは、描画関数のポインタ配列で、可変長配列をテンプレートで実装しているので、実際は、以下のように
typedef CArray<void (*)(int)> CSceneArray;
なっていて、こいつをスタック的に(素直にスタックを実装するか、STLを使えばいいのに、他人のライブラリ使うぐらいなら自作したほうがわかりやすいなどと頑固ジジイのようなことを呪文のように唱えながら)使用することで、シーン描画関数の呼出しの履歴を保存しておく。もちろん、履歴を保存するのは、呼出し元のシーンにReturnするためでもあるが、それより、ゲームを途中で終了させたとき、この履歴をたどって、履歴にある描画関数のデストラクタを確実に呼び出すことを保証するためである。
仮に、このようなフレームワークの実装ではなく、スレッドをもうひとつ起動して、片方は描画とメッセージループの処理、片方は、ゲーム処理を担当させているようなものを考えたとしても(そっちのほうが実装はすっきりするのだが)、WM_CLOSEに応答して終了させてしまうとなると、newしていたものを確実にdeleteするのは至難の業となってくる。んなもん、classのデストラクタでやらせればいいじゃん!と言われそうだが(まったくもってその通りなのかも知れないが)、WM_CLOSEに応答して、ゲームスレッドの終了シグナルを待つ部分をきちんと実装するとなると結構、汚くなってくるだろうし、何よりゲーム全体をクラス化しなさいと強要しているようで、今回は採用を見合わせた。
プロトタイプを組むときは、いろいろいじくり回すので、いちいちクラス化しないほうがプログラムが楽チンである。ある程度、構想が固まってきてからクラス化していく。そうするには、やっぱり今回のようなフレームワークのほうが適しているように思う。(他の人はどうやってんやろ??ご意見・ご感想などありましたら、お気軽にやねうらおまでどうぞ<そればっかし)
第5F回 PentiumIIのアセンブラ(やねうらおが日本一の馬鹿に成る日) 99/7/8
第5D回で紹介したインテルのサイトからアセンブラの資料一式をダウンロードしてきて、まる一日眺めていた。ふんふん。分岐予測のアルゴリズムもわかったし、パイプラインのステージも明確に書かれているし、この資料があれば、386,486とPentiumとPentiumProとMMXとPentiumIIのどれであるかさえ限定すれば、正確にクロック数が算出できるだろうから、それぞれのCPUに合わせた最適化が出来そうである。
えっ?6つのCPU個別のルーチンを用意するの?
なめてもらっては困る。ここにさらに、PentiumIIIとK6とK6−2,K6−3などもきちんと場合分けをして、それぞれのCPUごとに最適なルーチンを...って、んなことすっかい!!
僕が言いたかったのは、よくパイプラインの処理や、アライメント、ストールの問題、分岐予測ミスのペナルティなどが入ってくるとクロック数の算出は困難である(時として不可能である)とよく言われるが、そんなことは無いということである。気合を入れて、これらの技術資料をすべて読めば、クロック数を計算もそれほど難しくはないことがわかる。(分岐予測のペナルティについては、分岐予測を失敗する確率を計算して平均クロック数を算出する等の工夫は必要。フローを示す遷移行列作って分岐確率を考慮してどうのってところまではしなくて良いと思うけど)
それにしてもやね、データシートにこの命令は何クロックですよ、この命令は何クロックですよ、と書いてあった時代と比較すれば、恐ろしく複雑になっていることは確かである。そういう時代にすくすくと育ってきた人たちが、いまのCPUアーキテクチャを見て「ダメじゃん〜」と言ってアセンブラから離れて行ったとしても不思議ではない。その自分の努力の足りなさ(?)を正当化するために「もはや、パイプライン処理が入ってくるとクロック数の算出なんて出来ないし、まして...」という口調で語られても不思議はないが、そんなことはない!やれば出来る!!PentiumII君は、やれば出来る子なんだから!もっと真面目に学業に励もうよ!来年は受験なんだし、親御さんも期待しておられるし。それに長男なんだから...。(一体、何の話や...)