advance/CPU
の編集
http://hrb.osask.jp/wiki/?advance/CPU
[
リロード
|
差分
|
単語検索
|
一覧
] [
編集
|
バックアップ
|
添付
]
-- 雛形とするページ --
A
Akkie
Athlon64X2
Clover
DAsoran
Falcon
FormatRule
FrontPage
Genesis
Help
I
InterWikiName
InterWikiSandBox
InterWikiテクニカル
Jormungand
K
Kebo
Kor_Lee_Hee_Rak
Leaf
Linux
Linux/wako_memo
MOIZ99
MW
MenuBar
OSC
PG_MANA
ReadersOS
RecentDeleted
SKYDASH
SandBox
Sero
Sigle
Source
Triangle_Ld.
Zxcvbnm
advance
advance/CPU
advance/FDC
advance/FPU
advance/NotHariMain
advance/QEMUVGA
advance/RTC
advance/blike
advance/cpu_reset
advance/driver
advance/driver/01
advance/driver/02
advance/families
advance/filesystem
advance/fwrite
advance/hddboot
advance/he86
advance/hints
advance/ipl
advance/kernel
advance/keycode
advance/osselect
advance/smaller1
advance/startup
advnace/smaller2
anzy
aotatsu
banbi-
bluedwarf
bo
bugs
challengers
cybozulabsyouth11
deskmanta
esb02b
faq
faq/advance
faq/asm
faq/c00-03
faq/c04-07
faq/c08-15
faq/c16-23
faq/c24-31
faq/make
faq/others
faq/qemu
guide
guide03
guide05
guide07
hikarupsp
imp_log/0000
imp_log/0001
imp_log/0002
imp_log/0003
impressions
index
k
killer_elf
kota
lea
lea/10_memory
lea/4_color
lea/idea
lea/terms
links
logs
logs/osa_hrb/comments0000
logs/osa_hrb/rumors0000
masa
members
message
mistakes
moge32
moppoi5168
notice
osdevjp
populars
prog_index
projects
q_and_a
q_and_a_2
qa_log/0000
qa_log/0001
qa_log/0002
qa_log/0003
qa_log/0004
qa_log/0005
qa_log/0006
qa_log/0007
qa_log/0008
qa_log/0009
quark
rankings
rule
sakamoto
sasaki
spc09
spcc_30min_os
tatsu
tools
tools/bim2hrb
tools/bin2obj
tools/cc1
tools/edimg
tools/gas2nask
tools/makefont
tools/nask
tools/obj2bim
tools/sjisconv
uchan
uho
updates
violations
wako
white
win64-bit
x
ytakano
ヘルプ
リックス
質問します
整形ルール
本は買ったぞ!持ってるぞ!
練習用ページ
* CPUの動作に関するより詳しい解説ページ -(by [[K]], 2006.09.02) -発展課題のページ(全部読む前にここを読むのは混乱するのでおすすめじゃないです) *** CPUによる自動スタック切り替え機能の詳細ついて -(by [[K]], 2006.09.02) -おもに 21-7 の内容の補足 --ついでにINT命令、IRETD命令の詳細の理解 -この内容は理解を深め知的好奇心を満足させてくれますが、話が長くなる上にややこしくしたくはなかったので、本文中では割愛しました。それをここに書きます。 ---- -スタックの切り替えは、INT命令実行時(割り込み時も含む)とIRETD命令の実行時におきます。 -INT命令の実行時にCPUは以下の処理をします。 if (現在がアプリモードで、割り込み処理ルーチンがOSモードの場合) { スタックを切り替えるために、ESPとSSの値をTSSのss0とesp0から読み込む。 IRETD命令実行時にもとのSSとESPに戻せるように、 PUSH(旧SS); PUSH(旧ESP); を実行する。 (これらの値は切り替わった先のOS用スタックに積まれることになる。) } PUSH(EFLAGS); PUSH(CS); PUSH(EIP); CLI(); を実行する。 EIPとCSの値をIDTから読み込む。 if (エラーコードのある例外の場合) { PUSH(エラーコード); を実行する。 } -IRETD命令の実行時にCPUは以下の処理をします。 POP(EIP); POP(CS); POP(EFLAGS); を実行する。 if (それまでがOSモードでしかもPOPしたCSがアプリモードの場合) { スタックを切り替えるために、 POP(ESP); POP(SS); を実行する。 ( POP(ESP); した時点でESPが変わってしまうと次の POP(SS); がうまくいかなくなるので、 回路を工夫して、POPした値がESPに代入されるタイミングを遅らせてある。) } *** 整数除算命令の重さについて -(by [[K]], 2008.08.23) -整数除算命令(DIV、IDIV)の実行にはやたらとクロックがかかるのは本文に書いたとおりです。これは単なる割り算(/)だけではなくて、あまりを求めるときにも実行される命令です(%)。 -一方で、掛け算はどうかというと、2のベキ倍(2倍、4倍、8倍、16倍・・・)はシフト命令を使うことで非常に少ないクロックで実行できるのは知っている人も多いと思いますが、整数乗算命令(IMUL)はPentiumPro/PentiumII以降なら(つまりCPUのクロックが300MHzを超えているような機種なら)シフト命令並みの速度で計算できるようなっています。したがってかつての高速化テクニックを使って、18倍を9倍×2倍とかに直すよりも単にIMULを使ったほうが高速だったりします。 -掛け算命令がCPUの進歩と共に高速化されたにもかかわらず、割り算が高速化されていないのには理由があります。桁数の多い掛け算の筆算を考えてみてほしいのですが、掛け算では筆算の各行を計算するときに、他の行の結果が必要になったりはしません。他の行の計算結果が必要なるのは、最後に全部の和を出すときだけです。だからCPUの中ではそれぞれの行の算出を別々の回路で同時にやらせることが可能で、演算時間の高速化を達成しています。 -一方で割り算はこうは行きません。桁数の多い割り算の場合、一つの桁に対して、割ったあまりを出しおわらないと、次の桁の計算が始められないのです。このため掛け算のときのような高速化が出来ません。 *** テーブルの使用について -(by [[K]], 2008.08.23) -割り算などの計算を高速化するために、計算結果を配列に入れておき、計算の代わりに配列から値を取り出すという手法があります(九九の表から掛け算結果を求めるような感じ)。これはかつてはかなり有効な方法でしたが、現在ではうまくいかない場合も出てきています。 -というのも、最近のCPUはとても高速に動作しているのにもかかわらず、メモリはあまり高速ではないからです。そのために「キャッシュメモリ」なんてものがCPUに取り付けられ、メモリのスピードにCPUの足が引っ張られないように工夫しているくらいです。 -割り算くらいの演算量であれば、わざわざテーブルを作るのは得策ではないかもしれません。なぜなら、テーブルは当然のことながらメモリ上に置かれ、テーブルから値を取り出すのには(キャッシュメモリ上にテーブルのコピーが無ければ)ものすごく長い時間がかかるからです。この時間のかかり方は、DIV命令の遅さとは比べ物にならないとんでもないものです。 -もちろん以前その付近のメモリを読み書きしたことがあれば、キャッシュメモリはその値を覚えているはずなので、テーブルを引くのには時間は要りません。だからそういう場合はテーブルは効果絶大です。しかしキャッシュメモリの容量はかなり小さいので、他の番地のメモリの内容を覚えているうちにテーブルの内容を忘れてしまうことは十分にありえます。 -また仮にキャッシュメモリにいつも入っているとしても、それはつまりその分だけ他のメモリの内容をキャッシュメモリに入れておく機会を奪っていることになるので、プログラムの他の場所でキャッシュミスヒットが発生し、実際のメモリから値を読みに行くことになるでしょう。それなら整数除算命令を素直に使うほうが総合的には速いかもしれません。ということで、結局除算程度の処理ではテーブルによる高速化はあまりうまくいきません。テーブルはもっとずっと重たい計算(たとえば平方根とか)でこそ効果があるでしょう。 * こめんと欄 #comment
タイムスタンプを変更しない
* CPUの動作に関するより詳しい解説ページ -(by [[K]], 2006.09.02) -発展課題のページ(全部読む前にここを読むのは混乱するのでおすすめじゃないです) *** CPUによる自動スタック切り替え機能の詳細ついて -(by [[K]], 2006.09.02) -おもに 21-7 の内容の補足 --ついでにINT命令、IRETD命令の詳細の理解 -この内容は理解を深め知的好奇心を満足させてくれますが、話が長くなる上にややこしくしたくはなかったので、本文中では割愛しました。それをここに書きます。 ---- -スタックの切り替えは、INT命令実行時(割り込み時も含む)とIRETD命令の実行時におきます。 -INT命令の実行時にCPUは以下の処理をします。 if (現在がアプリモードで、割り込み処理ルーチンがOSモードの場合) { スタックを切り替えるために、ESPとSSの値をTSSのss0とesp0から読み込む。 IRETD命令実行時にもとのSSとESPに戻せるように、 PUSH(旧SS); PUSH(旧ESP); を実行する。 (これらの値は切り替わった先のOS用スタックに積まれることになる。) } PUSH(EFLAGS); PUSH(CS); PUSH(EIP); CLI(); を実行する。 EIPとCSの値をIDTから読み込む。 if (エラーコードのある例外の場合) { PUSH(エラーコード); を実行する。 } -IRETD命令の実行時にCPUは以下の処理をします。 POP(EIP); POP(CS); POP(EFLAGS); を実行する。 if (それまでがOSモードでしかもPOPしたCSがアプリモードの場合) { スタックを切り替えるために、 POP(ESP); POP(SS); を実行する。 ( POP(ESP); した時点でESPが変わってしまうと次の POP(SS); がうまくいかなくなるので、 回路を工夫して、POPした値がESPに代入されるタイミングを遅らせてある。) } *** 整数除算命令の重さについて -(by [[K]], 2008.08.23) -整数除算命令(DIV、IDIV)の実行にはやたらとクロックがかかるのは本文に書いたとおりです。これは単なる割り算(/)だけではなくて、あまりを求めるときにも実行される命令です(%)。 -一方で、掛け算はどうかというと、2のベキ倍(2倍、4倍、8倍、16倍・・・)はシフト命令を使うことで非常に少ないクロックで実行できるのは知っている人も多いと思いますが、整数乗算命令(IMUL)はPentiumPro/PentiumII以降なら(つまりCPUのクロックが300MHzを超えているような機種なら)シフト命令並みの速度で計算できるようなっています。したがってかつての高速化テクニックを使って、18倍を9倍×2倍とかに直すよりも単にIMULを使ったほうが高速だったりします。 -掛け算命令がCPUの進歩と共に高速化されたにもかかわらず、割り算が高速化されていないのには理由があります。桁数の多い掛け算の筆算を考えてみてほしいのですが、掛け算では筆算の各行を計算するときに、他の行の結果が必要になったりはしません。他の行の計算結果が必要なるのは、最後に全部の和を出すときだけです。だからCPUの中ではそれぞれの行の算出を別々の回路で同時にやらせることが可能で、演算時間の高速化を達成しています。 -一方で割り算はこうは行きません。桁数の多い割り算の場合、一つの桁に対して、割ったあまりを出しおわらないと、次の桁の計算が始められないのです。このため掛け算のときのような高速化が出来ません。 *** テーブルの使用について -(by [[K]], 2008.08.23) -割り算などの計算を高速化するために、計算結果を配列に入れておき、計算の代わりに配列から値を取り出すという手法があります(九九の表から掛け算結果を求めるような感じ)。これはかつてはかなり有効な方法でしたが、現在ではうまくいかない場合も出てきています。 -というのも、最近のCPUはとても高速に動作しているのにもかかわらず、メモリはあまり高速ではないからです。そのために「キャッシュメモリ」なんてものがCPUに取り付けられ、メモリのスピードにCPUの足が引っ張られないように工夫しているくらいです。 -割り算くらいの演算量であれば、わざわざテーブルを作るのは得策ではないかもしれません。なぜなら、テーブルは当然のことながらメモリ上に置かれ、テーブルから値を取り出すのには(キャッシュメモリ上にテーブルのコピーが無ければ)ものすごく長い時間がかかるからです。この時間のかかり方は、DIV命令の遅さとは比べ物にならないとんでもないものです。 -もちろん以前その付近のメモリを読み書きしたことがあれば、キャッシュメモリはその値を覚えているはずなので、テーブルを引くのには時間は要りません。だからそういう場合はテーブルは効果絶大です。しかしキャッシュメモリの容量はかなり小さいので、他の番地のメモリの内容を覚えているうちにテーブルの内容を忘れてしまうことは十分にありえます。 -また仮にキャッシュメモリにいつも入っているとしても、それはつまりその分だけ他のメモリの内容をキャッシュメモリに入れておく機会を奪っていることになるので、プログラムの他の場所でキャッシュミスヒットが発生し、実際のメモリから値を読みに行くことになるでしょう。それなら整数除算命令を素直に使うほうが総合的には速いかもしれません。ということで、結局除算程度の処理ではテーブルによる高速化はあまりうまくいきません。テーブルはもっとずっと重たい計算(たとえば平方根とか)でこそ効果があるでしょう。 * こめんと欄 #comment
テキスト整形のルールを表示する