link もっと前
   2008年 5月 7日 -
      2008年 4月 28日  
link もっと後

link 未来から過去へ表示(*)
link 過去から未来へ表示

日々

link permalink

やめて!VAIO の HP はもう 0 よ!

いつからか我が家の VAIO type G のファンがぶんぶん回りっぱなしになっています。冬の間は「うるせえなあ…」と思う程度で済んだのですが、改めて本体を触るとかなり熱い。

これから夏を迎えるに当たって温度が心配になってきましたので、原因を探ってみました。

負荷を調べる(2008年 5月18日改訂)

さて負荷をどうやって調べるかが問題です。ファンがブンブンしている状態でタスクマネージャを見ても 0% のままで、負荷がかかっているのかすらわかりません。というわけで 1秒おきに rdtsc 命令を発行し、その差分を表示するプログラムを書き(※)ました。

このプログラムが表示する値を理解するには、まず CPU の動作周波数がどうやって決まるか、rdtsc 命令の返す値は何を表すか、を説明しなければなりません。付け焼き刃の知識で頑張って説明します。

(※)本来なら自分で書かなくても、Crystal CPUID の Real Time Clock 表示機能を使うべきです。しかし Crystal CPUID は無駄に表示が凝っており、表示の負荷でシステムクロック周波数が上がる(rdtsc の変化分が 300MHz くらいまで)本末転倒状態だったので、没にしました。

システムクロックと CPU バスクロック(2008年 5月18日追記)

まず CPU バスクロック(CPU <-> ノースブリッジバス)の説明から入ります。CPU バスクロックはシステムバスクロックの半整数倍です。VAIO 君の場合はシステムクロック = 133MHz、CPU バスクロック = システムクロック(133MHz)x 4倍 = 533MHz のようです。

システムクロックはマザーボード上の水晶振動子(安い 10MHz〜30MHz くらい?)を原発振とした PLL(Phase Locked Loop)で供給されます。PLL って何?と聞かれても詳しくは知らんので勘弁して下さい。

CPU バスは Intel の伝統で FSB(Front Side Bus)と呼ばれ(※)ますが、今回は CPU バスで通します。

ノースブリッジにはメモリコントローラが載っていて SDRAM が繋がっています。比較的高速のバス(AGP バス、PCI-e x16 バス)などをノースブリッジに繋げることが多いようです。
ノースブリッジの先にはサウスブリッジが居て、PCI バス、PCI-e x1, x4 バスなど、比較的低速のデバイスを繋ぐことが多いようです。


CPU <- (1) -> ノースブリッジ <- (2) -> サウスブリッジ
                  |                        | (PCI バス)
              DDR SDRAM                PCI デバイス

(1) FSB(Front Side Bus, Intel 系), HyperTransport(AMD 系)
(2) DMI(Direct Media Interface, Intel 系), HyperTransport(AMD 系)

別にこの 2つでなければならないことはないです。
他の方式で接続するシステムも有るはず。

重要な点として、(1)、(2) のクロックと DDR SDRAM や PCI のクロックは全て同期しています。でないとデータのやりとりができないからだと思うんですが…。
そのため CPU バスと同様に、システムクロックから生成したバスクロックを用います。PCI バスだと 33MHz を欲しがるので、システムクロック 133MHz x 1/4 = 33MHz とします。

  • CPU の動作周波数 = システムクロック x CPU 内部動作周波数倍率
  • CPU バスの動作周波数 = システムクロック x 倍率
  • 周辺バスの動作周波数(例: PCI バス)= システムクロック x 倍率

(※)"Front" Side Bus に対して "Back" Side Bus もあるのか?
BSB もあります、いや…ありました。BSB は CPU <-> 2次キャッシュのバスです。しかし最近は CPU に 2次キャッシュも混載されているので BSB は不要です。ですから「最近のシステムにはありません」という方が正しそう。

rdtsc と CPU の動作周波数(2008年 5月18日追記)

rdtsc 命令とは CPU 内部のタイムスタンプカウンタを読み出す命令です。Core 系以前の CPU では rdtsc のカウントアップ周波数 = CPU 動作周波数でしたので、SpeedStep などで倍率を変化させると rdtsc の増分も変化していました。しかし Core 系では常に一定の周波数(Core Solo 1500U の場合は最大動作周波数 1330MHz)でカウントアップされます。
(hdk 氏、ご指摘&情報提供ありがとうございます)

つまり、
過去の CPU: システムクロック x 動作倍率(可変)
Core 系: システムクロック x 一定値
です。

じゃあ最初に書いた rdtsc を見るプログラムって意味無くね?と思うのはまだ早いんだ、これが。

VAIO 上で先ほどのプログラムを使って rdtsc の増分を見ると、システムの負荷によって変化します。rdtsc の増分はシステムクロック x 一定値、のはずですから、変化しているのはシステムクロック側と予想されます。

システムクロックを上げれば茨の道のオーバークロック(※)ですが、下げる方向に使えば省エネです。VAIO では CPU の省エネ機能(Enhanced SpeedStep)に飽きたらず、システムクロックも下げさらに省エネしようという設計なのでしょう。

(※)規定値よりシステムクロックを上げることをオーバークロックといいます。今までの説明からも類推できるように、システムクロックをメチャクチャ上げると CPU バスクロック、さらには PCI バス(1/4 倍 = 33MHz)や AGP バス(1/2倍 = 66MHz)まで上がり、いずれバスに繋がっているデバイスの許容値を超えて異常動作したり動作しなくなります。
この問題の解決にはシステムクロックと周辺バスクロックの比率を変える必要があります。オーバークロックを売りにしているマザーボードだと比較的柔軟みたいです。

VAIO の現状(2008年 5月18日追記)

システムに負荷をかけると、システムクロックが最大値に張り付いて rdtsc の増分も最大値である 1330MHz に張り付きます。負荷が低いと 50MHz 程度(※)まで落ちます。

さて、今の VAIO を見ると 1330MHz に張り付きっぱなしです。ファンがずっとブンブンしているのはこのせいでしょう。

ファンのスピードはシステム負荷に連動しているようなので、rdtsc 値の増分を下げる方向 = システムクロックを下げる方向へ改善することで「ファンがブンブン言う問題」は解決すると思われます。VAIO がシステム負荷をどうやって測定しているのかまではわかりませんでした。

(※)負荷が低いときは CPU 内部動作周波数倍率は 6.0倍まで落ちますので、rdtsc カウンタの増分 x 6/10 が本来のシステムクロックです。まあ、その辺の細かい値は今回どうでもいいので、高い、中間、低い、くらいが見えれば OK です。

犯人は USB HDD だ

というわけで犯人捜しです。片っ端からケーブルを引っこ抜いてみると、USB HDD を引っこ抜いた段階で 50MHz くらいまで下がりました。犯人はこれかあ。手始めに、デバイスの取り外しで無効化してみたものの全く負荷が下がりません。

USB 2.0 コントローラが有効な状態で一度 USB HDD を認識させてから、USB 2.0 コントローラ(Intel USB2 EHCI)を無効にすることで、USB 1.1 の機器として再認識させると、負荷が下がりました。

これで解決ですね……って、こんなん毎回やってられんよ。面倒くさくて死にそう。

もしかして

ひょっとすると HDD ケース(センチュリーのやつだった気がする)がおかしいのかもしれません。こやつは Windows XP の起動時に電源 ON だと 100% BoD するという、怪しさ爆発デバイスです。

というわけで別の USB HDD を繋いで、再度実験。やはり負荷が上がってダメです。さらに手持ちのデバイスで実験。

  • USB Flush メモリ -> 負荷高
  • USB DVD ドライブ -> 負荷高
  • USB 2.0 ハブ -> 負荷低
  • USB モデム(NEC N902iS、USB 2.0 デバイス) -> 負荷低
  • USB マウス(USB 1.1 デバイス) -> 負荷低

うーむ、どうも USB Mass Strage が NG っぽいですね。Windows の USB EHCI ドライバか、USB Mass Strage ドライバのどちらかが常に負荷をかける作りになっているんでしょうか?これはノート PC の設計者に優しくない作りだなあ…。

まとめ

  • USB Mass Storage(USB HDD、USB 2.0 デバイス) -> 負荷高、速い
  • USB Mass Storage(USB 2.0 デバイス)を「デバイスの取り外し」で無効化 -> 使えないくせに、負荷高
  • USB Mass Storage(USB DVD、USB 2.0 デバイス) -> 負荷高
  • USB Mass Storage(Flush メモリ、USB 2.0 デバイス) -> 負荷高
  • USB Mass Storage(USB 1.1 デバイス) -> 負荷低、ただし遅い
  • USB モデム、シリアルポート(NEC N902iS、USB 2.0 デバイス?) -> 負荷低
  • USB ハブ(ARVEL、USB 2.0 デバイス) -> 負荷低
  • USB マウス(Logicool、USB 1.1 デバイス) -> 負荷低
  • USB ゲームパッド(MS SideWinder、USB 1.1 デバイス) -> 負荷低

まとめといた。

[編集者: すずき]
[更新: 2008年 5月 18日 10:35]
link 編集する

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

再いんすこ

大下邸の PC のセットアップをしました。NTT 西日本の B フレッツ(光プレミアム)では ONU(光ファイバーつなぐやつ)以外に、CTU というルータのような装置を貸与されます。CTU は DHCP サーバとして動くので、大抵はケーブルを差せば動くようになっております。

無線 LAN も使いたかったので、無線 LAN ルータの DHCP サーバ機能を殺して接続しておきました。PPPoE も DHCP も NAT も何もかも OFF にしているため、無線 LAN ルータではなく単なる有線 <-> 無線ブリッジになり下がってますけど。もったいない話だ。

CTU

CTU は NTT 西日本独自の装置らしくて、地域 IP 網(IPv6)とユーザ側のネットワーク(多くは IPv4)を橋渡しする役目を果たしているようです。それ以外もごちゃごちゃやってるようですが、あまり詳しく書いてあるところがないですね…。

大きさも普通のルータ程度ですし、ルータ機能も良くできてると思いますが、設定するために一々 NTT のサーバへアクセス(アドレスは https://ctu.fletsnet.com/, IPv4:210.247.16.1, IPv6:2001:d70:3:1::3:3)しなければならないのがめんどくさい…。

そして

うーむ、風邪引いたかもしれん。

[編集者: すずき]
[更新: 2008年 5月 9日 00:09]
link 編集する

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

淡路島とは関係ありません

大下さんちに遊びに行きました。阪急の淡路駅で初めて降りた気がします。

淡路駅は特急が止まります。ですが駅前には商店街があるだけで特に何があるっつーわけでもないです。駅や周辺地域の規模ではなくて、交通要所(千里線と京都線の乗り換え駅)だから止まるんだな。たぶん。

[編集者: すずき]
[更新: 2008年 5月 8日 21:57]
link 編集する

コメント一覧

  • hdk 
    南千住駅には快速が止まります。ですが駅前には商店街があるだけで特に何があるっつーわけでもないです。駅や周辺地域の規模ではなくて、交通要所ですらなくて、うーんw 
    (2008年05月08日 22:17:48)
  • すずき 
    南千住ね…かなりいらない子だわ。一応東京都内だからお情けで止まるのかもw 
    (2008年05月09日 01:55:37)
open/close この記事にコメントする



link permalink

メモはすぐどっかに消える

ファミコンのアルテリオスというゲームを攻略した情報を一生懸命メモした(特にパスワード)のに、またやろうとしたら紙がない。こういう時って、やる気がなくなって諦めた頃に紙が出てくるもんですよね。

ここに書いてしまえば忘れないだろってことで書いておきます。まあ、ネット上の情報も「どう頑張っても探せなくなった」ら、消えたも同然なんですけどね。人の記憶と似てますねえ。

アルテリオスはうまくできていて、主人公の名前によって扉のパスワードが変わります。なので主人公の名前を「A」にしないと、以下のパスワードと違うパスワードになってしまうはずです(私には確認できませんが、カセットのロットなどその他の要因でも変わるかも)。

メイランド
特に何もない。レベルあげて武器買ったらさっさとリートランドへ進む。
リートランド、コロニー
ディーモスの右の扉のパスワード「1726」
小惑星でコルテス博士に会え、パスワードは「8A71」
(ウルムの言葉を習ってからもう一度)
ウルム: フローダのオルト博士に会え、パスワードは「B1B3」
リートランド、小惑星
(扉の向こう)コルテス博士: 4人の博士に会え、パスワード「7A7A」
(ウルムの言葉を習ってからもう一度)
左奥のウルム: 宮殿のパスワードは「27B1」
ユナイト、ダーフラの街
ディーモスの左の扉のパスワード「3740」
ユナイト、ニーツニーの街
オドラノエルでウルムの言葉を習える
弟: イクニバッドにいる姉さんに会え
ユナイト、イクニバッドの街
姉: ジェノ博士の部屋のパスワード「1B3A」、先に弟に会わないと何も言わない
ユナイト、オドラノエルの街
(扉の向こう)ジェノ博士: 4人の老人に会え、パスワードは「34C8」
老人: ウルムの言葉を教えてくれる。(この後、リートランドのウルムにもう一度会いに行くこと)
ディーモス、ノエロパの街
左には赤い石を置け、右には青い石を置け
リートランドにオルト博士を知っているウルムが居る(※リートランドのコロニーのこと)
ディーモス、エトラパノフの街
クラークス博士はレルチという街(ディーモスではなくてトゥメールカムスにある街)に いる、パスワードは「5A6A」
ディーモス、城内
(左の扉の向こう)レッドクリスタルがある、ヘビーシェルが守っている
(右の扉の向こう)ブルークリスタルがある、ヘビーシェルが守っている
(真ん中の扉)ヘビーシェル x 2 が守っている
レティシア: 宮殿の扉のパスワードは「2112」、ヘビーシェルが守っている
トゥメールカムス、レルチの街
(扉の向こう)クラークス博士: 4人の老人に会え、パスワードは「14FD」
トゥメールカムス、フローダの街
(扉の向こう)宮殿の扉のパスワードは「109E」
オルト博士: 4人の老人に会え、パスワードは「CBDB」
トゥメールカムス、宮殿
(最初の扉)フローダの街で聞いたパスワード
(次の扉)リートランドの小惑星で聞いたパスワード
(左の扉)コルテスのパスワード、クリスタルをくれる
(右の扉)クラークスのパスワード、クリスタルをくれる
(右下の扉)オルトのパスワード、クリスタルをくれる
(左下の扉)ジェノのパスワード、クリスタルをくれる
(次の扉)レティシアのパスワード
トゥメールカムス、宮殿最深部
詳細忘れた。皿みたいなものにもらった 4つのクリスタルを置けば先に進めるんだったかな?
最後のボス(サーベラー)がいるんではり倒す。メチャクチャ硬いです。

まあ、攻略の有無以前に単純に敵が強くてクリアできてないけどな…。ハイパーなんちゃら系がアホみたいに TUEEEEEE ので、必ずボコボコにされる。

以下、おまけ

チートコードを調べてたときのメモです。知ってどうする情報とか、いじるとおかしくなる情報もあります。自己責任で。セーブデータが飛んでも知りません。


0026: 戦闘時の横位置、移動時の横位置も?
0702: 戦闘時の縦位置

0428: HP
0430: WE

6201: 敵の縦位置 0x65 くらいで自分の初期位置
6202: 敵の横位置 0x80 くらいで自分の初期位置

6230: 敵弾の判定? 0にすると敵の弾が来ない

070e: 左の自弾の横位置
0716: 右の自弾の横位置

マップは変化しないが、出現する敵などに影響する。
0420: 現在居る惑星
00 メイランド
01 ユナイト
02 リートランド
03 ディーモス
04 トゥメールカムス
05 ディーモス
06 トゥメールカムス
07 (バグってリセットされる)

自身が居る位置は左上から右向きに 1ずつ増えるようだ。
(画面左端)0 1 2 3(画面右端)
            4 5 6 7
            続く...
例えばメイランドだと、0x40 足すと一個下に進める
0421: 自身が居る位置、上位 8ビット
0422: 自身が居る位置、下位 8ビット

マップを変えられるが、大抵変なところにはまる。
0423: 現在居るマップ
00 メイランド、メイン迷路
01 ユナイト、メイン迷路
02 ユナイト、ダーフラの街
03 ユナイト、ニーツニーの街
04 ユナイト、イクニバッドの街
05 ユナイト、オドラノエルの街
06 リートランド、メイン迷路
07 リートランド、小惑星
08 リートランド、コロニー
09 ディーモス、メイン迷路
0a ディーモス、城内
0b ディーモス、ノエロパの街
0c ディーモス、エトラパノフの街
0d トゥメールカムス、メイン迷路
0e トゥメールカムス、宮殿
0f トゥメールカムス、宮殿最深部
10 トゥメールカムス、レルチの街
11 トゥメールカムス、フローダの街
12 以降はバグる

(下位 4ビットが種類、5ビット目が装備しているか否か、それ以外は無意味)
042c: 武器1
042d: 武器2
042e: 武器3
042f: 武器4

043e: ストップ個数
043f: デビルハンマー個数
0440: デストロイド個数
0446: アイテム装備状態(2: ストップ, 4: デビルハンマー, 8: デストロイド)
0447: 武器攻撃力合計値

実家にはまだアルテリオスのカセットがあるはずですが、肝心のファミコン本体が死んじゃったからなあ。もうエミュレータでしか画面が拝めないのかあ…。

[編集者: すずき]
[更新: 2008年 5月 4日 17:26]
link 編集する

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

何を補うの?

毎回話題がバラバラな日記ですみません。今日は補数の話です。

N 進数の補数は 2つあります。N の補数と、N-1 の補数です。10進数ならば 10 の補数と 10-1 の補数(9の補数ともいう)があります。

N 進数における二つの補数

ある N 進数 x の N の補数 y とは、足すと桁上がりする最小の数値を指します。
10進数でいきますと、x = 123 だとしたら、10 の補数は足すと桁上がり(1,000 になる)する最小の数値ですから 877 です。

要するに y = 1,000 - x = 1,000 - 123 = 877 と計算します。4桁の数字なら 10,000 から引けばいいですし、5桁なら 100,000 から、n 桁なら 10^(n) から引いてください。

ある N 進数 x の N-1 の補数 z とは、足しても桁上がりしない最大の数値を指します。
また 10進数を例に取ると、x = 123 として、10-1 の補数は足しても桁上がり(1,000)に達しない最大の数ですから、876 です。足すと 999 になります。

これも要するに z = (1,000 - 1) - x = 999 - x = 876 と計算します。特徴として、10 の補数から 1 引いても得られますし、逆に 10-1 の補数に 1 を加えると 10 の補数になります(この性質は後ほど重要です)。

補数の活用方法

N の補数は何が嬉しいかというと「負の数の表現として使えば、引き算が不要になる」という点です。

3桁の 10進数 500 - 300 を計算したいとします。「引き算は知らないが 3桁の足し算と 10 の補数を書いた表だけ持ってる」と仮定します。むちゃくちゃに見えますけど、後で意味が分かると思います。

引き算は知りませんので、まずは負の数を消しにかかります。負の数は絶対値の補数に置き換えて消します。表を見ると 300 の 10 の補数は 700(計算で出すなら 1,000 - 300)ですから、
500 - 300 = 500 + 700
こう置き換えます。すると足し算のみになって、計算できるようになります。
500 + 700 = 1,200
4桁目が出てきてしまいましたが、3桁の足し算しか知らんので 4桁目は捨てます。さようなら〜。
1,200 => 200
この結果は 500 - 300 = 200 の結果と一致します。

不思議に見えますが、そもそも補数 y の定義が y = 1,000 - x なので、x = 300 で式を展開すると、
500 + (1,000 - 300) = 1,200 --(4桁目無視)--> 200
となるのは当たり前といわれれば当たり前の結果です。しつこいですが大事なポイントは「引き算が足し算に化ける」という点です。

2進数だと非常に嬉しい

とはいえ、10進数だと補数を計算するために結局引き算が必要で、ありがたみがありません。これはその他の記数法(図では 3進数を例とした)でも同じです。


3進数と 3 の補数、3-1 の補数

ところが 2進数となると非常に嬉しい性質があります。以下の図を見てください。


2進数と 2 の補数、2-1 の補数

2進数においては全桁を反転させる演算(Not 演算)によって、容易に 2-1 の補数を得ることができ、そこに 1 加えれば 2 の補数を得ることができます。つまり Not 演算さえあれば 2 の補数の導出に引き算は不要です。コンピュータだからこそできる技といえましょう。

この性質のためコンピュータに減算器は不要で(※)、加算器の前に Not 演算と 1 加える回路をつけるだけで良いのです。回路が少なくなればコンピュータも安くなります。いやあ、補数って素晴らしいですね。

(※)コンピュータは前章の説明に出てきた「引き算は知らないが 3桁の足し算と 10 の補数を書いた表だけ持ってる」の代表格です。コンピュータの場合 2進数を扱うため 10の補数ではなく 2の補数です。
まとめると「一定桁(32桁、64桁など)の足し算と、2の補数しか知らない」変な奴と言えます。本当は意図的にそう作っていると言った方が正しいですけど…。

負の数を解釈

補数を負の数として扱うと良いこと(減算がなくなる)があるのは分かっていただけたかとおもいます。残る問題はどこからを負の数と見なすかです。卑近な例で言うと printf したときに、どこからマイナスなのよ?って話です。

前章まで話してきた計算の問題と関係ありそうに見えますが、実は全然関係ありません。ぶっちゃけた話、どこから負の数と見なしても構いません。以下の図をご覧下さい。


2進数から 10進数へ解釈する一方法

この図にある解釈方法ですと 2進数の 101 以上を負の数と見なします。

  • 101 未満の数を表示しなさいと言われたら、そのまま 10進数に変換した値を印字します。
  • 101 以上の数を表示しなさいと言われたら、補数をとって 10進数に変換した値と、マイナスの符号をともに印字します。
例えば 110 を渡されたら、101 以上なので補数を取って 010 とし、010 を 10進数にすると 3 なので、-3 と表示します。

何?ずれてる?いやいや…。このような解釈でも使っている人がウンと言えばそれで良いんです。とはいったものの、この方式ではウンと言う人は少なそうです。この方式は欠点が多すぎます。

桁が増えたときに正負の境界をどう決めるかがあいまいであるがために、境界を見分ける処理が複雑になる可能性があります。プログラマや回路設計者に嫌われますね。それとやたら正の数ばかりが多くて、負の数を使いたい人にも嫌われます。

良い解釈方法はあるか

多くの方が見慣れたパターンは、最上位のビットが 1 なら負の数と見なす、以下のような解釈方法でしょう。


2進数から 10進数へ解釈する効率的な方法

この解釈方法が採用されている理由は、効率的だからだと思われます。この解釈方法であれば、何桁になろうとも「最上位ビットの有無」という同じルールが適用できます。さらに正の数の範囲と負の数の範囲がほぼ同じ(負の数の範囲が 1 広いけど)で使いやすいのです。

[編集者: すずき]
[更新: 2008年 5月 4日 16:51]
link 編集する

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

ページテーブルはどこに行った

Linux のページディレクトリを見ていると 0xc000 0000 以降(※)はページディレクトリエントリがあるのに、その先のページテーブルがありません。なぜこれで動くんでしょう?

調べてみると、なるほど、トリックがありました。

Linux は CR4 の PSE ビット(Page Size Extension、ビット 4)を 1 にして、4MB/4KB どちらのサイズでも使えるようにしています。

確かめ方は、右 Alt + ScrLock を押してレジスタダンプすると簡単でしょうか?以下のようなメッセージが出るはずです。Pentium Pro から導入されているはずですので、未対応というのはそうそうないかと…。

レジスタダンプの例
Pid: 0, comm:              swapper
EIP: 0060:[<c01019bd>] CPU: 0
EIP is at default_idle+0x31/0x59
 EFLAGS: 00010246    Not tainted  (2.6.18-6-486 #1)
EAX: 00000000 EBX: 00000800 ECX: c1101040 EDX: c030e000
ESI: 00099100 EDI: c0302800 EBP: 003a7007 DS: 007b ES: 007b
CR0: 8005003b CR2: c02bd7f4 CR3: 07175000 CR4: 00000690
 [<c0101a1c>] cpu_idle+0x37/0x4c
 [<c03105fa>] start_kernel+0x270/0x272

肝心なのは CR4 レジスタの値です。CR4 レジスタが 0x0000 0690、2進数だと 0110 1001 0000 ですから、ビット 4(ビット 0 から数えるので、右から 5番目)の PSE ビットが 1 になっていることが分かります。

(※)カーネルが使うリニアアドレス用のマッピングで、物理メモリ先頭 896MB 分を仮想アドレス 0xc000 0000 へマップしています。
物理: 0x0000 0000 .... 0x37ff ffff
リニア: 0xc000 0000 .... 0xf7ff ffff
というマッピングです。

二種類のページ

じゃあ 4MB と 4KB の区別はどこでやってるのさ?というと、ページディレクトリテーブルの要素である、ページディレクトリエントリでやっています。インテルのマニュアルによれば、ページディレクトリエントリの構成は以下のようになっています。


32ビット x86 のページディレクトリエントリ

細かい説明は後述しますが、PS ビット(Page Size、ビット 7)が 1 になっていれば 4MB のページを指し、0 ならば 4KB のページを使うことを意味します。

128MB の実メモリを割り当てた仮想マシン上で Linux を起動して、適当なプロセスのページテーブルをダンプしてみると、768 要素目から以下のようなページディレクトリエントリが見受けられます。

128MB しか実メモリがないので、768〜799 番目(4MB x 32ページ)までしか値が埋まりません。余った 800 番目以降は別の用途に使われます。

カーネルのページディレクトリテーブルの一部
  768: 0x000001e3, 0x004001e3, 0x008001e3, 0x00c001e3, 
  772: 0x010001e3, 0x014001e3, 0x018001e3, 0x01c001e3, 
  776: 0x020001e3, 0x024001e3, 0x028001e3, 0x02c001e3, 
  780: 0x030001e3, 0x034001e3, 0x038001e3, 0x03c001e3, 
  784: 0x040001e3, 0x044001e3, 0x048001e3, 0x04c001e3, 
  788: 0x050001e3, 0x054001e3, 0x058001e3, 0x05c001e3, 
  792: 0x060001e3, 0x064001e3, 0x068001e3, 0x06c001e3, 
  796: 0x070001e3, 0x074001e3, 0x078001e3, 0x07c001e3, 
  800: 0x00000000, 0x00000000, 0x07baf067, 0x00000000, 

772 番目を例に取ると、0xc100 0000〜0xc13f ffff の 4MB 分のアドレスをマップしています。0x010001e3 は 2進数だと 0001 0000 0000 0000 0001 1110 0011 ですので、先ほどの図に当てはめてみると、

ビット 0: P(存在): 1
4KB ページの時はページテーブルがロードされていることを表します。4MB ページの場合はページが存在していることを表します。
ビット 1: R/W(読み取り/書き込み): 1
0 は読み取り専用、1 なら書き込み可能であることを表します。
CR0 の WP ビット(書き込み保護、ビット 16)を 1 にすると、スーパバイザからユーザの書き込み禁止ページに書き込んだときに、ページフォルト例外が発生するようになります。コピーオンライト機能の実現に役立ちます。
  • ページテーブルエントリ EA が指すページ A をコピーせよという命令に対し、実際はコピーせず、エントリ EA を読み取り専用にし、さらに同じページを指すエントリ EB を読み取り専用で作ります。
  • 読み取り時
    • エントリ EA の指すページ A への読み取りは今まで通りです。
    • エントリ EB は書き込みがない限りページ A と同じ内容なので、読み取りだけならばエントリの指すページを変更する必要はありません。
  • 書き込み時
    • エントリ EA の指すページ A に書き込もうとすると、ページフォルト例外を発生させてページをコピーし、ページ A' を作ります(書き込み時のコピー、コピーオンライト、COW とも)。
      以降はエントリ EA は書き込み可能、指す先はページ A' です(EA -> A', EB -> A)。
      そうしないとエントリ EB が指すページ A を使っている人が混乱します。エントリ EB を使っている人から見ると、何もしていないのに(エントリ EA の指すページ A への書き込み発生時に)勝手にページの内容が変わったように見えます。
    • 同様にエントリ EB の指すページ A に書き込もうとしても、ページフォルト例外が発生します。そのとき初めてページ A の複製、ページ B を作ります(コピーオンライト)。
      以降、エントリ EB は書き込み可能、指す先はページ B に変更されます。(EA -> A, EB -> B)
      ただし既にエントリ EA がページ A を指していないことが分かっているなら、コピー作業は無駄なのでしません。エントリ EB はページ A を指したままで、書き込み可能に変更されるだけです(EA -> A', EB -> A)。
ビット 2: U/S(ユーザ/スーパバイザ): 0
0 はスーパバイザ用の領域を意味し、1 はユーザ/スーパバイザ用の領域を意味します。
ビット 3: PWT(ページライトスルー): 0
0 ならページへの書き込み時に、可能ならキャッシュのみを更新(ライトバック方式)します。1 にするとキャッシュとメモリを同時に更新(ライトスルー方式)します。PCD が 1 のときは、そもそもキャッシュを使わないので無意味です。
  • CR0 の NW ビット(非ライトバック、ビット 29)が 1 だと、ライトスルー方式が採用されます。こちらが優先です。
  • CR3 の PWT ビット(ページライトスルー、ビット 3)が 1 だと、ライトスルー方式が採用されます。これはページディレクトリエントリだけのキャッシュ方式に適用されます。
しかし MTRR の設定とも関係します。ライトバックとライトスルーの設定がかち合ったときは、ライトスルーが優先されます。
ビット 4: PCD(ページキャッシュ無効): 0
0 にするとページをキャッシュします。1 にするとページをキャッシュしなくなります。I/O メモリなど、キャッシュしても意味がない領域などに使うそうです。
  • CR0 の CD ビット(キャッシュ無効、ビット 30)が 1 だと、メモリに対するキャッシュ全てが無効になります。こちらが優先です。
  • CR3 の PCD ビット(ページキャッシュ無効、ビット 4)が 1 だと、ページ単位のキャッシュは無効になります。これはページディレクトリエントリだけのキャッシュ方式に適用されます。
キャッシュの設定は MTRR の設定とも関係します。ライトバックとライトスルーがかち合ったときは、ライトスルーが優先されます。
ビット 5: A(アクセス): 1
ページ番号が指しているページに読み込み、書き込みがあると 1 にセットされます。
ビット 6: D(ダーティ): 1
ページ番号が指しているページに書き込みがあると 1 にセットされます。
ビット 7: PS(ページサイズ): 1
0 なら 4KB ページ、1 なら 4MB ページを表します。ページディレクトリエントリ(一段目のテーブル)だけで有効です。
Linux ではページテーブル(二段目のテーブル)でアクセス権のないページを表すために、P ビットと合わせて使っています(当然 CPU は無視します)。P:PS = 0:0 なら存在しないページ、P:PS = 0:1 ならアクセス権のないページを表します。
(4KB ページ、ページテーブルエントリ(二段目のテーブル)のみ)Pentium Pro 以降であれば、このビットは PAT ビットを表します。このビットが 1 であれば PCD および PWT の 2ビットで 4 つのメモリ属性(ライトバック、ライトスルー、MTRR 優先のキャッシュ無効、MTRR 上書きのキャッシュ無効)を表します。このビットが 0 であれば、従来と同じです。
ビット 8: G(グローバル): 1
0 なら TLB フラッシュの時に消されます、1 なら消されずにずっと残ります。
CR4 の PGE ビット(グローバルページ有効、ビット 7)を 1 にしないと意味がありません。
ビット 12: PAT(ページ属性テーブル): 0
(4MB ページのみ)0 なら PAT 機能を無効にして、1 なら PAT 機能を有効にします。
ビット 31-22: ページ番号: 4(0x4)
先頭から 16MB(4MB x 4個目)の位置にある 4MB 分の領域(0x0100 0000〜0x013f ffff)をマップすることを表します。

なぜ使い分けるのか

4MB のページングを使っているのはカーネル用のリニアアドレス(0xc000 0000〜)だけのようです。他のページディレクトリエントリには PS ビットが設定されていません。ページ番号の指す先には、もう一段ページテーブルがあり、その先にやっと 4KB のページがあります。

理由ですが、インテルのマニュアルによると 4MB と 4KB のページは別の TLB に置かれるので、カーネルのように頻繁に使うコードやデータは 4MB ページに置いておくと、フラッシュされなくて良いよ、ってなことが書いてあります。また、ページサイズが大きければ TLB ミスも少ないよ、ってな解説もあります。恐らくそんな理由です。


あるプロセスのページディレクトリテーブル

絵にしてみるとこんな感じでしょうか。間違ってるかも…。

サイズはアドレスの範囲を意味するのではなくてテーブル自体の大きさのことです。ページディレクトリテーブル(一段目のテーブル)も、ページテーブル(二段目のテーブル)も 4バイト x 1024 要素なので同じ 4KB ですよ、って言いたかっただけです。

[編集者: すずき]
[更新: 2008年 5月 3日 19:20]
link 編集する

コメント一覧

  • hdk 
    あれ? PAT は? (・∀・)

    A ビットは書き込みがあっても 1 になりますね。A, D ビットは実際は TLB とも深く関わってます。R/W と CR0 の WR フラグも関係があります。 
    (2008年05月03日 14:11:03)
  • すずき 
    PAT に MTRR ですか…正直、勘弁してくださいという領域ですorz
    良くわからんくせに、書き足しました。内容には全く自信ないです。 
    (2008年05月03日 16:23:33)
  • hdk 
    MTRR ってわけわからんですよねー。
    たしか CR3 のキャッシュの設定って CPU がページディレクトリエントリを読み書きする時にキャッシュの設定をどうするかじゃなかったですか?  
    (2008年05月03日 18:07:45)
  • すずき 
    >MTRR
    マニュアル読んだけど理解させる気ないね。難しすぎ。
    >CR3
    うお、早速間違ってた。直します。 
    (2008年05月03日 19:19:30)
  • すずき 
    それにしても読みづらい日記だな…。
    hdk氏には感謝感謝。 
    (2008年05月03日 19:22:14)
  • すずき 
    かなりいまさらになりますが…日記でやってるページテーブルダンプのやり方(bash, zsh 専用)
    # i=0x6e94000; dd if=/dev/mem skip=$((i / 4096)) bs=4096 count=1 | hexdump -v -e '" " 4/4 "0x%08x, " "\n"' | nl -v 0 -i 4 -s :
    です。

    i に代入する値は、
    ・適当にレジスタダンプ
    ・dmesg で結果見る
    ・CR3 レジスタ(= ページディレクトリエントリの値です)
    を確認してそれを 16進でそのまま入れてください。 
    (2010年05月07日 10:30:51)
  • すずき 
    用語がふにゃふにゃしててすみません。訂正します。
    ページ「テーブル」のダンプじゃなくて、ページ「ディレクトリテーブル」のダンプです。
    日記に書いたとおり 4MB ページの場合は、ページテーブルはありません。 
    (2010年05月07日 10:35:35)
open/close この記事にコメントする



link permalink

メーデー!メーデー!

今日はメーデーです。そんなことより、エクスプローラのネットワークドライブへの無駄なリトライがすごくイライラする。

あるマシン A で Windows のネットワークドライブを設定(宛先を B とする)して、接続先であるマシン B を落とすと、当然そのネットワークドライブは使えなくなります。

そこまでは良いのですが、エクスプローラってば使えなくなったネットワークドライブにアクセスしようとすると 10秒近くフリーズしてしまいます。TCP SYN+ACK 待ちにしては諦めが早すぎるので、NetBIOS でしょうか?

さらに嫌なことに、ネットワークドライブと全く関係ない操作(例:フォーカスを戻す)でも、毎回ネットワークドライブを確認してはフリーズします。もうイライラして仕方ないです。

マシン A を起動した時点でマシン B が死んでいると、ネットワークドライブは切断されている扱いになって、上記の現象は起きません。その後マシン B を起動してもネットワークドライブは切断された扱いのままです。

切断されている状態だとネットワークドライブ上のファイルへのアクセスが軒並み失敗しますので、すぐにわかるかと思います。

しかしエクスプローラからネットワークドライブを見てしまうと再接続処理が走るようで、以降は接続された扱いになります。こうなるともうダメで、マシン B を落とすと上記のフリーズしまくり状態に突入します。

Samba だとダメ

ネットワークドライブの接続先が Samba の場合はフリーズ現象が発生します。接続先のマシンを落とすと、ネットワークドライブのプロパティには「ネットワークドライブ:NTFS(または未フォーマットとも)」などと表示されます。

一方で Windows XP の共有ドライブの場合はフリーズ現象が起こりません。接続先のマシンを落とすと、ネットワークドライブのプロパティには「切断されたネットワークドライブ」と表示されます。

どうも Samba はサーバ終了時に、接続中のクライアントに何かを通知すべきなのに、全部すっ飛ばして終了するみたいです。オプションでなんとかならんかなあ…。

原因不明

しかし、いつまでも未練がましく覚えているクライアント側も大概にしてほしいものです。なんとかしてネットワークドライブの記憶を消せないか探ってみました。

まず、以下のコマンドで ARP のキャッシュをクリアしました。
arp -d *
しかし症状は変わらず。

次に NetBIOS のホスト名 <-> IP アドレスのキャッシュをクリアしました。
nbtstat -R
やはり直りません。

エクスプローラが何か覚えているのかもと explorer.exe を強制終了させ再起動しましたが、依然として直りません。

残るは System プロセス(pid: 4)が覚えている可能性がありますが、確かめる方法がわからんなあ。

[編集者: すずき]
[更新: 2008年 5月 2日 04:17]
link 編集する

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

黄金ウィーク

うちの会社は 5/1 と 5/2 が休みなので、今年のゴールデンウィークは 6連休(5/1〜5/6)です。さらに 4/29 の祝日(昭和の日)を有給休暇(4/30)で繋いで 8連休にする人が多いのではないでしょうか。

中には 4/28 も有給休暇にして 11連休(4/26〜5/6)でイ゛ェアアアア!!という猛者も居ます。

一方、自分は特に予定もなく今日も出社しておりました。普段と違うのは、チームの人が何人か居ないのと、良く知らない仕事(隣のチームの仕事の手伝い)が回ってきたくらいか…。

ちなみに隣のチームは修羅場ってて、ゴールデンウィークなんかねえよwwみたいな話をしている方がいました。恐ろしい子…!

[編集者: すずき]
[更新: 2008年 5月 2日 03:01]
link 編集する

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

一週間以上

ついに一週間更新せずに放置してしまいました。あわてて書き足すも、先週の頭あたりなんてもう覚えてないぜ。

私は正義、貴様を見ているぞ!

先日、JR 長岡京駅で発見して以来、気になっていて仕方ないポスターがあります。鉄道警察隊によるちかん防止のポスターです。


せいぎくん

どうみても下手な絵、バラバラで虚ろな瞳、真っ赤な枠、首だけで浮かび「私は見ている 許さない」と決め台詞。「せいぎくん」はちかん被害にあった女性の代弁者なのでしょうか…呪ってやるという雰囲気すら感じます。見れば見るほどに怖いです。

ちなみに発行元が京都府警なので、京都府内の他駅(長岡京駅、以外)でも見かけるかもしれませんね。何、別に見たくない?あ、そう…。

[編集者: すずき]
[更新: 2008年 4月 29日 18:40]
link 編集する

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link もっと前
   2008年 5月 7日 -
      2008年 4月 28日  
link もっと後

管理用メニュー

link 記事を新規作成

合計:  counter total
本日:  counter today

link About www.katsuster.net
RDF ファイル RSS 1.0
QR コード QR コード

最終更新: 11/17 22:47

カレンダー

<2008>
<<<05>>>
----123
45678910
11121314151617
18192021222324
25262728293031

最近のコメント 5件

  • link 18年11月15日
    すずき 「なるほど、Windows 10 と古い ...」
    (更新:11/17 22:47)
  • link 18年11月15日
    hdk 「あっ、拒否されるというのは昔のWindo...」
    (更新:11/17 21:07)
  • link 18年11月15日
    すずき 「hdk さん\n\n色は自動で付けている...」
    (更新:11/17 13:15)
  • link 18年11月11日
    すずき 「T4 さん\n\nクロック周りなんですね...」
    (更新:11/17 13:06)
  • link 18年11月11日
    T4 「● I2S1が 全く動かない\nなぜか ...」
    (更新:11/17 09:44)

最近の記事 3件

link もっとみる
  • link 18年11月14日
    すずき 「[初めての OpenVX] OpenCV+OpenVX のデモンス...」
    (更新:11/17 13:51)
  • link 18年11月15日
    すずき 「[Windows 10 と Samba] Windows からアク...」
    (更新:11/17 01:29)
  • link 18年11月11日
    すずき 「[linux-next で動かない ROCK64 の I2S] 昨...」
    (更新:11/17 00:27)

こんてんつ

open/close wiki
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報