CPU のお勉強


x86 と x64 はビット数を示す
x86 → 32 ビット
x64 → 64 ビット
1 ビット → 0, 1
2 ビット → 00, 01, 10, 11
1 ビット増えると情報量は 2 倍
32 ビット → 64 ビットはおよそ xxx
Intel が 1978 から 1989 年まで MPU の型番に xxx86 としていたため
64 ビット版 x86 は x86 の互換製品を作っていた AMD が 2000 年に x86-64 で発表した
2003 に AMD64 で実装
続いて Intel が実装した Intel64 があり、AMD64 互換を総称して x64 と言う

ビット数は CPU が扱えるメモリの最大サイズ
32 ビット → 2^32 ( 4GB )
64 ビット → 2^64 ( 128TB )
32 bit の歴史
- Intel が IA-32 を作った
- Intel が IA-64 を作った
- IA-64 は IA-32 との互換性を持たせなかった
- AMD が IA-32 互換のある x86-64 を発表した ( AMD64 )
x86 とは
Intel 8086 およびその後方互換を持つ MPU の命令セットアーキテクチャの総称
8086 ( 16 bit ), 80386 ( 32 bit, のちに IA-32 と命名 ), x64 ( 64 bit ) など
ただよく x86 or x86_64 と書かれたりするため、x86 = 32 bit として一般には使われる
x64 とは
x64 または x86-64 とは、x86 を 64 bit に拡張した命令セットアーキテクチャ
AMD の AMD64, Intel の Intel 64 などを含む、各社の AMD64 互換命令セットの総称
x86 との互換があるので広義では x86 に x64 を含む

命令セットアーキテクチャとは
Instruction SEt Architecture ( ISA ) といい、CPU を動かすために必要になる CPU が理解できる命令のセットのこと
x86-64 や x64 や AMD64 は ISA の名前
x86-64 もしくは x64 は、x86 アーキテクチャを 64bit に拡張したものの総称で、AMD64 や Intel64 を含む
AMD64 は、AMD が発表した x86 アーキテクチャを 64bit に拡張したもの、Intel 64 とはほぼ差はない
Intel64 は、Intel が発表した x86 アーキテクチャを 64bit に拡張したもの、AMD 64 とはほぼ差はない
AArch64 ( ARM64 )
スマホやタブレットなどで多く使われる ARM アーキテクチャを 64bit に拡張したもの

bit の違いはメモリー容量や HDD 容量に影響する
32bit: 2GB ~ 4GB
64bit: 8GB ~
macOS Mojave ( 10.14 ) を最後に 32bit アプリの対応は終了している
macOS Catalina ( 10.16 ) 以降は 64bit アプリのみサポートされる
macOS Big Sur ( 11 ) は Intel ベースの Mac に加えて Apple シリコンを搭載した Mac でも動作する

M1 チップは、iOS デバイス向けの Apple シリコンを Mac 向けにアレンジしたもの
CPU や GPU や Neural Engine などを1つのチップに組み込んだもの
iPhone や iPad のアプリをそのまま M1 Mac で動かすことができる

M1 が省電力で公正なのは統合型システムチップのアーキテクチャだから
異なる目的の処理回路が同じメモリを共有して協調動作するアーキテクチャだった
CPU と GPU や、機械学習モデルの推論アルゴリズム専用プロセッサ ( Neural Engine ) を並列動作させるときに真価を発揮する
GPU の処理結果をビデオメモリにロードして、CPU で処理してメモリに書き戻す、ということは効率が悪い
あるデータを必要に応じて CPU / GPU / Neural Engine でアクセスできる
逆にメモリを共有しなければいけないので、1パッケージにどこまでメモリを乗せられるかが課題になる
今後の上位モデルと値段がどうなるのだろうか
あとは I/O インターフェースもチップに統合しているので、Thunderbolt 2/USB 4 のポートを 2 つまでしかサポートできない

ARM は x86 とかと退避するもの
ARM は ISA の1つ
x86 は高性能、ARM は安価で低消費電力
PC は Intel が多かったが、組み込みで活躍してた ARM も増えてきた
スマホとかタブレットは ARM が多い
ARM64 と AArch64 というのがあるが、もともと別だったが公式にマージされて AArch64 になる

ARM アーキテクチャ
ARM 社によるもの
Reduced Instruction Set Computer ( RISC ) とは ISA の1つ
命令の種類を減らし、回路を単純化して演算速度の向上を図る
従来のアーキテクチャは対義語として Complex Instruction Set Computer ( CISC ) と呼ばれるようになった
ARM アーキテクチャは携帯電話や携帯端末で使われている
Android や iPhone ではほぼ ARM が使われている
Intel の ATOM プロセッサが対抗していたが撤退した
x86 アーキテクチャ
Intel 社の 32 bit アーキテクチャ
x64 ( もしくは x86-64 ) は Intel の 64 bit アーキテクチャ
x86 も x86-64 も CISC アーキテクチャ
パソコンではほぼこれらが独占している

ARM64 は Apple によって 64 bit iOS 用に作られたもので、最近公開された
AArch64 は機能は足りていた
ARM64 はパフォーマンスが良かったが機能が若干足りなかった
チューニングより機能追加の方が楽なので、ARM64 をベースに AArch64 をマージして、それを新たな AArch64 にすることになった

Finder でアプリの情報を確認すると Universal や Intel と書いてある
Universal アプリは x86-64 バイナリと ARM64 バイナリの両方を含む
Intel は x86-64 バイナリのみを含む
Universal アプリには Rosetta を使用して開くというチェックボックスがあり、そうすると ARM64 バイナリではなく x86_64 バイナリが使われる
Rosetta 2 は /Library/Apple/usr/libexec/oah
にあり、カーネルが必要だと判断すると自動で呼び出される

Rosetta は PowerPC から Intel へ移行するときに活躍したバイナリトランスコードシステム
Rosetta は Apple の技術

Apple シリコンは、Apple Inc. が ARM アーキテクチャを使用して設計した Software on a Chip ( SoC ) および System in Package ( SiP ) の総称
iPhone, iPad, Apple Watch などで使われている
Apple M1 プロセッサを使用した ARM ベースの Mac になった
SoC, SiP どちらも半導体チップののことである
SoC は1つの半導体チップの上に必要とされる全ての機能を集積する
SiP は複数の LSI チップを1パッケージにまとめる
コスト、サイズ、配線や消費電力などのメリデメがあるが、今はそこは対象外とする
Apple シリコンには次のシリーズがある
- A シリーズ ( iPhone 8 )
- S シリーズ ( Apple Watch )
- T シリーズ ( MacBook Pro with Touch Bar )
- W シリーズ ( AirPods )
- H シリーズ ( AirPods Pro )
- U シリーズ ( iPhone 11 )
- M シリーズ ( Mac )

- Rosetta 2 があれば子プロセスのアーキテクチャは混在できる
- Homebrew は
/usr/local
から/opt/homebrew
に変わる - Homebrew で ARM64 のパッケージを入れるには、バイナリがないのでソースからビルドすることになる
- x86_64 のシェルから ARM64 のパッケージはインストールできない
- 逆も同様

Homebrew でパッケージをインストールするときは、シェルのアーキテクチャに依存して決まる
で、ユニバーサルバイナリのコマンドは、ターミナルのアーキテクチャに応じて決まる
> lipo -archs /bin/bash
x86_64 arm64e
↑ デフォルトのコマンドはユニバーサルバイナリ
> uname -smp
Darwin x86_64 i386
> bash
$ uname -smp
Darwin x86_64 i386
uname -smp
Darwin arm64 arm
bash
$ uname -smp
Darwin arm64 arm
つまり arm のバイナリを入れたければ arm のシェルで brew
を叩く
arm のシェルを使うために arm のターミナルを使う

アーキテクチャに応じて brew
自体のインストール方法とインストール先が違う
x86_64 での brew
> which brew
/usr/local/bin/brew
> brew install zsh
> which zsh
/usr/local/bin/zsh
/usr/local/bin
に入ったものはユニバーサルバイナリではない
> lipo -archs /usr/local/bin/zsh develop
x86_64
arm64 での brew
which brew
/opt/homebrew/bin/brew
brew install zsh
which zsh
/opt/homebrew/bin/zsh
同じく opt/homebrew/bin
に入ったものはユニバーサルバイナリではない
lipo -archs /opt/homebrew/bin/zsh
arm64

Rosseta 2 On ターミナル → x86_64 は x86_64
> uname -smp
Darwin x86_64 i386
> /usr/local/bin/zsh
> uname -smp
Darwin x86_64 i386
Rosseta 2 On ターミナル → arm64 は x86_64 ( Rosseta 2 で変換されている? )
> uname -smp
Darwin x86_64 i386
> /opt/homebrew/bin/zsh
> uname -smp
Darwin x86_64 i386

Rosseta 2 Off ターミナル → x86_64 は x86_64
uname -smp
Darwin arm64 arm
/usr/local/bin/zsh
> uname -smp
Darwin x86_64 i386
Rosseta 2 Off ターミナル → arm64 は arm64
uname -smp
Darwin arm64 arm
/opt/homebrew/bin/zsh
uname -smp
Darwin arm64 arm

Docker のイメージはマルチアーキテクチャと言う
- 同じイメージで複数の OS や CPU アーキテクチャをサポートできる
- ホストのアーキテクチャに応じてイメージが選択される
それぞれのターミナルで pull してみる
x86_64 の Mac
> docker pull alpine:3.14.0
> docker image ls | grep alpine
REPOSITORY TAG IMAGE ID CREATED SIZE
alpine 3.14.0 b0e47758dc53 2 weeks ago 5.33MB
arm64 の Mac
docker pull alpine:3.14.0
docker image ls | grep alpine
REPOSITORY TAG IMAGE ID CREATED SIZE
alpine 3.14.0 b0e47758dc53 2 weeks ago 5.33MB
イメージの ID は同じ
なのにコンテナのアーキテクチャは違う
/ # uname -spm
Linux aarch64 unknown todo
docker run -it alpine:3.14.0 /bin/sh
/ # uname -spm
Linux aarch64 unknown
どっちのイメージが pull できたかは、image id で inspect
すれば確認できる
> docker inspect b0e47758dc53 | jq '.[] | {Id: .Id, RepoTags: .RepoTags, RepoDigest: .RepoDigests, Architecture: .Architecture}'
{
"Id": "sha256:b0e47758dc53e7391c7abf92fd56fd959bf37fb74574feba3d557b4182d15801",
"RepoTags": [
"alpine:3.14.0"
],
"RepoDigest": [
"alpine@sha256:234cb88d3020898631af0ccbbcca9a66ae7306ecd30c9720690858c1b007d2a0"
],
"Architecture": "arm64"
}

arm64 の Mac から x86_64 を指定することもできる
> docker pull alpine:3.14.0 --platform linux/x86_64
> docker inspect d4ff818577bc | jq '.[] | {Id: .Id, RepoTags: .RepoTags, RepoDigest: .RepoDigests, Architecture: .Architecture}'
{
"Id": "sha256:d4ff818577bc193b309b355b02ebc9220427090057b54a59e73b79bdfe139b83",
"RepoTags": [
"alpine:3.14.0"
],
"RepoDigest": [
"alpine@sha256:234cb88d3020898631af0ccbbcca9a66ae7306ecd30c9720690858c1b007d2a0"
],
"Architecture": "amd64"
}
> docker run -it alpine:3.14.0 /bin/sh
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
/ # uname -spm
Linux x86_64 unknown
run の時も指定すると警告は出ない
> docker image ls | grep alpine
alpine 3.14.0 d4ff818577bc 2 weeks ago 5.6MB
> docker run -it --platform linux/x86_64 alpine:3.14.0 /bin/sh
/ # uname -spm
Linux x86_64 unknown
アーキテクチャを変えるとローカルにないと言って取り直す
> docker run -it --platform linux/arm64 alpine:3.14.0 /bin/sh
Unable to find image 'alpine:3.14.0' locally
/ # uname -smp
Linux aarch64 unknown
増える
> docker image ls | grep alpine
alpine <none> d4ff818577bc 2 weeks ago 5.6MB
alpine 3.14.0 b0e47758dc53 2 weeks ago 5.33MB

コンテナのアーキテクチャがどうなるかと、その結果やりたいことができるかはまた別
haskell を arm Mac で適当に pull すると、なんか「ねーよ」って言われる
> docker pull haskell:latest
latest: Pulling from library/haskell
no matching manifest for linux/arm64/v8 in the manifest list entries
指定して取りに行く
> docker pull haskell:latest --platform linux/x86_64
> docker image ls | grep haskell
haskell latest 02006a905c71 12 days ago 1.5GB
ちゃんと amd64 になってる
> docker inspect 02006a905c71 | jq '.[] | {Id: .Id, RepoTags: .RepoTags, RepoDigest: .RepoDigests, Architecture: .Architecture}'
{
"Id": "sha256:02006a905c714fa82e87f87670b0bc9c897fd95a47e53cfc740cda6e87610191",
"RepoTags": [
"haskell:latest"
],
"RepoDigest": [
"haskell@sha256:6f4ff6858ac90fc73f7f6e39239df1eef1bcfa4cba240531674d2b6754d3aea6"
],
"Architecture": "amd64"
}
が、stack
が使えない
> docker run -it haskell:latest bash
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
root@d1685461b293:/# uname -smp
Linux x86_64 unknown
root@d1685461b293:/# stack -h
Killed
haskell には arm64 対応のイメージがビルドされていない
> DOCKER_CLI_EXPERIMENTAL=enabled; docker manifest inspect haskell:latest | jq -r '.manifests[].platform | .os + "/" + .architecture' | sort
linux/amd64
/Users/ryo
> DOCKER_CLI_EXPERIMENTAL=enabled; docker manifest inspect alpine:3.14.0 | jq -r '.manifests[].platform | .os + "/" + .architecture' | sort
linux/386
linux/amd64
linux/arm
linux/arm
linux/arm64
linux/ppc64le
linux/s390x

haskell は結局 x86_64 の brew で入れることにした
arm64 の brew
/opt/homebrew/bin/brew install haskell-stack
/opt/homebrew/bin/stack ghci
zsh: segmentation fault /opt/homebrew/bin/stack ghci
> brew reinstall haskell-stack
> stack ghci develop
ghci> 1 + 1
2

vim のコマンドラインについて
子プロセスは親と同じになるだけ

todo
CPU と ISA の違いを整理

ユーザ → ターミナル ( エミュレータ ) → シェル → カーネル

arch について確認

- 参考をやっぱ載せる
- 長いので結論と強調表示を適宜使う
- この章の操作は xxx ですと冒頭に警告する
- テキストと画像とコードブロックの順番を x86_64 → ARM64 の順に統一する
-
コマンド名はハイライトする (
zsh
) - 標準? ARM64?
- 章タイトル
- インデントプレビュー

vim のコマンドラインについて
子プロセスは親と同じになるだけ
:W
が動かない