パイプラインとストールと2

昨日の続き。

んで、CPUの内部は分担作業を順番にこなすことで高速化をしていて、
それをパイプラインというわけだ。

ところで、命令には色々あって条件によって分岐する命令もある。

昨日書いた、↓は、順序よくこなしている物の、1~3はある意味で先読みをして先行着手している状態だ。

1,メモリーから命令の読み出し
2,命令の解釈
3,命令に従って別のメモリーからデータの読み出し
4,読み出した命令の実行
5,実行結果をメモリーに書き出し

と言うことは、先行する命令が4で実行された結果、
先読みしていた1~3が無駄になる。
これを制御ストールという。

または、先行する命令の結果を受けて後続の命令が計算するためには、
先行する命令が5の処理を終えるまで、後続の命令は3の処理を待たないといけない。

これがデータストールという。

このように、パイプライン処理というのは非常に強力な武器ではある物の、
どこか一部で問題が生じるとトタンに遅延が発生するガラス細工のような物だ。

Pentium4等は、このパイプラインを数十段にする事で高速化をしたけど、
逆に、ストールが起きないプログラム作りをしないとパフォーマンスがかえって低下すると言うこととなる。
それが、Pentium4の悪評に繋がったわけだ。

また、このパイプラインとストールの話はなにもCPUに限った話では無く、
スケジュールをパイプライン化すると、
1つの作業の遅延が全体の遅延となるワケだ。

くわばらくわばら。

パイプライン処理とストール

パイプラインというのは要するに流れ作業でCPUの内部で
たとえば、CPUの内部動作が、以下の様な感じだったとする。

1,メモリーから命令の読み出し
2,命令の解釈
3,命令に従って別のメモリーからデータの読み出し
4,読み出した命令の実行
5,実行結果をメモリーに書き出し

これを、バカ正直に実行すると、1つの命令を実行するのに5ステップかかる。

なので、1~5の機能を持った装置を並べて、
・1番目の命令を「1,」の装置に渡す。
・前の結果を「2,」の装置に渡し、「1,」の装置は2番目の命令を読み出す
    :
といった感じに順番で動作させれば、見かけ上1ステップで1つの命令が実行できると言うのが、パイプライン処理。

いや、今日はこれを説明したいんじゃ無かったけど、
まぁいいや、今日はこの辺で、明日はこの話の続きでも。

病院でのOoO

風邪でdone中。
と言うわけで、風邪で病院に行ったのですが、
あいにくと、かかりつけはお休みだったので、行ったことが無いところに言ったわけです。

したらば、こんな張り紙が:

重症な患者さんや、薬の処方のための来院、診察内容などで
呼ばれる順番が前後することがあります。
予めご了承下さい。

うん、まさしくOoO。

OoOとはOut of Orderの略で指定された順番でプログラムを実行しないという、
コンピューターの最適化手法の一つ。
Intel系のCPUだとPentiumProから搭載されている。

病院でたとえると、
・皮膚科と内科の診察が出来る医院長先生
・内科が診察できる、平医者
の2名が居たとする。

そこに、
1,皮膚科患者A
2,皮膚科患者B
3,内科患者C
4,内科患者D
と病院に来たら、皮膚科患者Bを飛ばして、内科患者Cを診察した方が、
皮膚科患者Bさんの診察時間は変わらず、内科患者CさんDさんの診察時間が早まる。

全体として効率が上がるわけだ。

まぁ、とはいえ、結構、そういう細かいことで、文句を言う患者さんはいるんだけどね。(遠い目・・・
#そこまで元気なら、病院来るなとも言いたい。

余談だけど、「Pentium」は、
「PentiumPro」と「Pentium with MMX Technology」の2系統進化をして
前者はOoOを搭載しm後者はMMXを搭載したわけだ。
そして、その次の世代「Pentium II」はこの2つの機能を搭載したという、系譜がある。
いや、ホントにどうでもいい話だけど。

CPUを効率よく使うプログラムの使い方(2000年頃の書き方)

今から10年以上まえのこと。
当時、自分はとあるゲームのプログラムを作っていました。

当時のWindowsゲームのプログラムは、
まぁ、いろいろな方法があったのですが、
画面に対してそれなりに動きのあるプログラムとか、
内部での演算が色々生じるプログラムの場合には、
2パターンほどの書き方に分かれます。

1つは、タイマーイベントを定期的に飛ばして、
タイマーイベント内で演算処理とか描画処理をする方法。
CPUがひ弱なPCではCPU占有率がうなぎ登りですが、
そこそこのスペックのPCなら、CPU占有率は逆に落ちてくれます。
ただ、タイマーイベントは優先順位が低いので、
スムーズな処理が出来ないというのが難点です。
※マルチメディアタイマーを使えば、タイムラグが少なく(と言っても10msec程度のラグはある)、処理が行えるけれど、
 今度は、色々と制限が出てくる。

自分がとったのは別の方法で、
通常、自分のプログラムにOSからイベントが飛んでこなかったら、
イベントが来るまで休ませるプログラムを書きますが、
あえて、別スレッドを立てて、そのスレッドでゲームのプログラムぶん回し、
そのスレッド内で他のプログラムへのイベントなどが発生したことを検知したら、
そちらのプログラムにCPUをお裾分けする方式。

この方式は、当時の音楽再生ソフトとかでも多用されていた方法で、CPUの処理能力が十分あれば、
自分が必要としているタイミングがmsec以下のタイミングで制御できる画期的な方法です。
※CPU能力が少なくても、それなりに動きます。

が!

デバッガーから
「CPU100%になるプログラムは製品としておかしい!」
という、ある意味至極もっともなご意見を頂いたわけです。

いや、それで正しいんだよと、説明しようにも、
そこそこPCに詳しいデバッガーさんが理解できなかった時点で
お客様への理解もされないだろうなと言うことで、
前者の方式になるようにプログラムの組み直しをしました。

で!何が言いたいかというと、
あれやれ!これやれ!と指示を受けて作業する仕事と、
今これに集中しないと!で偶にインタラプトされる仕事と、
仕事にも色々あるなぁということです。

効率は後者の方が良いけれど、自分の処理能力が追いつかないと、
インタラプトされたことに気がつかず怖いなーと

|