はてなキーワード: レジスタとは
blogを読むときに必要なのは"どうしてだろう?"って考えること。blogを読んで何か納得するのは正しい読み方じゃない。
当該ブログは、部分的に正しいし、部分的に間違っている。特に昔話とコンピュータアーキテクチャの類には多くの異常な主張があるので(意図的かも知れない)、それを探して検証してみるのはとても勉強になると思う。
現場に関する話は、うーん、それほど悲観しないで欲しい。
ただここを読んだ若い人があまりアポロン的になってもいけないので一応警鐘。偉大な先人の多くはゲームを作るために生まれてきた訳じゃないことにもっと関心を持って欲しい。人間を形作るのはゲームづくりだけ?違うよね。
http://blog.livedoor.jp/woopy_doo-game/archives/50938887.html
アドレスレジスタが16bitしか無い様なハードウェアしか存在していませんでしたから(ファミコン、PCエンジン、みんなそうです。メガドラは違いますが)、増加するリソースへの対応が必須でありました。あのアーキテクチャは当時も我々プログラマが提言したのです。
...
呑み会に行ってもハード屋とプログラマは喧嘩ばかりでしたが、バンクアーキテクチャは我々が勝ち取ったものです。事実上無限のメモリ空間を手に入れましたからね。
メモリバンクはゲーム機固有の仕組みじゃない。というわけで、ゲームプログラマが提案したのは多分ゲームシステムにメモリバンク(バンクメモリ? Bank switching?)を導入させたこと、と、読むことにする。
でも、ファミコンを含めた初期のゲーム機、それこそAtari2600でもメモリバンクは実現されていた。これはアーキテクチャがそのように作られていたからではなく、小規模のハードウェア追加でこの仕組みは実現できるからだ。ハードウェアはカートリッジ側に内蔵されていた。ファミコンの音楽に詳しい人ならVRCとかFME、いわゆるマッパーといったチップが内蔵されていたことを知っているだろう。
これらのハードウェアの追加をプログラマが提言したというのは言い過ぎと言える。技術自体は既にあり、採用するのは非常に自然な流れだった。ハードウェアの技術者であっても反対しないだろう。32bitの(アドレスバスを持つ)CPUを導入するのに比べれば、メモリバンクのためのハードウェアはずっと容易に採用できる。
直接的なコピーは彼らにも防げていない。彼らが売っているのはマルチプレイ用のアカウントと考える方がすっきりする。MMORPGと同様に、コピーできないゲーム体験を売るという点では一定の成功を収めている。
何もブラックボックスがないDRMは機能しない。Steamでいえばブラックボックスはゲームサーバであり、PS3とかXbox360で言えばハードウェアそのものがブラックボックスになっている。
草木も眠る丑三つ時、という表現はもはや古いのだろう。最近は人間だって眠らない。
雨がアスファルトをぬらす午前三時、老人はコンビニエンス・ストアにやってきた。夜道に煌々と灯る店内の光はきわめて人工的で浮いていて、蜃気楼みたいに所在ない。彼はいつもそのくらいの時間に訪れる。長い間手入れも洗髪もされていない長い髪の毛と、擦り切れた服、老廃物の酸っぱい臭いが老人の人生を伝えていた。顔には深いしわが宇宙空間から見たヒマラヤ山脈みたいに刻み込まれていたけれど、ともするとその印象より若いのかもしれなかった。
疲れ果てたような表情で背中を丸くしてアルコールコーナーへ向かうと、カップ酒をつかんでレジスター・カウンターへ差し出した。左手からめいっぱいに握られた十円玉がざらっと流れ出る。店員がお釣りの小銭を渡そうとすると、老人は何も言わずに、ふるえる指でレジスターの横にやる気なさげに佇んでいる募金箱をゆびさした。この町で人々から忘れられた十円玉たちは、そうして二〇〇ミリリットルの日本酒と、世界の貧困に対する少しばかりの善意に換算されるのだった。
むせかえるような雨のふる夜だった。傘を持たない老人は一人、静かな町の静かなコンビニエンス・ストアの軒下でカップのふたを開けた。
レジスタの多いCPUの場合で、単純なループが最適化されるとループカウンタはレジスタ上に確保される。
ローカル変数の場合。全てのコンパイラを知ってる訳じゃないから、全部そうなるとは言えないけど。
Javaの場合が気になったので、二つのコードを書いてちょっと調べてみたところ、
for(int i = 0; i < 10; i++){ System.out.println(i); } for(int i = 0; i < 10; i++){ System.out.println(i); }
Code: 0: iconst_0 1: istore_1 2: iload_1 3: bipush 10 5: if_icmpge 21 8: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 11: iload_1 12: invokevirtual #3; //Method java/io/PrintStream.println:(I)V 15: iinc 1, 1 18: goto 2 21: iconst_0 22: istore_1 23: iload_1 24: bipush 10 26: if_icmpge 42 29: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 32: iload_1 33: invokevirtual #3; //Method java/io/PrintStream.println:(I)V 36: iinc 1, 1 39: goto 23 42: return
int i; for(i = 0; i < 10; i++){ System.out.println(i); } for(i = 0; i < 10; i++){ System.out.println(i); }
Code: 0: iconst_0 1: istore_1 2: iload_1 3: bipush 10 5: if_icmpge 21 8: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 11: iload_1 12: invokevirtual #3; //Method java/io/PrintStream.println:(I)V 15: iinc 1, 1 18: goto 2 21: iconst_0 22: istore_1 23: iload_1 24: bipush 10 26: if_icmpge 42 29: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 32: iload_1 33: invokevirtual #3; //Method java/io/PrintStream.println:(I)V 36: iinc 1, 1 39: goto 23 42: return
- アクセス速度: レジスタ>キャッシュ>メモリ>>>HDD>>>オンラインストレージ
確かにコンピュータの世界はいろいろあるし、どういう場面で三角関数を使うのかも人によって違う。
だから自分の常識が他の環境では通用しないというのはよくある話。
「いやいや、それは違うよ。なぜならそれは……」と意気揚々と相手の間違いにツッコミを入れようとするが、
周囲の反論を聞いているうちに自分の考えが間違っていることに気づき、しょぼーんとするのもよくある話。
これを確かめる方法は一つ。
実験してみるしかない。
めんどくさい?時間が無い?
だったら一番実装が簡単な方法で組んだ方がいいよ。
C/C++にいくつか思うこと (ちなみに、プログラマ始めたのはCができた頃でC++よりも私のプログラマ歴の方が長い)
Cはポインタ というか、ポインタを使いこなすことで、チューニングしていく言語だから ポインタ使いたくない=チューニングしたくない
って人は他の高級言語で良いと思う。ただ、動画などの処理をC/C++又はアセンブラ以外で書く人というのは、あまり聞かないので
速度が必要=C/C++って事かと思う。
昔、全くチューニングしていない、CとJavaを比べて同じ速度だからJavaでもOKというレポートを読んだことがあるのだが、あれは酷かった。
Cはチューニングしたときに、もっとも伸びしろが大きく、必要な場合アセンブラと並記できることで、ほぼアセンブラという領域まで
チューニングできるところが魅力。その際、ポインタは無くてはならない。知っておくべき技術。
繰り返しになるけどチューニングしない人には意味がない言語と言われればその通り。
また、ポインタだけではなく、レジスタについても知っておくとCでの伸びシロが大きくなる。
そして、少なくともアセンブラレベルでのPUSH,POP,CALLは覚えておいた方がよい。
関数コールをすると、レジスタ類の待避がアセンブラレベルでは走り、その上、スタックに引数や返値を積んでジャンプするという
ものすごく遠大な処理がアセンブラレベルでは走っているが、Cレベルでは1行の関数コールに見える。
という事を理解しておくと、C++でのインライン関数の重要性や、再帰関数が実行時にはかなり重い理由が頭の中に浮かんでくる。
こういう言い方をすると、最近はCPUが早いから大丈夫とか言う人が多いが、じゃぁWindows Vistaは売れましたか?と聞きたい。
少なくともチューニングが必要な事もある。必要ないこともある。という事で選択すれば良いと思う。
たかだか、数行のスクリプトでチューニング不要ならそりゃ、Perlつかうさ
参考までに書いておくと、個人的感覚ではC++はオブジェクト指向言語ではない。
アセンブラにまで行き着く C言語を大規模開発する時に最低限必要となる抽象化をするための言語
そのために、まともにOOPで設計するとC++では重くなる事が多い。いかに、崩せるかがキモ。
またC++使いか?エセC++使いか?の見分け方は
constを正しく使えるか?参照を正しく使えるか? vtableの説明ができるか?
という質問に正しく答えられるか?で見分けると結構見分けがつくと思っている。
システムの機械語レベルの挙動を意識するとどういうところが気になるようになるか、それを現代の環境ではどう教えるか、という点が問題でしょうね。
・メモリやレジスタ幅(桁数)と情報の規模の関係を意識する - まあ、Oracle は 64bit OS で使えとか、xfs を 32bit OS で使うと(atomic な部分の更新が泣き別れになって)クラッシュの危険が高いとか
・API 仕様を意識する - 上の例の続きだけど、パッチのあたってない古い gzip で 2Gbytes 以上のファイルが圧縮できないとか
・コードを展開した結果、関数の出入りやインタフェースでどう膨れ上がるか、リソースの解放がどれだけ無意味になりうるかを知っている - C++ とかの場合。Tomcat もクラスロード(とリソースの確保も -- 追記)で1時間待たされるとかくだらないことが起こるけど、開発効率と運用のトレードオフだからなぁ
・(Ruby, PHP, Java などの)VMに頼るべきでない場合が何かを知っている - 速度もだけど、VMがバグ持ちの場合、デバッグが困難を極めることもある
・ビット操作系のコードを書けないと困る - まあ、ioctl や fnctl で苦労したことがあればどういうものかは判ると思うけど
・(追記)strace とか ldd とかくらい言われる前にやってほしい - 実際 Java と PHP しか知らないと本当にこの辺はできない
・(追記)497(×10^-n)日で落ちた、と言われた瞬間にカーネルのバグを疑ってほしい - lbolt 溢れ系のバグは本当にありふれている
いまどきは障害対応系の運用をやったほうがプログラマとしてコード書くよりもこの辺の問題に詳しくなれる気がします。
追記:「こういうこともわからん子供たち」をうまく使って利益を上げる会社と、「こういうこともわからん子供たち」を教えるのにフラストレーションを感じるハッカーがひとりで回している会社、どっちが上記のようなことを学びやすいかというのは難しいところです。SUSv3 (昔のオライリーの POSIX 本でもいいけど)を面白いと思えない人に正直あまり細かいことを学べるとは思えないし‥
言いたいことはわかりますよ。スタックを知っていれば、レジスタを知っていれば、メモリ管理の仕組みを知っていれば… そういう知識があればあるほど、問題に遭遇したときの解決が早くなる。
そういった事の体験学習の道具としてマシン語(というかアセンブリ)を薦めたい気持ちもわかりますよ。
でもね。煽りすぎなんです。あなたの文章は、「これは、こういう仕組みになっています。これの意味は、こういう事です」の後に必ず「こんな事も知らない奴は」「絶対に知っておくべきだ」という脅しをかける。だから攻撃的でイヤミになるんですよ。
あなたは、その文を読んだ人が「チクショウ!」と思って勉強することを期待しているんでしょうが、現実は「こんなイヤミな奴の言うこと聞きたくない」の方じゃないですか? そうして若い人たちがマシン語に背を向けてしまったら悲しくないですか。
思い出してください。マシン語がプログラミングの主役だったあの時代、なぜ人々はわざわざマシン語を選んでいたのか。“オールBASIC”のプログラムでは逆立ちしても実現できないことが、マシン語ならできる。家のPC-8001でギャラクシアンが動く。それに感動して、あのスパイの乱数表みたいなリストを打ち込んだんでしょう。どこかのイヤミな野郎にケツを叩かれて始めたわけじゃないでしょう。今はそれがRubyだったりJavascriptだったりするわけです。
マシン語を知らない子供たちも、プログラミングの喜びは知っています。だから、もうやめてください。
匿名相手じゃなくてもキツいことは言えるみたいですね。というか、キツいことを言えるのが嬉しいんですか?
ええと、言いたいことがまとまらないのでばらばら書きます。
ハードディスクやメモリ上の情報構造物が dense であるとか sparse であるとかいいますよね。当然何かその情報構造物について「密度」を考えているわけですが、その単位はよくわからないものです。気体の「体積」「1分子あたりの熱エネルギー」「モル数」はそれぞれ違う次元の数ですが、ディスク上の情報構造物の「占有領域」「最低/平均ブロックサイズ」「圧縮した場合のバイト数を表現するのに必要なレジスタ幅」はまったく意味が違うのに、いずれもバイト数で表されます。これは情報科学の根底にあるトラブルの原因ですが、いまは統計力学と情報理論の間に安易な橋渡しができないことだけを意識してください。
ただ、気体でも極端に自由度の低い系(絶対零度近くとか、強い磁場の下にあるとか)では体積は圧力にも温度にも比例しないでしょう。それと似たような話として、自由度の低い情報構造物は情報理論の適用外です。個々のビットの間の関係は恣意的であって、あまり統計的扱いに向かないからです。
古典力学の前提で、粒子間の引力も斥力も無視するとボルツマン統計、量子力学ならボーズ統計やフェルミ統計に従うという話ができますが、すべてのアプリケーションが書き出すビット列にそういう統計を考えることはできるでしょうか?
アプリケーションの各論を展開できるほど柔軟で包括的な数学を使えば、情報構造物のミクロの理論は好き勝手に展開できるでしょう。ただ、それはアルゴリズムの単なる記述ではありませんか?