エントリー

カテゴリー「備忘録」の検索結果は以下のとおりです。

またまたURLが変わりました

  • 2014/07/02 14:25
  • カテゴリー:備忘録

 またまた,URLが変わりました。

 新しいURLは,

http://gshoes.dyn.dhs.org/

 です。

 ダイナミックDNSをまた乗り換える必要が出たために,こういうことになりました。

 dyndnsからno-ipへ移行したのがこの春なのですが,昨日から艦長日誌が開けなくなっていました。

 IPアドレスを直接打ち込めば表示されるので,どうやらDNSだろうと調べてみると,なんとまあno-ipのトラブルというではありませんか。

 詳しい事情は私もよくわからないのですが,マイクロソフトがno-ipのドメイン管理権限を取得し,不正なトラフィックを制御する措置を執ったという事に関連があるようです。

 もともと,no-ipはマルウェアの拡散に使われることがあったりしたのですが,マイクロソフトによるとこうした声にも耳を貸さず事態を放置しており,裁判所に仮差し止め命令の申し立てが認められた6月30日に,無料ドメインの管理権限を取得,マルウェアのトラフィックを操作するシステムを構築し,稼働させたというのです。

 悪意のあるドメインだけに影響が出ているなら誠にめでたい話なのですが,問題は何も悪いことをしていないユーザーのドメインにまで影響が出ていると言う事実です。そして私のドメインも,これに引っかかったようです。

 なかには,no-ipの有料サービスを申し込んでいた人もこの影響で使えなくなっているケースがあるらしく,こういう場合ってno-ipからお金を返してもらえるのかどうか,ややこしい話になっています。

 マイクロソフトとしては,良かれと思ってやっているのでしょうが,問題はそのやり方です。悪い奴をつかまえるためには,善良な市民の犠牲も厭わないという姿勢です。極論すれば,犯罪者が逃げ込んだ町を町ごと焼き尽くすようなものです。

 ただ,その犯罪者をかくまうことにした町にも問題があるわけで,私はその町の住人に,わざわざ最近なったわけですから,ちょっと浅はかだったかなあというのが本音の所です。

 ということで,あまりドメイン名をコロコロ変えることは好みませんが,マイクロソフトに爆撃されてしまった町にはもう住めません。違う町に引っ越す事にしましょう。

 この例えで言えば,長年済んでいたdyndnsに立ち退きを迫られ,家を失った難民が数多く流れ着いたno-ipが犯罪者の巣になってしまい,マイクロソフトに吹っ飛ばされ,またも流浪の民となった,という感じでしょう。

 しかし,1つ大事な事があります。私は確かに流浪の民となりましたが,dyndnsにしてもno-ipにしても,そこに済むための対価を,支払っていないということです。(とはいえ,no-ipには対価を支払っても住めなくなったでしょうが)

 そんなわけで,新しいURLで引き続きよろしくお願い致します。

URL変更のお知らせ

  • 2014/04/08 09:48
  • カテゴリー:備忘録

 お知らせです。

 長い間無料で使わせてもらっていたDynDnsが,とうとう全面的に有償化されることになりました。

 あと30日で無料で利用出来なくなるというメールが届いています。

 まあ,年間25ドル払ってもよいのですが,他に無料のDDNSがありますので,残念ですがこちらに移行することにしました。

 よって,長年使って来たgshoes.dyndns.orgは,近日中に廃止されて,使えなくなります。

 新しいドメインは,

gshoes.no-ip.biz

 です。ホームページのURLは,

http://gshoes.no-ip.biz

 で,艦長日誌のURLは,

http://gshoes.no-ip.biz/mqv/

 です。

 すでに切り替えが済んでおりますので,以後はこちらでご覧下さい。

TimeMachineがエラー

  • 2013/02/22 12:31
  • カテゴリー:備忘録

 先日,生活マシンであるMacBookAirが,エラーを吐き出しているのを見つけました。いわく,

 信頼性を向上するために、Time Machine は新規バックアップを作成する必要があります。

 とのこと。

 QNAPのNASを導入してから,TimeMachineによるバックアップを積極的に行うようになったのですが,もともとMacBoorAirは内蔵のSSDが64GBと少なくバックアップの負担が軽く,しかもうっかり操作でメールなどを消してしまうことが多い私としては,それなりに便利に使っていたのです。

 TimeMachineのような,履歴を遡って復元できるバックアップというのは,その保存期間が長いほど安心感があります。時間が経てば経つほどそのバックアップに値打ちが出てくるような錯覚に陥るのはそのせいですが,老舗のとんかつ屋の「秘伝のソース」のような気分で,ずらーっと列んだ自分のTimeMachineを見るのは,悪い気分ではありません。

 このエラーメッセージが出た時の選択肢は2つ。バックアップをやめるか,親近いバックアップを作り直すか。突然出てきたエラーメッセージに,過去の資産をすべて捨てろと言われることの,精神的ショックはかなり大きいです。

 こんな貧乏くさいのは私だけかなと思っていたら,国内外の先輩諸氏が同じ気持ち(かどうかは定かではありませんが)でこの問題に取り組み,見事に打破していることがgoogle先生の指南により,はっきりしてきました。

 まあ,こういうのはケースバイケースで,同じ手段で必ず解決出来るわけではない,特に最近のPCやMacは複雑化しているので,ダメモトでやってみました。

 なかなかうまくいかず,あきらめかけたのですが,幸いなことにうまくいきました。UNIXのコマンドに抵抗がないこと,MacOSXにおけるファイルシステムの扱いと共有の概念がきちんと分かっていることが求められますが,尻込みしていても仕方がないので,試行錯誤を繰り返したのです。

 このトラブルは今後も出てくると思います。そこで,ここにメモしておくことにしました。

 先輩諸氏は汎用性のある書き方をしてくれています。それは分かっている人にはありがたいのですが,分かっていない人には具体的な作業が分からず,結果が好ましくない場合になにが間違いだったのか,わかりにくい側面があります。そこで今回は,私のケースをそのまま記述しておくことにします。

(1)まず,TimeMachineのエラーが出たときに,バックアップしないを選択する。

(2)ターミナルを立ち上げて,
sudo su -
と入力する。これで以下の作業はrootで行う事が出来るが,失敗すると大変なことになるので,くれぐれも気をつける。

(3)カスタムアクセス権がかかっている場合に解除の必要があるため,以下のように打ち込む。
chflags -R nouchg /Volumes/TMBackup/MacBook\ Air.sparsebundle

 /Volume~は環境によって違うのだが,私の場合はこう。

 ここで出てくる「sparsebundle」というのは,MacOSX Leopardから採用されたディスクイメージの形式で,約8MB単位でファイルを細かく分割して保存することで,差分の保存を素早く行う為のもの。「スパースバンドル」と読む。

 成功してもなんのメッセージも出ないので気を落とさず次に進む。

(4)いよいよ修復。以下のように打ち込む。

hdiutil attach -nomount -noverify -noautofsck /Volumes/TMBackup/MacBook\ Air.sparsebundle

 すると,以下のように表示が出る。あくまで私の場合。
 
/dev/disk1 GUID_partition_scheme
/dev/disk1s1 EFI
/dev/disk1s2 Apple_HFS

 これを見ると,TimeMachine用のディスクイメージは/dev/disk1s2にマウントされていることがわかる。

 実はこのコマンドを実行すると,すでにfsck_hfsが走っており,修復がバックグラウンドで行われている。topコマンドを実行するとfsck_hfsが走っていることがわかるし,以下のように打ち込むとfsck_hfsのログがリアルタイムで見られる。

tail -f /var/log/fsck_hfs.log

 私の場合,こんな感じに。

QUICKCHECK ONLY; FILESYSTEM DIRTY

/dev/rdisk1s2: fsck_hfs run at Thu Feb 21 21:33:32 2013
/dev/rdisk1s2: ** /dev/rdisk1s2
/dev/rdisk1s2: Executing fsck_hfs (version diskdev_cmds-557~393).
** Checking Journaled HFS Plus volume.
** Detected a case-sensitive volume.
The volume name is Time Machine Backups
** Checking extents overflow file.
** Checking catalog file.
** Checking multi-linked files.
** Checking catalog hierarchy.
** Checking extended attributes file.
Invalid sibling link
・・・以下つづく

(5)ログに以下のように出てくると,修復は成功。

** Checking extents overflow file.
** Checking catalog file.
** Checking multi-linked files.
** Checking catalog hierarchy.
** Checking extended attributes file.
** Checking multi-linked directories.
** Checking volume bitmap.
** Checking volume information.
** The volume Time Machine Backups was repaired successfully.

 ここで,修復できないというメッセージが出てきた場合には,

fsck_hfs -drfy /dev/disk1s2

 と打ち込めば,もう一度fsck_hfsが走る。

(6)ディスクイメージをアンマウントする。以下のように打ち込む。
hdiutil detach /dev/disk1s2

 すると,以下のようにかえってくる。

"disk1" unmounted.
"disk1" ejected.

(7)壊れていることになったままの設定を変更する。以下の操作をする。

cd /Volumes/TMBackup/MacBook\ Air.sparsebundle
vi com.apple.TimeMachine.MachineID.plist

 viを使えるようになっておくと,こういうときなにかと便利。

 そして,以下の2行を削除。

RecoveryBackupDeclinedDate
{whatever-the-date}

 続けて,

VerificationState
2

 の2を0に変更。

 ファイルを保存して終了。

(8)これで復活。TimeMachineを手動で実行すると,おそらく成功するはず。


 という感じで,書けばなんてことない作業なのですが,私の場合何度も失敗していました。まず,TimeMachineのディスクをマウントしておくという先輩諸氏の記述を忠実に守らんとし,デスクトップにアイコンが出るようにするために,TimeMachineに入って中止するという手順をやったのです。

 はっきりしないのですが,これがよくなかったらしく,fsck_hfsがすぐに止まってしまいます。

 それで,こうした手動のマウントしないで,いきなり上記の手順を始めると,/dev/disk1s2 Apple_HFSてのは出てくるのですが,そこから進んでいないように見えます。

 仕方がないので手動でfsck_hfsをやるのですが,最後の最後にエラーが修復できない,と返ってきます。何度やっても修復できず,これはもう私の場合は修復できないエラーだったのかなあと,くじけそうになりました。

 今にして思い返してみると,hdiutilを行った後に,自動でfsck_hfsが動いているにもかかわらず,fsck_hfsを手動で実行してしまったからではないかと思います。

 そして最後に上記の手順に素直に従ってみると,どういうわけだかうまくいったと,
こういうわけです。

 とりあえず結果オーライということで,TimeMachineは順調に動いています。他に問題も出ていないようですから,これでよいということにしますが,TimeMachineは気持ち悪さも含みつつ,しかし一度でも救われた経験があるとやめるわけにはいかなくなる,そんな存在です。

 もう少し信頼性が上がってくれればありがたいのですが,NASとの組み合わせで問題が出てもそれは自己責任ですし,なんとかやっていくしかありませんね。

コンピュータ基礎の基礎~仮想マシン支援機構

  • 2010/08/05 18:14
  • カテゴリー:備忘録

 コンピュータ基礎の基礎,今日が一応の最終回という事で,仮想マシンについてとりあげます。

 コンピュータのハードウェアにはCPU,メモリ,I/Oがあって,その上でソフトウェアは動いています。では,そのソフトウェアでCPUやメモリ,I/Oを記述し,ハードウェア上で仮想的に別のハードウェアを作り出して,その上で別のソフトウェアを動かすと,どんなメリットがあるでしょうか。

 かつて,大型の汎用機は,新機種に置き換わるときに,お客さんが使っているソフトウェアが使えなくなることが大問題でした。今のようにパッケージソフトなどなく,お客さんが自分の都合で作ったソフトばかりなわけですから,新機種がいかに魅力的であっても,苦労して作ったソフトが走ってくれなければ困ります。

 しかし,互換性の問題は,いつの時代も技術的な進歩の妨げになるものです。そこでコンピュータメーカーは,新機種上で旧機種を仮想的に作り出し,過去のソフトウェアはここで動かすことで,ユーザーの不安を取り除くことにしました。

 このように,過去の資産の継承という目的で登場したのが,仮想マシンという技術です。歴史的には随分と昔からある技術ですが,最近特に注目を集めているのは,高性能化するコンピュータを有効に利用するため1台のコンピュータを仮想的に複数台にし,台数を減らしてコストを削減したり,資産継承ではなく異なるOSを走らせて各々得意とするアプリケーションを走らせるなど,もう少し積極的な目的で使われる事が増えたからです。

 仮想マシンには,大きくわけて2つの方法があります。

 1つは,エミュレータに代表される方式で,ホストOS型と呼ばれるものです。その名の通り,実ハードウェア上にまず1つのOSが走っており,このOSの上で仮想マシンを実現するソフトウェアを走らせます。このOSをホストOSを言いますが,仮想マシンもこのホストOSの機能を使って作られます。

 もう1つは仮想マシンモニタ型というものです。ハードウェアとOSの間に,ハードウェアを仮想マシンモニタというソフトウェアを1段挟みます。仮想マシンモニタはハードウェアを仮想化するもので,ここから上位レイヤーに対して,仮想化されたハードウェアを提供します。この上で複数のOSが走るわけですが,すべて別々の仮想マシンで動いているわけです。

 ホストOS方式は実装は楽ですし,仮想マシンがあたかもホストOSのアプリケーションのように見えるのでわかりやすく,またホストOSは仮想化されたハードウェアで動いているわけではないので,仮想マシンによって生まれる制約がありません。

 その代わり,ホストOSの提供するサービスによって実装されている仮想マシンは,競合するリソースや演算パワーを割り振るオーバーヘッドの影響が大きく,速度的にも信頼性の点でも今一歩です。

 これに対して,仮想マシンモニタ型の仮想マシンは,なにせハードウェアが直接見えず,あるのは複数の仮想マシンです。面倒なリソースの配分はこの仮想マシンモニタが行ってくれますし,それぞれの仮想マシンで動くOSはどれも対等な扱いです。それに,仮想マシンモニタがあるおかげでオーバーヘッドも小さく済みます。

 とはいえ,この仮想マシンモニタもソフトウェアなわけで,出来るだけ軽く作るのが望ましいです。そのために,ハードウェアの支援,とりわけCPUに仮想マシンモニタを支援するような機構を入れ込むことが,近年のCPUでは当たり前になっています。

 では,x86で仮想マシンを実現するのに,問題となっていることを見ていきます。

 まず,x86には,実行レベルという概念があります。リング0からリング3までの4段階があり,実行レベルが上がれば上がるほど,アクセス出来るリソースに制約が多くなってきます。OSやBIOSは最低レベルで動いて全てにアクセス出来ないといけませんが,アプリケーションが最上位で動いてくれると,万が一ソフトが暴走してもOSに動作を妨げたり,マシン全体に影響を与えるような動きを防いでくれます。

 この,レベルによってアクセス出来る範囲を変え,信頼性を高める技術をリングプロテクションと呼んでいますが,高度なOSを実装するには必須の機能の1つです。

 x86の場合,OSは全てのリソースにアクセス可能なリング0で実装されてきました。リング1や2はOSの一部が使い,最上位で最も制約の多いリング3はアプリケーションが使う事になっています。もしアプリケーションがOSの動きを妨げるようなレジスタを書き換えようとしたら,例外が発生して保護するようになっているわけですね。

 仮想マシンを実現する仮想マシンモニタを実装するには,OSよりも下位のリングで動かす必要がありますが,仮想マシンモニタをリング0で動かしてしまうと,OSはリング1や2で動かすことになってしまいます。
 
 しかし,OSは全てのリソースにアクセスしようとしますから,リング1や2でリング0でなければアクセス出来ないリソースをアクセスしてしまうと,例外が発生してしまいます。

 仮想マシンモニタは,この例外を受けると,その命令をエミュレートしてOSの代わりにレベル0でアクセスを代行し,結果をOSに渡してあげます。しかし,想像が付くようにこの方法はいちいち例外を監視し,命令のエミュレートを行うために,オーバーヘッドが大きくて速度が上がりません。

 別の問題もあります。

 x86はその名の通り,8086に端を発する歴史あるプロセッサです。互換性を維持してここまで来た驚異のプロセッサですが,これも簡単なことではなく,無理な建て増しを繰り返して,矛盾をギリギリの所で回避して成し遂げた産物です。

 例えばpopfという命令ですが,なんとリングレベルによって異なる動作をする命令だったりします。ということは,仮想マシンモニタの上で動いているOSが,リング0で動いているつもりで実行したpopf命令が,実はリング1や2で別の動作をすることが起きてしまうのです。

 この場合,悪いことに例外も発生してくれませんから,仮想マシンモニタはpopf命令がこないかどうか,常に監視する必要が生じるのです。これはさすがに足を引っ張りそうですね。

 ここ数年で用意されたx86の仮想マシン支援機能では,この問題を効果的に解決しています。まず,リング0からリング3まのリングをもう1つ用意し,それぞれVMXrootとVMXnon-rootと呼ぶようにしました。そして仮想マシンモニタをVMXrootで動作させ,OSをVMXnon-rootで動作させるのです。

 VMXnon-rootで動作するOSが,もし特権命令を実行したら,即座に処理をVMXrootに切り替え,仮想マシンモニタに制御を移します。VMXnon-rootのリング0では,リソースにアクセス出来ない代わりに,VMXrootで走っている仮想マシンモニタが動いてくれるわけですね。

 こうすると,例外によって処理を代行することもなく,またpopfをいちいち監視することもなく,オーバーヘッドを大幅に削減できることがおわかり頂けると思います。

 これに加えて,それぞれの独立した仮想マシンは,各々のコンテキストを保存しておかなければいけないのですが,その保存領域を専用に用意してあり,仮想マシンの切り替え時にはこれらの待避と復帰が自動で行われるようになっていて,これも大幅にオーバーヘッドを削減することに貢献しています。

 さらに,I/Oについても仮想マシンの支援の仕組みが考えられています。I/OとOSを繋ぐのはデバイスドライバですが,I/Oも仮想マシンモニタで管理されると,従来のデバイスドライバは当然使えません。またI/Oのエミュレータが仮想マシンモニタから提供されるようなものですので,非常に遅くなります。

 そこで,DMAのアドレスをハードウェアでリマップする機能を持たせてあります。こうすると,実際のI/Oデバイスのアドレスを直接仮想マシンに提供出来るようになるため,従来のデバイスドライバがそのまま利用出来るようになるばかりか,高速にアクセスが可能になってくれます。

 ただし,仮想マシンモニタが行ってくれていた排他制御はできなくなってしまいますので,ここはハードウェアによる排他制御が可能になるよう,PCIeの仕様が拡張されているので,これを用いることになっているそうです。


 さて,長々とコンピュータの基礎的な事項についてまとめを行って来ました。最終的には仮想マシンの支援機構までやってきましたが,ふと気が付くのは,従来は出来るだけハードウェアの規模を小さくして,その中で最大限の処理能力を出そうと言う目的で新しい技術が開発されてきたところが,最近では使う事の出来るトランジスタの数が膨大になり,処理能力を上げるためにどうやって回路規模を大きくするかを考えると言った,アプローチの違いがあるように感じます。

 例えばキャッシュメモリをたくさん積むことや,4コア,6コアという多数のコアを実装するマルチコアプロセッサなどは,その例だと思います。見方によってはインスタントで安易な高速化の方法が利用出来るようになるほど,トランジスタがふんだんに利用出来るようになったということでしょうか。

 しかし,喜んでばかりもいられません。微細化によってトランジスタの数が増えても,その微細化は消費電力の増大と発熱の問題を助長します。いつの時代も,こうしてバランスを取りながら,知恵と工夫でコンピュータの性能は上がり続けるのだと思うと,私などはワクワクしてしまいます。

 今後,どういう流れになっていくのでしょうか。特にマルチプロセッサの次に来るのは,いったいどういう技術でしょうか。楽しみです。

コンピュータ基礎の基礎~マルチプロセッサとマルチスレッド

  • 2010/08/03 17:00
  • カテゴリー:備忘録

 さて,今日はマルチプロセッサとマルチスレッドについてです。

 CPUは1980年代のRISCから1990年代のスーパースカラ,そして2000年代に入りマルチプロセッサに,その進化の方向が移ってきました。RISCはパイプラインとコンパイラ技術によって高速化をしようという試みでしたが,次にやってきたスーパースカラはソフトはそのまま変えずに,出来るだけハードウェアで並列な命令実行を行うものでした。CPU設計者が無茶な意地を張っていた時代です。

 そしてスーパースカラに限界が見えて,マルチプロセッサの時代になりますが,これはマルチプロセッサを前提にしたソフトウェアを作らなければ全く高速にはならず,その点でハードウェア設計者が再びソフトウェア設計者に頭を下げた,と言っていいかも知れません。

----

問題:
 ある問題について,その実行時間の95%は完全に並列処理が可能で,Nプロセッサを利用することによりN倍性能が向上する。しかし,残りの5%は全く並列処理を行うことが出来ない。この問題を10台のプロセッサを用いて並列処理を行った場合,1台で実行するのに比べて何倍高速に実行することが可能か?

----

 まず最初に,マルチプロセッサとアムダールの法則についてです。

 仕組みや構造はちょっと置いておいて,2つのプロセッサを用いると,処理時間は1/2になりそうなものです。とはいえ,人間でも同じですが,二人が手分けして仕事をしても,なかには手分けできない仕事もあります。こういうものはどちらかが処理するかありません。

 System360の設計者で,後に富士通と一緒にSystem360互換機をビジネスにするジーン・アムダールは,プロセッサの数と同時実行不可能な命令の割合から,最終的な処理速度がどれくらい高速化されるかを公式にしました。これがアムダールの法則です。

 プロセッサの数をNとし,同時に実行出来ない命令の処理時間の割合をFとします。

 まず,Fが0,つまり全ての命令が同時に実行出来るという状態を考えると,プロセッサの数が1の時に比べて,1/Nの時間で処理が終わります。

 逆に,Fが1,つまり全ての命令が同時に実行出来ないという状態を考えると,プロセッサの数であるNに全く関係なく,1つのプロセッサで処理せねばなりませんから,プロセッサの数が1のと同じ処理時間,つまり1倍となります。

 では,Fが0.5,つまり半分は同時に実行出来る場合はどうなるかです。Nに関係なく,絶対にかかってしまう処理時間は0.5です。残りの0.5は1/Nになりますね。もしプロセッサが2つだったら,0.5+0.5*1/2で,0.75です。プロセッサが1つの時に比べて0.75の時間で処理が終わるということになります。

 さて,一般化しましょう。プロセッサが1つ時に比べて,どのくらいの処理時間がかかるのかは,

 F + ((1-F) / N)

 ですね。何倍高速,と言う言い方にするには,これの逆数をとればよいです。

 では,この式を使って早速問題を解いてみましょう。

---
回答:
 全体の処理時間を1とすると,同時に実行出来ない時間は0.05,同時に実行出来る時間は0.95である。プロセッサの数が10であるから,プロセッサが1台の時の処理時間を1とすると,このシステムでは,

 0.05 + 0.95*1/10 = 0.145

 の時間で済むことになる。よって1/0.145=6.90倍高速に実行が可能である。
----

 アムダールの法則によると,プロセッサを10台も使い,しかも命令の並列性を95%まで高めても,7倍弱までしか速度が上がらないのです。なんだか割が合いませんが,プロセッサの数を2つに減らし,しかも命令の並列性が80%まで悪化していると,1.67倍にしかなりません。プロセッサの数を増やすことも大事ですが,実際には命令の並列性を高めることがもっと大切なのです。

 マルチプロセッサには,大きく分けて対象型と非対称型があります。例えば汎用CPUとDSPの組み合わせのように,プログラムを分け,それぞれのプロセッサの役割も決められているようなシステムは非対称型と言われますが,何せいろいろな方法がありますのできちんとした定義は難しいです。

 一方の対象型は,プログラムも役割も同一です。また共有しているメモリへのアクセスについても時間的空間的に平等です。その共有メモリについて,全てのメモリを同じアドレスで複数のプロセッサにアクセスが可能になっているものを集中共有メモリ方式といい,プロセッサごとにローカルメモリを持つものを分散共有メモリ方式と言います。

 言うまでもなく,同じメモリに全てのCPUがアクセス可能というのはプログラムを書くのが楽ですし,わかりやすいですからほとんどがこの方式といってもよいと思いますが,何分メモリが1つ,バスも1つですから,あるCPUがアクセスをしていたら,他のCPUは待たされてしまいます。処理速度がバスのせいで上がらないというわけです。おのずとCPUの数は制限を受けてしまいます。

 一方の分散共有メモリ方式は,命令の局所性をあてにして,バスを使わず自分だけのメモリをガンガンアクセス出来る仕組みですので,プロセッサの数はいくらでも増やすことが出来ます。

 しかし,他のCPUのローカルメモリにアクセスに行くには時間がかかってしまう傾向があります。これではマルチプロセッサでの高速処理が,メモリのアクセスでふっとんでしまいかねません。

 それぞれに一長一短がありますので,システムの規模やコストによって使い分けられています。

 ここでは,対象型の集中共有メモリ方式を例に考えていきます。

 バスとメモリを共有しているのですが,CPUごとにキャッシュメモリを置いてやると,バスやメモリへのアクセスが激減します。しかもキャッシュメモリはソフトウェアにはほとんど影響を与えません。これでマルチプロセッサは万々歳といいたいところなのですが,大きな問題があります。

 キャッシュというのは,メインメモリの一部を高速なメモリに蓄えておくものでした。メインメモリとキャッシュの内容が食い違うことが起こるので,これをどうやって解消するかという問題が,キャッシュでは重要なテーマの1つだったことを思い出して下さい。

 これがマルチプロセッサになると,さらに深刻です。なぜなら,自分の手元にあるキャッシュのアドレスを,他のプロセッサが変更しているかもしれず,その場合自分に変更の覚えがなくても,自分の手元のキャッシュの内容がメインメモリと食い違っていることがあるわけです。

 こうなるともうキャッシュの内容を信用できなくなってしまいます。さすがにまずいので,何らかの対策を取って,それぞれのCPUが持っているキャッシュの内容の一致をしなければなりません。これをキャッシュのコヒーレンシを保証するといいます。

 手段としてはいくつかありますが,ここではMESIプロトコルについて考えてみましょう。

 MESIプロトコルとは,

Modified
Exclusive
Shared
Invalid

 の頭文字を取ったものです。この4つはキャッシュメモリの状態を示すステートで,キャッシュのタグに書き込まれています。これらを持つステートマシンを考えます。4つのステートの状態を以下に示します。

M
 キャッシュメモリとメインメモリは不一致で,他のキャッシュメモリにはキャッシュされていない。

E
 キャッシュメモリとメインメモリは一致しており,他のキャッシュメモリにはキャッシュされていない。

S
キャッシュメモリとメインメモリは一致しており,しかも他のキャッシュメモリにもキャッシュされている。

I
 キャッシュメモリの内容が無効であることを示す。


 基本的には,Sのステートになるように制御がかかります。この制御を行うのが,メインメモリとキャッシュメモリの間に入る,スヌープコントローラです。スヌープとはのぞき見という意味だそうです。

 さて,2つのCPUが同じアドレスのデータをリードした場合を考えます。最初に1つ目のCPUがリードを行うと,1つ目のステートはIからEに遷移します。続いて2つ目のCPUのアクセスが起こると,1つ目のステートはEからSに遷移し,2つ目のステートはIからSになります。2つともSになっていますので,全てのデータが一致していますね。コヒーレンシは保たれています。

 ここでCPU1が書き込みを行ったとします。キャッシュの内容がメインメモリと不一致になりましたので,ステートはMに遷移します。同時に2つ目のステートはSからIになり,キャッシュを無効とします。無効になったのですから,1つ目のキャッシュの内容は2つ目のキャッシュにはキャッシュされていないことになり,Mで矛盾は生じません。

 そしてここでスヌープコントローラの出番です。スヌープコントローラは2つのキャッシュのステートがSになるように動きます。ここでは,1つ目のキャッシュの内容をメインメモリに書き出します。そしてそのデータを2つ目のキャッシュにも書きます。

 このことで2つのキャッシュとメインメモリの3つが全て一致しましたので,1つ目のキャッシュはMからSへ,2つ目のキャッシュのステートはIからSに遷移します。こうして,出来るだけSになるようにして,コヒーレンシを維持するのです。

 対象型のマルチプロセッサにおいては,CPUがいつアクセスを行ってそのデータが有効でなくてはなりません。しかしデータの保存場所がメインメモリだけではなく,それぞれのCPUのそばにも存在しているので,基本的には全てのデータが一致していないと,マルチプロセッサシステムとしては成り立ちません。


 さてさて,ここまででCPUの数は複数に出来ました。しかし前述の通り,複数の命令が同時に実行出来るようにしないと,CPUが同時に動いてはくれません。

 ぱっと思いつくのは,メモリ空間さえも独立しているプロセスを単位として,CPUに割り付けて同時実行することです。しかし,あくまでそのプロセスは1つのCPUで動いていますから,そのプロセスが重いときには,他の手の空いているCPUは手伝ってあげられません。

 かといってOSにはプロセスの中身を見て分割する機能まではありませんから,1つのプロセスを複数のCPUに割り当てることは不可能です。

 そこで,各プロセスの中に「ここは同時に動かしますよ」という印を付けることにします。

 こうして,同じプロセスの内で同時に動くのがスレッドです。同じプロセスですからそれぞれのスレッドは同じメモリ空間で動いています。

 実は,プロセスが情報の共有を行おうとすると,プロセス間通信などを行う事になりますが,これは結構オーバーヘッドも大きく,効率的とはいえません。しかしスレッドはメモリ空間が同じですから,グローバル変数で共有出来るので,とても高速で効率がよいのです。

 そして,わざわざ明示してくれた「同時に動かしますよ」と書かれたスレッドを,複数のCPUに割り当てるのです。どうですか,メモリは共有でグローバル変数で情報のやりとりが出来,同時実行可能とわざわざソフト屋が書いてくれているのです。

 ソフト屋さんとしては,これまで1つのプロセスを書いているつもりで済んでいたのが,どれとどれを同時に実行するかを考えて,スレッドという形で分割しないといけないことになりました。

 プロセスを分割してスレッドにする方法は,大きく分けて2つあります。1つはフォークジョインモデルで,文字通りソフト屋さんが同時実行可能な部分でスレッドと生成し,ソフト屋さんが設定した同期ポイントによってメインのスレッドと同期します。

 POSIXの場合,スレッドの生成はpthread_createで行います。こうして複数のスレッドが生成され,それぞれが同時実行される時に,CPUが複数あればスレッドをCPUに割り当てることで,処理能力を向上させることが出来るわけです。そして各スレッドの結果は,設定された同期ポイントで同期されます。

 しかし,いかにスレッドが軽いとはいえ,スレッドの生成や同期にはそれなりの時間も手間もかかります。スレッドに分割して複数CPUに割り当てて高速化出来ても,これらのオーバーヘッドで食いつぶしてしまうようだと意味がありませんから,スレッドとして同時実行される時間が十分に長い場合ことが条件です。

 もう1つはスレッドプールモデルと呼ばれます。これは複数のスレッドが定期的に実行されることが先に分かっている場合に有効な方法で,これら複数のスレッドをひとまとめにしたスレッドのプールを作成します。

 そして,このプールに情報を入力することで,複数のスレッドが動作して処理されていくのです。スレッドの生成をいちいち行いませんし,同期も頻繁に行いません。それにあらかじめスレッドをひとまとめにしておく関係で,各スレッドの対称性が高い,つまり似たような単位に区切って置けるということで,処理の効率が随分よくなります。


 ということで,例えばWEBブラウザでGoogle Chromeなどは1つのタブを1つのスレッドで処理しています。ですからCPUが増えれば増える程,同時に処理されるタブの数が増えるので,タブをたくさん立ち上げても処理速度が落ちません。また,タブの1つがエラーを出してこけても,スレッドという単位で独立していますから,そのタブが落ちて終わるだけです。(もちろんスレッドで共有されたメモリが壊されてしまえばプロセス,つまりアプリケーションが丸ごと落ちることもあります)

 しかし,CPUが1つしかない時には,スレッドの生成や同期に時間がかかってしまうので,そうした処理を行わない他のブラウザの方が軽くなることになります。そう考えると,マルチコアが当たり前になった昨今のパソコンを使い切るのが,Google Chromeということになりますね。

 そして,CPUの進化がマルチコアと言う方向に進んでいる現在,ソフトを書く上でもどことどこを同時に実行出来るか考え,それをスレッドという単位でまとめることがとても重要な技術になってきます。こうして半導体の進歩とソフトウェアの進歩は歩調を合わせることになり,コンピュータ全体の処理能力が高まっていくことになりました。どちらか一方だけではだめ,そんな時代が来たことを改めて感じます。

ページ移動

  • ページ
  • 1
  • 2
  • 3
  • 4

ユーティリティ

2020年05月

- - - - - 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31 - - - - - -

検索

エントリー検索フォーム
キーワード

ユーザー

新着画像

新着エントリー

過去ログ

Feed