Slide 1

Slide 1 text

#11 プロセスと ハードウェア B2 sksat

Slide 2

Slide 2 text

おさらい:デジタルデータの表現 ・ビット(bit):情報の最小単位 ・0/1, yes/no, ON/OFF, +/-, N/S ・2進数の1桁 ・バイト(byte):8bit ・電子計算機ではデータをだいたい 1〜数バイト単位で処理 ※実は1byte != 8bit.まあほとんどは8bitだが...(明示的に8bitだと言う場合はオクテット)

Slide 3

Slide 3 text

コンピュータの構造(迫真) :thinking_think: ホンマか?

Slide 4

Slide 4 text

皆さんのお手元のThinkPad X230

Slide 5

Slide 5 text

バラバラ事件 これを こうして こうじゃ

Slide 6

Slide 6 text

マザーボード HDD メモリ CPU ファン

Slide 7

Slide 7 text

メモリ ・データをたくさん置いておける (1,2,4,8,16,32,64...GB) ・1次記憶・主記憶 ・揮発性:電源切るとデータが消える ・アドレス(番地)を指定してデータを読み書き ・byteごと data 〜 0x0000 0x0001 0x0002 0x0003 0x0004 0xffff 0xfffe 0xfffd 0xfffc 0xfffb

Slide 8

Slide 8 text

メモリの読み書き 0xaf 0xbe 0xad 0xde 〜 0x0000 0x0001 0x0002 0x0003 0x0004 0xffff 0xfffe 0xfffd 0xfffc 0xfffb CPU \addr=0x002のデータが1byteホシイ/ 0xab \addr=0xfffeに0xabを入れたい/ 0xad 0xab

Slide 9

Slide 9 text

バス ・メモリ読み込み ・CPU:アドレス→アドレスバス ・メモリ:memory[addr] -> データバス ・メモリ書き込み ・CPU:アドレス→アドレスバス   書くデータ→データバス ・メモリ:memory[addr] <- データバス

Slide 10

Slide 10 text

レジスタ ・CPUの中にも記憶領域がある ・レジスタは小さい(8〜64bit) ・メモリよりはるかに高速 ・メモリが作業机ならレジスタは手とか ・用途によって色々ある x86のレジスタ

Slide 11

Slide 11 text

HDD/SSD ・2次記憶装置 ・不揮発性:電源切ってもデータが残る! ・OS/プログラムはここに保存 ・起動したらメモリに読み出してから動作 ・容量がデカい:数百GB〜数TB ・ブロックデバイス:「ブロック (512byteとか)」ごとに読み書き

Slide 12

Slide 12 text

記憶装置 記憶容量: 2次記憶(HDD/SSD) >>> 1次記憶(メモリ) >>>>>>> レジスタ ・ぜんぶ2次記憶でいいじゃん アクセス速度:レジスタ >>>>>>>  1次記憶 >>>> 2次記憶 ・それだと遅すぎる!!!!! ・レジスタはCPUの内部なので超高速 容量当たりの価格: レジスタ >>>  1次記憶 >>> 2次記憶 ・でも2次記憶装置は安い ・2次記憶でもHDDは低速安価大容量,SSDは高速高価低容量(比較的)

Slide 13

Slide 13 text

メモリのアクセス速度 ・メモリ:数十〜数百サイクル ・昔はCPUの動作速度が大したことなかったのでなんとかなった ・今:CPU「俺の”速さ”についてこられるかな?」 ・int a = 1 + 2; ← a, 1, 2がレジスタかメモリ上かで数十〜数百倍速度が変わってしまう!? ・コンパイラの最適化でできる限りレジスタが使われるようになってる ・めでたしめでたし・・・とはいかない ・思い出すシリーズ:レジスタはクソ小さい ・じゃあどうすんねん

Slide 14

Slide 14 text

キャッシュメモリ ・レジスタとメモリの中間の存在 ・もちろんメモリより低容量高価格だが高速 ・レジスタとメモリの間に挟む レジスタ キャッシュメモリ メモリ 3次キャッシュ 2次キャッシュ ・最近は2, 3, 4次キャッシュなんてものも

Slide 15

Slide 15 text

キャッシュメモリのしくみ ・発想:アクセスしそうなデータがいいかんじに キャッシュに載っているとうれしい! メモリ キャッシュメモリ addr=0x01, data=0xbe addr=0x03, data=0xde addr=0x05, data=0xba addr=0x09, data=0x1f 0x00: 0xef 0x01: 0xbe 0x02: 0xad 0x03: 0xde 0x04: 0xbe 0x05: 0xba 0x06: 0xfe 0x07: 0xca 0x08: 0x8b 0x09: 0x1f 0x0a: 0x00 addr=0x0a, data=0x00

Slide 16

Slide 16 text

キャッシュメモリのしくみ(2) ・「アクセスしそうなデータ」とは? ・時間的局所性:同じアドレスに何度もアクセスする ・空間的局所性:アクセスしたところの近くにアクセスする ・方式がいくつかある:ダイレクトマップ,セットアソシアティブ,フルアソシアティブ

Slide 17

Slide 17 text

デバイスとのやりとり ・入出力命令 ・入力:ちょっとN番のデバイスから値を取ってきて ・出力:ちょっとN番のデバイスにこれをセットして ・割り込み:デバイス「カンカンカンカン!!!入力!!!!おきてー!!!!!」 ・MMIO

Slide 18

Slide 18 text

MMIO ・Memory Mapped I/O ・メモリとデバイスが繋がっている (!?) ・マイコンだとよくある ・PCだとVRAM(Video RAM) ・「(x=10, y=20)を紫に」とかを入出力命令でやってたら遅すぎる ・メモリの一部の領域がディスプレイと接続 VRAM 0xA0000 0xAFFFF

Slide 19

Slide 19 text

「プログラム」の正体 ・プログラムもデータ(バイナリ) ・CPUへの命令の集まり ・「機械語」

Slide 20

Slide 20 text

機械語 ・CPUはバカ ・int a = 1 + 2; ← こんなの難しすぎてわからん ・面接官「あなたは何ができるんですか?」 ・CPU「計算がとても速くできるくらいです ...」 ・思い出すシリーズ:電子計算機 ・機械語:CPUが理解できる「言葉」 ・いくつか[要出典]の命令 ?

Slide 21

Slide 21 text

機械語の種類 ・算術命令:add, sub, mul, divなど ・add eax, 0x05:EAXレジスタの値に5を足す ・論理演算命令:and, or, not, xorなど ・ビットシフト ・メモリの読み書き ・入出力命令 ・ジャンプ命令:実行位置を変更

Slide 22

Slide 22 text

プログラムの実行 ・電源投入 ・2次記憶→メモリ ・実行開始! ・どうやって?

Slide 23

Slide 23 text

プログラム実行のしくみ add r0, 5 sub r1, [0x20] inc r1 add r0, r1 jmp -2 実行中 PC: 0x01 r0: 0x05 r1: 0x00 memory[0x20] = 0x03 メモリ

Slide 24

Slide 24 text

プログラム実行のしくみ add r0, 5 sub r1, [0x20] inc r1 add r0, r1 jmp -2 実行中 PC: 0x02 r0: 0x02 r1: 0x00 memory[0x20] = 0x03 メモリ

Slide 25

Slide 25 text

プログラム実行のしくみ add r0, 5 sub r1, [0x20] inc r1 add r0, r1 jmp -2 実行中 PC: 0x03 r0: 0x02 r1: 0x01 memory[0x20] = 0x03 メモリ

Slide 26

Slide 26 text

プログラム実行のしくみ add r0, 5 sub r1, [0x20] inc r1 add r0, r1 jmp -2 実行中 PC: 0x04 r0: 0x03 r1: 0x01 memory[0x20] = 0x03 メモリ

Slide 27

Slide 27 text

プログラム実行のしくみ add r0, 5 sub r1, [0x20] inc r1 add r0, r1 jmp -2 実行中 PC: 0x02 r0: 0x03 r1: 0x01 memory[0x20] = 0x03 メモリ

Slide 28

Slide 28 text

プログラム実行のしくみ add r0, 5 sub r1, [0x20] inc r1 add r0, r1 jmp -2 実行中 PC: 0x03 r0: 0x03 r1: 0x02 memory[0x20] = 0x03 メモリ

Slide 29

Slide 29 text

プログラムカウンタ ・「次に実行する命令」や「今実行している命令」の アドレスを指すレジスタ ・ジャンプ命令:プログラムカウンタの値を変える命令 絶対ジャンプ:アドレスを指定してジャンプする 相対ジャンプ:「N個前/後の命令」にジャンプする ・前にジャンプ → 繰り返し処理を実現 ・条件ジャンプ命令:「比較結果が0だったらジャンプ」 ・条件分岐の実現(条件分岐命令とも)

Slide 30

Slide 30 text

様々なコンピュータアーキテクチャ ・コンピュータの基本的な構造は大体同じ ・スマホもバラせばCPU・バス・メモリ・ディスク・外部装置 ・PCの/bin/bashをスマホにコピーしたら動くか?  → 動かない ・何故か? ・CPUの種類が違う ・PCはx86,スマホはarm ・機械語の種類・フォーマットが全然違う

Slide 31

Slide 31 text

RISCとCISC ・アーキテクチャ設計の2つの思想 ・RISC:命令が固定長 ・CISC:命令が可変長

Slide 32

Slide 32 text

代表的なアーキテクチャ(ISA) ・x86:CISC.皆さんのお手元のPCに多分入ってる.Core 〜とかRyzen 〜とか. ・Arm:RISC(などと主張しており).スマホに入ってる.マイコンの Cortex-M*とかもある. ・RISC-V:RISC.UCB発のオープンなアーキテクチャ.最近はマイコンも出てきた. ・MIPS:RISC.今はもう... ・PowerPC:RISC.昔のAppleが使ってた.なんかPerseveranceに入ってるらしい. ・SPARC:RISC. .京はSPARC64. ・SuperH:RISC.日立製作所.組み込み向け.日本の人工衛星には結構入ってるらしい. ・PDP-11:おぢさんがすきなやつ

Slide 33

Slide 33 text

64bitアーキテクチャ ・「これは16bitアーキテクチャ,こっちは32bitアーキテクチャ」とか言ったりする ・32bitアーキテクチャは汎用レジスタ・メモリアドレスのサイズが 32bit ・0xffffffff ≒ 4 * 1024 * 1024 * 1024 ・表現できるのが約4GB(4GiB) <- アドレス空間の大きさ ・今は32/64bitアーキテクチャが主流

Slide 34

Slide 34 text

マルチタスク

Slide 35

Slide 35 text

ところで

Slide 36

Slide 36 text

選ばれたのは,Ryzen™でした ・最近3600から3700Xに ・個人でも8C16TのCPUが安価に手に入る時代... ・すりっぱほしい

Slide 37

Slide 37 text

しかし実際は ・プロセス数>>>>CPUコア数 ・無理があろうと思われます

Slide 38

Slide 38 text

同時に動いているとでも?それは残像だ ・「時分割」処理 ・短い時間で区切って実行タスクを切り替える ・適度に高速に切り替えられれば人間からは同時に動いているように見える ・TSS:Time Shareing System CPU1 時間→ 端 末 ゲ | ム ブ ラ ウ ザ カ | ネ ル ゲ | ム ブ ラ ウ ザ 端 末 カ | ネ ル ゲ | ム 端 末 カ | ネ ル ゲ | ム ブ ラ ウ ザ ゲ | ム 端 末 ゲ | ム

Slide 39

Slide 39 text

スケジューリング ・プロセスには優先度がある ・音の再生とかは優先度高め ・niceコマンドで設定できる ・プロセスの動作をいいかんじに管理しないといけない ・スケジューラ(ディスパッチャ) ・スケジューラの設計で性能が全然変わってくる

Slide 40

Slide 40 text

プロセスのメモリ ・諸々のアドレス(開始アドレスとか)がまちまちだとダルい ・関数呼び出し,アドレスを指定したジャンプ (絶対ジャンプ)がやりにくい ・事前にアドレスを覚えておく or 相対ジャンプでなんとかする (位置独立コード) ・他プロセスとの競合 ・そんなんやってらんねえ!!!! ・じゃあどうするか? → 仮想メモリ

Slide 41

Slide 41 text

仮想メモリ ・プロセスから見える仮想的なメモリ空間 ・プロセスからは0x00〜の広大なメモリが全部自分のものとして扱える ・どうやって? ・アドレス変換:仮想のアドレス  → 実際のアドレス(物理アドレス) ・実際の読み書きは物理アドレスで行われる ・実際にプロセスからアクセスできるか (存在しているか,権限があるか )は別の話

Slide 42

Slide 42 text

物理アドレス・論理アドレス ・プロセスは幻想に浸ったままアドレスを指定してメモリを読み書きできる 物理アドレス:実際のアドレス 論理アドレス:幻想のアドレス ・物理アドレス ⇔ 論理アドレス が自動的に行われる ・MMU:Memory Management Unit ※x86の場合物理アドレス →リニアアドレス→論理アドレス プロセス 俺はアドレス0x00にアクセスしている ... addr=0x00 MMU addr=0x1000 メモリ ふふふ...こっちがアドレスを 書き換えてるとも知らずに ...

Slide 43

Slide 43 text

仮想メモリの種類 ・セグメンテーション:今はほとんど使われない ・「〜から〜までのメモリ空間」みたいなのを設定 ・ページング ・メモリを「ページ」という単位で切り分ける ・それぞれのページを仮想メモリ空間の一部に対応させる ・昔はバンク切り替えとかもあった (仮想記憶とは呼ばない)

Slide 44

Slide 44 text

ページング ・1ページは4KBとか ・メモリをページ毎に切る ・論理アドレス空間内に割り当て ・対応するページが存在する必要は無い ・必要になってから物理ページを確保して対応させてもいい (デマンドページング) ・対応するページが物理メモリ上にある必要は 無い

Slide 45

Slide 45 text

ページングと2次記憶 ・メモリにアクセス→存在しない!?→ページイン 存在しない!?:ページフォルト ・メモリがいっぱい or 今これいらねえな→2次記憶に突っ込む 2次記憶に突っ込む:ページアウト ・うまいことやると高速化できる ・やることはキャッシュの時と同じ ・ただしこっちの制御はOS 2次記憶 メモリ ページ ページ ページ ページ ページイン ページアウト

Slide 46

Slide 46 text

メモリマップトファイル ・”ド”の表記も多いけど”ト”の方が正しいとかなんとか (まあ元の発音からしてそう ) ・ファイルをメモリ領域のように扱える ・ファイルは使ってたらそりゃメモリの中にあるやろがい ・ファイルをプロセスのメモリ空間の中に(仮想的に)割り当てる ・*addr = ‘A’; とかできる

Slide 47

Slide 47 text

共有メモリ ・メモリを他のプロセスと共有できると  → たのしい!!!!!! ・同じページ(群)を復数のプロセスのメモリ空間内に割り当てる ・巨大なデータを復数プロセスで扱いたいときとか ・アクセス競合には気をつけよう! プロセス プロセス メモリ

Slide 48

Slide 48 text

アドレス空間の構造 ・text:プログラムそのもの.機械語 ・data:文字列,明示的に初期化される変数 (グローバル変数や関数内の static変数) ・bss:初期化の必要が無い変数. ELFなどではサイズ情報だけ(ロード時に確保される) ・heap:動的に確保する領域 ・stack:関数呼び出しで積まれていくデータの領域.関数の引数やローカル変数.

Slide 49

Slide 49 text

プロセスのメモリ確保 ・text, data:そのままメモリに載せればいい ・bss:サイズが確定している→ロード時にそれだけ確保してやればいい ・stack:仮想アドレスのめちゃくちゃ後ろから始めれば使い切ることないやろ (鼻ホジ) ・heap:システムコール呼ぶしかねえ

Slide 50

Slide 50 text

動的なメモリ確保 ・システムコール:brk/sbrk ・mmapを使うことも ・メモリを確保してプロセスの仮想メモリ空間内に割り当てる ・やったね! ・でも遅い(システムコールは大体遅い )

Slide 51

Slide 51 text

malloc() ・libc(C言語の標準ライブラリ)の関数 ・malloc()で確保,free()で開放 ・内部でbrk/sbrk/mmapを呼んで大きめのメモリ領域を確保 ・細かい領域の割り当ては malloc()が行う ・高速!ヽ(゚∀゚)メ(゚∀゚)メ(゚∀゚)ノ ・色々なアルゴリズム・実装がある (性能がめちゃくちゃ変わってくる )

Slide 52

Slide 52 text

いろいろなmalloc ・glibc malloc: ふつうこれ ・K&R malloc: いにしえ ・dlmalloc: 移植性が高い(自作OSでお世話になる) ・jemalloc: FreeBSDのlibc,マルチコア環境での性能, Facebook ・tcmalloc: Google ・mimalloc: Microsoft

Slide 53

Slide 53 text

プログラムができるまで

Slide 54

Slide 54 text

プログラムができるまで コンピュータ黎明期:機械語を書けばええ(パンチカード,コアロープメモリ, ...) いま:int main(int argc, char **argv){ printf(“hello, world!”); return 0; } ・ソースコード(人間が理解できるもの) → 機械語 ・コンパイル型言語:コンパイラで事前に機械語にしておく ・インタプリタ型言語:インタプリタが解釈しながら実行 ・C/C++はコンパイル型言語 ・C/C++コンパイラ:gcc, clang, icc, aocc, ...

Slide 55

Slide 55 text

プリプロセス ・#から始まるアレを処理する アレ:プリプロセッサディレクティブ マクロとも ・基本的に単純な(ソースコードの)書き換え ・#define -> 値に書き換えられる ・#include -> ファイルの中身がそのまま展開される ・gcc -E a.c / cpp a.c でプリプロセスだけできる ・定数/関数の定義 ← 毎回同じものを定義するのはめんどい → ヘッダとしてまとめて,プリプロセス時にそのまま展開してくれればいい → #include Linux「えっ,マクロで関数が作れるのか.使いまくったろ」  C++「templateだいすき!ヘッダに実装を書くプラよ〜」 ctags「ア゜」 C++20「C++の最新の妹です.兄が迷惑をおかけしました. moduleです.STLはまだです.」

Slide 56

Slide 56 text

コンパイル ・匠の手によりC言語のソースコードをアセンブリに変換 ・匠:コンパイラ ・アセンブリ言語:機械語と 1対1対応 BEFORE AFTER

Slide 57

Slide 57 text

アセンブル ・アセンブリ言語のソースコードをバイナリ (機械語列)に変換 ・変換するプログラム:アセンブラ ・バイナリフォーマット:ELF,COFF,a.out ・ベタなバイナリは扱いにくい これはディスアセンブルだけど ...

Slide 58

Slide 58 text

リンク ・ELFとか:機械語列以外のデータがいろいろ付いてる ・大抵ソースコードのファイルは複数 ・後でくっつけないといけない ・「のりしろ」に相当するデータ ・リンク:「のりしろ」を見てファイルをくっつける ・リンク前のELFなどのファイル(.o)をオブジェクト・ファイルとよぶ

Slide 59

Slide 59 text

ライブラリのリンク ・みんなよく使う便利関数とかをライブラリとして切り出しておく ・あとからリンクする→かんたんに過去の資産が使えてべんり!

Slide 60

Slide 60 text

ダイナミック(動的)リンク ・ライブラリをリンクするとファイルサイズが大きくなる (それはそう) ・めちゃくちゃ色々なプログラムが使うライブラリ ・同じライブラリの分だけストレージが膨れ上がっていく ・無駄すぎる ・ライブラリは1つだけ入れておいて実行時にリンクしてしまえばいいのでは!? (天才) ・リンクローダ/ローダ

Slide 61

Slide 61 text

どっちのリンク使えばええねん ・大体動的リンクでいい ・libcだって動的リンク ・Golang「せやろか」

Slide 62

Slide 62 text

ダイナミックロード ・ダイナミックリンクのようなことをプロセスが自分でやる ・API:dlopen ・インタプリタとか

Slide 63

Slide 63 text

プログラムができるまで:まとめ C ソ | ス コ | ド ア セン ブリ ソ | ス コ | ド Cコンパイラ アセンブラ オ ブ ジェ クト ファ イ ル リンカ コンパイル 元のCソースコード プ リ プ ロ セ ス アセンブル C ソ | ス コ | ド ア セン ブリ ソ | ス コ | ド Cコンパイラ アセンブラ オ ブ ジェ クト ファ イ ル コンパイル アセンブル 静的ライブラリ リンク 実 行 バ イ ナ リ フ ァ イ ル ローダ 動的リンク プ ロ セ ス イ メ | ジ 動的ライブラリ これはメモリ上

Slide 64

Slide 64 text

プログラムができるまで:まとめ C ソ | ス コ | ド ア セン ブリ ソ | ス コ | ド Cコンパイラ アセンブラ オ ブ ジェ クト ファ イ ル リンカ コンパイル 元のCソースコード プ リ プ ロ セ ス アセンブル C ソ | ス コ | ド ア セン ブリ ソ | ス コ | ド Cコンパイラ アセンブラ オ ブ ジェ クト ファ イ ル コンパイル アセンブル 静的ライブラリ リンク 実 行 バ イ ナ リ フ ァ イ ル ローダ 動的リンク プ ロ セ ス イ メ | ジ 動的ライブラリ これはメモリ上 広義での「コンパイル」

Slide 65

Slide 65 text

まとめ ・コンピュータはCPU・バス・メモリ・2次記憶・外部装置!w   GPU...?知らない子ですね ... ・記憶装置:レジスタ,キャッシュ,メモリ, SSD,HDD,... ・プログラム = 機械語の塊 ・コンピュータアーキテクチャには色々ある: x86,arm,RISC-V,PowerPC,MIPS,... ・TSS:高速に処理を切り替えてマルチタスクを実現 ・仮想メモリ:アドレス変換で仮想的なプロセス専用のメモリを扱える ・メモリ確保のAPI:システムコールで大きく確保,内部は malloc/freeで管理 ・ソースコード→アセンブリ→オブジェクトファイル→実行形式ファイル ・どうしてこの内容を1章にしてしまったんですかねぇ ...