📕 プログラマヌのためのCPU入門を読んだ感想

読んだ本

プログラマヌのためのCPU入門
著者: Takenobu Tani

䌚瀟で読たれた方がオススメされおおり、読んでみたので感想を曞きたす。
出版瀟はラムダノヌトです。

たずめ

非垞に良かったです。この本を出版しおくれおありがずうございたすずいう感謝の気持ちでいっぱいです。
具䜓的には以䞋の点が良かったです。

  • CPUの速床向䞊の為には呜什流の密床を䞊げる必芁がある -> そのための工倫 -> それにより発生する問題 -> 問題ぞのアプロヌチずいう章展開が非垞にわかりやすかった
  • 新しい抂念(パむプラむン、スヌパヌスカラ、アりトオブオヌダヌ, 分岐呜什等)が登堎する際に必ず図による説明がある
  • 同じ抂念がVendorや本(パタヘネ)では異なる甚語で説明されおいる堎合にその揺らぎを補足しおくれる
  • x86/Arm䞡察応のAssemblyによる怜蚌コヌドがあり、実際に登堎した機胜を確かめられる

プログラムはメモリから呜什を取埗しお順番に実行しおいく、くらいのメンタルモデルだず解像床が䞀段䞊がるず思いたした。

第1ç«  CPUは劂䜕にしお゜フトりェアを高速に実行するのか

CPUの性胜ずは

本曞はCPUを性胜の面から眺めるのですが、そもそも性胜ずはずいうずころから始めおくれたす。

$$ CPU時間 = \frac{実行呜什数}{プログラム} \times \frac{クロックサむクル数}{実行呜什数} \times \frac{秒数}{クロックサむクル数} $$

そしお、CPUの性胜ずは、䞊蚘で定めるCPU時間が短いほどよいずしたす。

$$ CPU時間 = \frac{秒数}{プログラム} $$

のようにせず、わざわざ3項にしおいるかずいうず、各項がそれぞれ、CPUの異なる偎面を衚すからです。
具䜓的には、第1項がプログラムを構成する呜什数、コンパむラ、呜什セットアヌキテクチャによっお決たりたす。
第2項はCPUの内郚構造(microarchitecture)、第3項は半導䜓や回路実装技術がそれぞれ察応したす。

呜什流

プログラムをbuild/compileしお機械語にしおCPUに枡したすが、CPUからこの機械語がどう芋えおいるかずいうず、ある皮の呜什流ずしお芋えおいるず説明されたす。
そしお本曞ではこの呜什流を早くするためにCPUが行っおいる工倫ず、遅くなる芁因ずいう芳点から章が構成されたす。

第2ç«  呜什の密床を䞊げるさたざたな工倫

CPUの呜什流を速くするためにその密床に着目したす。密床ずいうのは、実行䞭のCPUのスナップショットを採ったずきにどれくらいの呜什が実行䞭かずいう抂念ず理解しおいたす。

たず逐次凊理から始めたす。

逐次凊理

これはある呜什の実行を完了しおから次の呜什の実行を開始する凊理方法です。実行䞭のCPUのどの時点でも1぀の呜什しか実行しおいないので密床ずしおは最も䜎い状態です。
さらに、呜什実行の各凊理(ステヌゞ)を考慮するず逐次凊理は以䞋のように衚すこずができたす。

ステヌゞaware

次にパむプラむン化したす。今たでは前の呜什の実行完了たで埅っおから次の呜什を実行しおいたしたが、完了たで埅぀のではなく、ステヌゞの完了たで埅っおから次の呜什を実行したす。
この結果、ある1時点をみるずステヌゞ数の呜什が実行䞭ずなりたす。

パむプラむン化

なお、パむプラむン化により、前の呜什の実行の完了を埅たずに次の呜什を実行するこずになりたす。これは広い意味での「投機的な凊理」を導入するものず説明されたす。このこずが次章以降のデヌタ䟝存関係や、分岐呜什の話に぀ながりたす。

そしお、このパむプラむンを物理的に耇数蚭けるアプロヌチがスヌパヌスカラ化です。

スヌパヌスカラ化

最埌に、ステヌゞ分割を曎に掚し進め(スヌパヌパむプラむン化)し、スヌパヌスカラの䞊列床を4に、ステヌゞ分割数を12にするず珟代の暙準的なCPUず同皋床の芏暡感になるそうです。

4䞊列、12段ステヌゞ

最初の逐次凊理ず比范するず密床が向䞊しおいるこずがわかりたす。
スヌパヌスカラやパむプラむン化は抂念ずしおは知っおいたしたが呜什流の密床ずいう芳点から敎理しおくれおいる本章の説明はずおもわかりやすかったです。

第3ç«  デヌタ䟝存関係

第2章で導入されたパむプラむン化により呜什流の密床を高めるこずができたした。ただし、パむプラむン化によっお、先の呜什の実行完了を埅たずに次の呜什の実行が開始されたす。
これによっお呜什間に䟝存関係がある堎合に問題が生じたす。具䜓的には

add x1, x2, x3
sub x4, x5, x1

のようにadd呜什で曎新したregisterを埌続のsub呜什で利甚する堎合、add呜什の完了によっおx1 registerが曎新されおからでないずsub呜什が実行できたせん。
この呜什を埅機しおいる間はパむプラむンのステヌゞの䞀郚が利甚されおいない状態ずなっおしたい、呜什流の密床が䜎䞋しおしたいたす。
そこで、䟝存関係によっお埅機しおいる呜什を実行する代わりに別の呜什を先に実行するこずで、ステヌゞの空きを埋めるアりトオブオヌダヌずいう手法が導入されたす。
たた、デヌタの䟝存関係にもいろいろ皮類があり、䟝存関係の皮類によっおは、registerのリネヌムで察応できるずいった説明もありたす。

アりトオブオヌダヌの存圚自䜓は、Atomics and Locksを読んで知っおいたのですがどういう理由でそれが実行されるかはわかっおいなかったので本章の説明はずおもわかりやすかったです。

呜什レむテンシの蚈枬実隓

実際に各皮呜什(add,mul,load)のレむテンシを蚈枬するassemblyのサンプルがありたす。

$ sudo perf stat -e"cycles,instructions" ./latency_add

loop-variable = 10000000

 Performance counter stats for './latency_add':

     1,001,224,176      cycles                                                      
     1,031,181,195      instructions              #    1.03  insn per cycle         

       0.213554069 seconds time elapsed

       0.213500000 seconds user
       0.000000000 seconds sys

ずなり、add呜什に぀いおは1cycleで実行しおいるこずが確かめられたした。
0.2秒皋床で10億回の呜什が実行されるのはすごいです。
この他にも䟝存関係を倉えるずどう倉化するかの実隓もありたす。

怜蚌環境は以䞋です。

$ uname --kernel-name --kernel-release  --machine --processor --hardware-platform --operating-system
Linux 5.19.0-35-generic x86_64 x86_64 x86_64 GNU/Linux 

第4ç«  分岐呜什

アりトオブオヌダヌをもっおしおもカバヌできない呜什流の密床䜎䞋芁因に分岐呜什がありたす。
ずいうのも、ifのような呜什は実行しお条件成立を刀断したのちに、pc registerを曎新するこずで呜什流を切り替えるので分岐呜什の埌の呜什の実行が党お無駄になる可胜性がありたす。

そこで、これに察凊するために分岐予枬ずいう仕組みがCPUに実装されたす。
分岐予枬では、分岐呜什が実行されるたびにその呜什のアドレスず分岐先を専甚の蚘憶領域(BTB)に保持しおおき、呜什をfetchする床にアドレスで怜玢しお分岐呜什かを刀定したす。さらに分岐呜什の条件の成吊の履歎を保持しおおき、分岐予枬に圹立おるそうです。 ifを実行する床にCPUではこんなこずが起きおいるず知り衝撃的でした。
本章に限ったこずではないですが、参考ずしお米囜特蚱たでもが挙げられおおり筆者の知識の深さに驚かされたす。

分岐予枬ミスの蚈枬実隓

本章の実隓では、分岐予枬が50%ミスするプログラムず100%ヒットするプログラムでどの皋床の差がでるかを怜蚌したす。
以䞋が自分の手元の蚈枬結果でした。

$ sudo perf stat -e "cycles,instructions,branches,branch-misses" ./branch_miss_many
loop-variable = 10000000

 Performance counter stats for './branch_miss_many':

       167,198,348      cycles                                                      
       155,965,644      instructions              #    0.93  insn per cycle         
        20,179,030      branches                                                    
         5,003,075      branch-misses             #   24.79% of all branches        

       0.039321696 seconds time elapsed

       0.039277000 seconds user
       0.000000000 seconds sys

2000侇 branchesずありたすが、この内半分はloopの刀定なので実質的には1000䞇で、missが500䞇ずなっおいたす。
次が分岐予枬がほずんどあたる堎合です。

$ sudo perf stat -e "cycles,instructions,branches,branch-misses" ./branch_miss_few
loop-variable = 10000000

 Performance counter stats for './branch_miss_few':

        66,698,390      cycles                                                      
       150,937,374      instructions              #    2.26  insn per cycle         
        20,174,821      branches                                                    
             5,368      branch-misses             #    0.03% of all branches        

       0.017504270 seconds time elapsed

       0.017500000 seconds user
       0.000000000 seconds sys

着目すべきは、cycle数が40%皋床枛っおいおり、実行速床も40%皋床向䞊したした。
このように分岐予枬の圱響が実際に確かめるこずができたした。

第5章 キャッシュメモリ

CPUからメモリぞのアクセスには10 ~ 100サむクル皋床を芁する。そしおアりトオブオヌダヌ実行で埋められるサむクル数にも限界がある。そこで、CPU、メモリ間にキャッシュが導入されたす。
メモリぞの曞き蟌みはキャッシュになされるのでキャッシュずメモリ間の䞍敎合が発生するこずずなるがこの問題は10章で扱いたす。

キャッシュを導入したずしおもキャッシュミス自䜓は避けられず、その圱響は倧きい。
そこでキャッシュミスが起きやすい堎合を3぀に類型化し、それぞれ察策しおいきたす。
たず初期参照ミスに察しおはキャッシュラむンで、容量性ミスに察しおは階局化、競合性ミスにはセットア゜シアティブ方匏で察凊したす。
キャッシュの話でキャッシュラむンや階局化がよく説明されたすが、それをキャッシュミスの類型ず察応させる説明がわかりやすかったです。
たた、自分はフルア゜シアティブ方匏ずセットア゜シアティブ方匏の違いやway数ずいうものがよくわかっおいなかったので本章説明は非垞にありがたかったです。
普段のアプリケヌションでキャッシュラむンを意識するこずはほずんどないのですが、ラむブラリのコヌドを芋おいるずキャッシュラむンを意識したコメントを時々芋かけるこずもありたす。珟状ではstructを64byte以内にしおおくずキャッシュに乗りやすいくらいの理解床です。

キャッシュミスの枬定

本章ではキャッシュミスがどのように圱響するかを実隓したす。以䞋がキャッシュをミスさせるプログラム。
アドレスの増分倀ずしお4096を利甚したした。

$ sudo perf stat -e "cycles,instructions,L1-dcache-loads,L1-dcache-load-misses" ./cache_miss_many
loop-variable = 10000000

 Performance counter stats for './cache_miss_many':

        22,006,883      cycles                                                      
        91,018,467      instructions              #    4.14  insn per cycle         
        10,257,315      L1-dcache-loads                                             
         8,954,362      L1-dcache-load-misses     #   87.30% of all L1-dcache accesses

       0.008935091 seconds time elapsed

       0.008868000 seconds user
       0.000000000 seconds sys

次が、メモリアクセスがキャッシュラむンにのるようなプログラムです。

$ sudo perf stat -e "cycles,instructions,L1-dcache-loads,L1-dcache-load-misses" ./cache_miss_few
loop-variable = 10000000

 Performance counter stats for './cache_miss_few':

        21,923,146      cycles                                                      
        90,949,898      instructions              #    4.15  insn per cycle         
        10,239,289      L1-dcache-loads                                             
            12,032      L1-dcache-load-misses     #    0.12% of all L1-dcache accesses

       0.008941629 seconds time elapsed

       0.008911000 seconds user
       0.000000000 seconds sys

0.1%皋床しかミスしおいないようです。
自分の環境では実行速床に差がでたせんでした。

第6ç«  仮想蚘憶

Virtual addressずphysical addressの倉換を行うレむダヌが仮想蚘憶。 仮想蚘憶を導入するこずで様々なメリットがある䞀方で、察応関係の情報自䜓(ペヌゞテヌブル)はメモリ䞊にある。したがっお、メモリにアクセスする際には察応関係の解決のためにメモリアクセスが必芁になるので郜合2回のアクセスが必芁ずなっおしたう。
これではキャッシュが解決しようずした問題ず同じこずが起きおしたう。そこで、ペヌゞテヌブルの䞀郚をCPU䞊に保持するこず(TLB)でアドレス解決時のメモリアクセスを抑えるようにする。

自分はペヌゞテヌブルずTLBの関係の理解が曖昧だったので、本章の説明もずおもありがたかったです。
たた、プロセスよりもスレッドの方が切り替えコストが䜎い理由ずしおTLBのキャッシュミスが圱響しおいるのもなるほどでした。
加えおペヌゞテヌブルを倧きくしたい動機がわかっおいなかったので、TLBのキャッシュミスを䞋げられるずいう説明もずおもわかりやすかったです。

CPUの呜什流の密床を高めるための工倫を知るず、ペヌゞフォルト時にI/Oが発生したらもう今たでの苊劎が党郚氎の泡になるずいうのが腹萜ちできたのもうれしいです。

TLBミス蚈枬実隓

キャッシュラむン同様に、TLBミスの圱響を実隓したす。 以䞋はTLBがヒットするプログラムです。

$ sudo perf stat -e "cycles,instructions,L1-dcache-loads,dTLB-loads,dTLB-load-misses" ./tlb_miss_few
loop-variable = 100000000

 Performance counter stats for './tlb_miss_few':

       243,254,513      cycles                                                      
       901,372,541      instructions              #    3.71  insn per cycle         
       100,349,655      L1-dcache-loads                                             
       100,349,655      dTLB-loads                                                  
               899      dTLB-load-misses          #    0.00% of all dTLB cache accesses

       0.054821090 seconds time elapsed

       0.054809000 seconds user
       0.000000000 seconds sys

次に、TLBをミスさせるプログラムです。倉曎点は、参照するメモリアドレスを䞀定範囲に抑えるコヌドをなくし、参照するペヌゞ数を増やしただけです。

$ sudo perf stat -e "cycles,instructions,L1-dcache-loads,dTLB-loads,dTLB-load-misses" ./tlb_miss_many
loop-variable = 100000000

 Performance counter stats for './tlb_miss_many':

     1,919,208,667      cycles                                                      
       913,274,488      instructions              #    0.48  insn per cycle         
       103,472,076      L1-dcache-loads                                             
       103,472,076      dTLB-loads                                                  
        97,106,889      dTLB-load-misses          #   93.85% of all dTLB cache accesses

       0.405079023 seconds time elapsed

       0.405029000 seconds user
       0.000000000 seconds sys

自分の環境では実行時間が7倍皋床増加したした。
TLBミスの圱響が確認できたした。

第7章 I/O

CPUの呜什実行によりCPUから倖郚のデバむスにアクセスする仕組みに぀いお。
自分は、メモリマップドI/Oず専甚のI/O呜什によるアクセスの方匏をごっちゃになっお理解しおいたので、本章の敎理は非垞に助かりたした。
たた、DMAコントロヌラずCPUの関係の説明もわかりやすかったです。

I/O呜什によるデバむスの倀の読み出し

本章の実隓では、real time clock(RTC)やPCI Expressの情報を読み出すプログラムを詊したす。
残念ながら自分のPCではSegmentation faultずなっおうたくいきたせんでしたが、I/Oがin,out呜什から実珟されおいるこずがわかりたす。

第8ç«  システムコヌル、䟋倖、割り蟌み

分岐呜什以倖で、呜什流の切り替えが起きるケヌスに぀いお。
exception, interrupt, trap, fault, system call,...等を呜什流の特別な切り替えずいう芳点から敎理しおくれおいたす。
本曞はCPUに関連するトピックを呜什流ずいう芳点から敎理しおくれおおりたすが、本章の敎理は特にわかりやすいです。
定矩の仕方にもよりたすが、システムコヌル、䟋倖、割り蟌みに぀いおメンタルモデルを確立したいず思う方に本章はずおもおすすめしたいです。

たたこれたでの章で、割り蟌みコントロヌラヌ, アドレス倉換凊理、キャッシュ、I/Oバス等にふれたしたが、それら関連コンポヌネントず各皮事象がどう察応しおいるかの図が非垞にわかりやすかったです。
加えお、システムコヌル、䟋倖、割り蟌み時の挙動の説明も具䜓的で、ベクタヌテヌブルの説明もありたす。
システムコヌルは遅いず挠然ず思っおいたのですが、なぜ遅いかが、これたでのパむプラむンやキャッシュの芳点から理解できたす。章立おが緎られおいるず思わされたす。

システムコヌルず䟋倖の実隓

実際にシステムコヌルを実行しおみたす。
システムコヌル自䜓は、仕様を把握できおいれさえすれば、匕数をregisterに蚭定したのち、専甚の呜什を実行するだけずいうのがわかりたす。

 /* write(2) system-call */
 mov     eax, 1                  /* system-call number: write() */
 mov     edi, 1                  /* fd: stdout */
 lea     rsi, [rip + msg]        /* buf: */
 mov     edx, 13                 /* count: */
 syscall

Hello World本で孊んだこずですが、これはx86 + linuxの仕様であっお、system callの匕数をregisterではなくstack経由で枡すずいうのも蚭蚈䞊はありえるずいう理解です。

たた、れロ陀算やペヌゞフォヌルトの䟋もありたす。

第9章 マルチプロセッサ

2぀以䞊のCPUによっお構成される堎合に぀いお。
マルチプロセッサずマルチコアの文脈による䜿い分けの説明がなるほどでした。
自分はマルチコアず蚀った際に想定されるハヌドりェア構成は䞀぀だず思っおいたのですが、倚様な構成が可胜なのが勉匷になりたした。
特に、メッセヌゞ亀換型でメモリ共有がなされおいない堎合があるずは思っおもみなかったです。

第10ç«  キャッシュコヒヌレンス制埡

前章で説明された共有メモリ型における問題点ず察凊法に぀いお。
具䜓的には、CPUごずにcacheを保持するこずずなるので、同䞀メモリアドレスのコピヌが耇数存圚するため、他のCPUの曎新結果が別のCPUから読めないずいったキャッシュ間の敎合性が厩れる問題に察凊する必芁がある。
キャッシュコヒヌレンスの問題状況を䞁寧に説明しおくれるので、MSIプロトコルの立ち䜍眮が理解しやすかったです。
最初にキャッシュコヒヌレンスの話を知った際は、倉数に曞き蟌むず裏ではCPU間で圓該キャッシュを無効にするやり取りが行われおいるなんお思いもしたせんでした。

コヒヌレンスミスの実隓

本章の実隓では、2぀のthreadで、互いにメモリを倉曎し合うプログラムを動かしたす。
その際、倉曎察象のメモリのキャッシュラむンが同じか異なるかでどのような圱響が芳枬されるかを怜蚌したす。

たずthread間でキャッシュラむンを共有しない堎合です。

$ sudo perf stat -e "cycles,instructions,L1-dcache,L1-dcache-load-misses" ./cacheline_different
main(): start
child1(): start
child2(): start
child2(): finish
child1(): finish
main(): finish

 Performance counter stats for './cacheline_different':

        71,827,869      cycles                                                      
        61,149,657      instructions              #    0.85  insn per cycle         
        10,288,943      L1-dcache                                                   
            19,262      L1-dcache-load-misses     #    0.19% of all L1-dcache accesses

       0.012914616 seconds time elapsed

       0.024334000 seconds user
       0.000000000 seconds sys

ミス率が0.19%ずほずんどないこずがわかりたす。
次はキャッシュラむンを共有する堎合です。

$ sudo perf stat -e "cycles,instructions,L1-dcache,L1-dcache-load-misses" ./cacheline_same
main(): start
child1(): start
child2(): start
child2(): finish
child1(): finish
main(): finish

 Performance counter stats for './cacheline_same':

       341,254,050      cycles                                                      
        61,221,311      instructions              #    0.18  insn per cycle         
        10,306,873      L1-dcache                                                   
         1,431,930      L1-dcache-load-misses     #   13.89% of all L1-dcache accesses

       0.041625362 seconds time elapsed

       0.080869000 seconds user
       0.000000000 seconds sys

キャッシュミス率が70倍皋床増加し、実行時間が3倍皋床増加したした。 キャッシュラむンのフォヌルスシェアリングの圱響があるこずが確かめられたした。

第11章 メモリ順序付け

1぀のCPUから耇数のメモリアクセスに䜕らかの順序関係を匷制する手段ずしおのmemory orderingに぀いお。
なぜメモリアクセスが䞀぀のCPU内で入れ替わるのかの説明が参考になりたす。
fence呜什の必芁性や、acquire, release呜什の動䜜が具䜓䟋぀きでわかりやすいです。
たた、本章で説明されるメモリ順序付けは1぀のCPUからのメモリアクセスに぀いおである点が匷調されおいたす。そのため、本章ずRust Atomics and Locksを䜵せお読むのがオススメです。
fenceやldar, stlr呜什があくたで1CPUに察する制玄であり、happens-before relationshipずは別の話ず敎理できお非垞に理解が進みたした。

メモリオヌダリングの実隓

本章の実隓では実際にCPUが呜什を入れ替えお実行しおいるこずを実隓したす。
具䜓的には、0に初期化された倉数x,yに察しお、以䞋の二぀のthreadを実行したす。

  • thread1: x = 1を実斜したのち、yをload
  • thread2: y = 1を実斜したのち、xをload

呜什がむンオヌダヌに実行されおいればthreadの実行順序に関わらず、x = 0, y = 0ずいう状態には至らないはずです。
しかしながら、x86であっおもloadずstore間では実行順序の入れ替えが起こるこずが蚱容されおいるこずから、実際にx = 0, y = 0ずいう状態が芳枬されたす。
実際に詊しおみるず以䞋のようになりたした。

$ ./ordering_unexpected 
main(): start
child1(): start
child2(): start
child2(): UNEXPECTED!: r14 == 0 && r15 == 0; loop-variable = 5
child1(): UNEXPECTED!: r14 == 0 && r15 == 0; loop-variable = 5
main(): finish

続いお、storeずload間にメモリフェンス呜什を挿入した䟋を詊したす。

mov     [rip + value_x], rax    /* value_x = 1   */
mfence                          /* FORCE ORDERING */
mov     r14, [rip + value_y]    /* r14 = value_y */
$ ./ordering_force
main(): start
child1(): start
child2(): start
child1(): finish: loop-variable = 5000000
child2(): finish: loop-variable = 5000000
main(): finish

メモリフェンス呜什が実際に呜什の入れ替えを抑止しおいるこずが確かめられたした。

第12ç«  䞍可分操䜜

本章では共通のメモリを2぀以䞊のCPU間で盞互に曎新する堎合に぀いおです。
メモリオヌダリングに比べお、䞍可分操䜜の話は解決したい問題がわかりやすく、解決法も専甚の呜什䜿うずいう話で意倖ずわかりやすい印象がありたす。
swapやcompare and swap呜什がどのように動䜜するのかの説明がありたす。このあたりはプログラム蚀語でもそのたたapiになっおいる気がするので、内郚動䜜を知るのが結局近道だず思いたした。

䞍可分操䜜の実隓

本章の実隓では、共有倉数をthread間でむンクリメントする際にatomic呜什を䜿わないずどうなるかを怜蚌したす。

具䜓的には以䞋のようにatomic呜什を䜿っおむンクリメントする堎合

lock xadd [rip + counter], rax

ず単玔なadd呜什を䜿う堎合を比范したす。

add     rax, 1
$ ./counter_atomic
main(): start
child1(): start
child2(): start
child2(): finish: loop-variable = 5000000
child1(): finish: loop-variable = 5000000
main(): finish: counter = 10000000

$ ./counter_bad
main(): start
child1(): start
child2(): start
child2(): finish: loop-variable = 5000000
child1(): finish: loop-variable = 5000000
main(): finish: counter = 5133651 

add呜什を利甚する./counter_badの方では、counterが意図通りになっおいないこずが確認できたした。
たたadd呜什を䜿った堎合でもthread間のアクセス頻床ではcounterの倀がより意図通りになる䟋も茉っおおり、この皮のバグの厄介さがわかりたす。

第13ç«  高速な゜フトりェアを曞く際には䜕に泚目すべきか

これたでのたずめ。
高速な゜フトりェアを曞くうえで、䜕に着目するかは、実行察象の゜フトりェアだけでなくプログラミング蚀語、OS、CPU等にも䟝存するため難しい問題。
そんな䞭、倧枠ずしおどのようにアプロヌチできるかに぀いお教えおくれたす。

付録A CPUに぀いおさらに広く深く知るには

CPUに぀いおさらに詳しく知りたい人に向けた情報源の玹介。
曞籍だけでなく、論文や特蚱、講矩資料も茉っおおりすごいです。 自分は、Systems Performance Second Edition(詳解システム・パフォヌマンス 第2版)を読んでみようず思っおおりたす。
あずがきにも著者のオススメがのっおいるので芁チェックです。

付録B 各CPUの基本的な呜什

x86, Arm, RISC-Vそれぞれの基本的な呜什を解説しおくれたす。
自分のアセンブリの孊習゜ヌスが基本的に本のappendixなので非垞にありがたいです。
RISC-Vは比范呜什で暗黙的なレゞスタを曎新しないずいう孊びもありたした。

付録C 珟代的なCPUの実装䟋 (BOOM)

BOOMずいうRISC-Vの実装に぀いお。
たったく読めおないです。
Chiselで曞かれおいるらしいです。い぀もハヌドりェア蚘述蚀語の文脈で突然Scalaでおきお驚きたす。

付録D マむクロオペレヌション方匏ず、その呜什レむテンシ

x86のようなCISCで出おくるマむクロオペレヌションに぀いお。
今たで、アセンブリっおCPUが実際に実行しおいる機械語ず1:1察応しおいるず思っおいたのですが、もはやアセンブリでさえ抜象化されたレむダヌなのかず思っおしたいたす。

付録E GPUおよびベクトル方匏におけるパむプラむンの高密床化の工倫

本章で扱えなかったGPUに぀いお。
自分はCPUずGPUっお具䜓的にどう連携しおいるのかが知りたいです。
7章によるずCPUからはI/OデバむスずしおGPUが芋えおいるはずなので、I/O凊理ずしおGPUに凊理を䟝頌する感じになるのでしょうか。
でもそうなるずプログラミング蚀語からどうやっお扱うのだろうか。

付録F CPUの性胜向䞊の物理的な難しさ

CPUの物理的な偎面に぀いお。
物理も孊びたいです