💻

2ヶ月間で低レイヤを学ぶためにやったこと

こんにちは。来週末久しぶりに100kmマラソンを走ります。y-meguro です。

この記事は「#しがないラジオ Advent Calendar 2019」6日目の記事です。

前回、こちら の退職エントリで勉強生活を始めることを書きました。

まず低レイヤ(CPUからOS周り)から学び始めたのですが、2ヶ月間経って一区切りがついたので、ここまでにやったことをまとめてみます。

なぜ学ぼうと思ったか

私はもともとIBMでITコンサルタントをしていて、4年前からWeb系のソフトウェアエンジニアになりました。情報系の出身でもないので、低レイヤの勉強はほとんどしたことがなく、10年前に プログラムはなぜ動くのか を読んだくらい。苦手意識を持っていました。

業務上は、知らなくてもなんとかなる気がしたのですが「目の前で動いているプログラムがどのように動いているか仕組みを理解できたら楽しいな」「いま気付いていないだけで実は自分を助けてくれる場面があるかもな」と思って勉強することにしました。あと低レイヤの話とか用語が出てくる度に目を背け続けるのも嫌ですしね!

学習の基本戦略

まず勉強生活全体のスケジュールを考えて、低レイヤの勉強に使う時間は2〜3ヶ月に限定しようと決めました。

その上で自分がより効率的に学ぶために、以下の3つを基本戦略としました。

1. 下のレイヤーから順に学んでいく

これは前職の同僚からアドバイスをもらいました。また後で紹介する コンピュータシステムの理論と実装 という本でもこのアプローチが採用されています。

最も基本的な要素(回路や論理ゲート)からはじめてハードウェアの世界を学び、そこからソフトウェアの世界に入ってコンパイラやOSに進んでいくという順番で学ぶこととしました。

一番下から順々に積み上げていって、困った時に常に振り返れるよう意識しました。

2. まず作って学ぶ。その上で理論を学ぶ

これまでに馴染みのない範囲を学ぶので、まず手を動かして、試行錯誤したほうが効率がいいかなと思いました。思った通り動かなかったり、デバッグしたりしながら進めたほうが、なんだかんだ詳しくなりますよね。

ただ、手を動かしてある程度イメージを掴んだ後は、もう少し体系的に理論を学ばないと全体観が掴めないかなと思ったので、あわせて理論も学ぶように意識しました。

3. とはいえ最初に低レイヤで使われている技術の全体像をおさえる

これは自分に時間の制約があったことも大きいですが、「どの分野にどのくらい時間を使えるか」がわかっていないと安心して勉強できないなと思ったので、最初に全体像をおさえることにしました。

また全体像をおさえておくことで、各分野のつながりや、自分がいまどこにいるかも明確になるかなと思いました。最初にCPUを勉強するにしても、この後どう進んでいくかわかったほうがモチベーション高く学べますしね。

実際にやったこと

以下の6つに取り組みました。計450時間。

やったこと詳細

#カテゴリタイトル時間
1全体像コンピュータシステムの理論と実装115.6
2CPUCPUの創りかた84.4
3CPUプロセッサを支える技術28.6
4コンパイラコンパイラの構成と最適化34.5
5OS作って理解するOS70.6
6OSOperating System Concepts116.3

architecture.jpeg

お世話になりました

ここから、それぞれの本でどのような内容を学んでいったか記載していきます。

全体像

コンピュータシステムの理論と実装(115.6時間)

まず全体像を掴むために「コンピュータシステムの理論と実装」から勉強を始めました。前述の通り、ボトムアップの流れで、コンピュータシステムの説明が記載されています。

ブール論理 → ブール演算 / 順序論理 → ALU / メモリ → コンピュータアーキテクチャ → 機械語 → アセンブラ → バーチャルマシン → コンパイラ → オペレーティングシステム → 高水準言語 / アプリケーション と進んでいき、各章の最後についているプロジェクト(演習問題)を実装していくことで、手を動かしながら学ぶことができました。

HDL言語を用いた論理ゲートの実装から始まり、アセンブラやコンパイラも自分で実装することになるので、この本をやるだけで、低レイヤではどのような技術が使われているか、イメージがとても明確になりました(自分が実装したコードは こちら )。

やりきるのは大変でしたが、1冊目にこの本からはじめてよかったです。より詳細な学習メモは以下になります。

CPU

CPUの創りかた(84.4時間)

「コンピュータシステムの理論と実装」ではHDL言語でCPUを実装するのですが、せっかくだから物理的にも作ってみたいなということで、「CPUの創りかた」に取り組みました。

この本ではCPUの自作がテーマとなっていて、「TD4(とりあえず動作するだけの 4bitCPU)」の作成を通じて、基本的なCPUの動作原理がわかりやすく紹介されています。

私はブレッドボードで4bitCPUを作成しました。

電子工作については何も知らない状態からのスタートだったので、正しく部品を買うのにも苦労していたのですが、徐々に各部品の使い方を覚え、少しずつCPUができていくのはとても面白かったです。

より詳細な学習メモは以下になります。

プロセッサを支える技術(28.6時間)

「CPUの創りかた」でCPUの基本的な仕組みは学んだのですが、高性能化のためにどのような技術が使われているか、どのような構造になっているか勉強するために「プロセッサを支える技術」を読むことにしました。

この本では、命令アーキテクチャ・マイクロアーキテクチャの変遷に加え、マイクロアーキテクチャを支える技術(パイプライン実行・キャッシュなど)、仮想化サポート、マルチプロセッサなどについての説明が記載されています。

プロセッサの変遷を学んで、現代のCPUの偉大さを感じることができました。

読書メモは以下。

コンパイラ

コンパイラの構成と最適化(34.5時間)

続いてコンパイラの勉強に入ったのですが、「コンピュータシステムの理論と実装」でコンパイラをある程度しっかり実装したこともあり、理論的な部分を補足するためにこちらの本を読みました。

この本ではコンパイラを構成する各要素技術の解説に加え、最適化の手法について詳しく解説されています。

時間の関係もあり、私はすべての手法について詳細に確認できたわけではないですが、実行時間を速くするためにはまず「命令の実行回数を減らす」「より速い命令を使う」「並列度を上げる」の3つを考えればいいこと、それぞれのためにどのような手法が使われているか理解できました。

読書メモは以下。

OS

作って理解するOS(70.6時間)

OSを学ぶための1冊目として「作って理解するOS」に取り組みました。

タイトルの通り、この本では実際に動作するプログラムを作成することで、OSの各機能について学習できます(自分が実装したコードは こちら )。また実装に入る前に、コンピュータの基礎についての説明があったり、x86系PCのアーキテクチャについての説明があったりするので、実装時に困ったらその都度確認しながら進めることができました。

なかなかのボリュームなのでやりきるのは大変ですが、1つずつ進めていくことでOSが何をやっているかイメージを明確にすることができました。

読書メモは以下。

Operating System Concepts(116.3時間)

「作って理解するOS」でOSがだいたい何をやっているかイメージできたのですが、少し理解の浅いところがあったのと、まだLinuxのコードを読める状態じゃないなと思ったので、そこのギャップを埋めるために最後に「Operating System Concepts」を読みました(自分が読んだのは以下の第9版ですが、第10版も出ているようです)。

この本ではOSの概要に始まり、プロセス管理、メモリ管理、ストレージ管理、保護とセキュリティと網羅的に解説されています。また最後にケーススタディがあって、LinuxやWindowsでは実際にどのような実装となっているか学ぶことができます。

英語で800ページ以上あってなかなかのボリュームなのですが(自分の場合、演習問題を飛ばしても100時間以上かかりました)、基本的なことがわかりやすくまとめられていて、読み応えのある本でした。

手を動かさなくても、これだけわかりやすければOSの1冊目として読むのもありだったなと思いました。

読書メモは以下。

振り返り

学習前とどう変わったか

まずもともと思っていた「プログラムがどう動いているか、低レイヤでどういう技術が使われているか」ということについて、全体観を掴むことができました。また一通り学んで、手も動かしたおかげで、イメージが明確になりました。

以前だと「メモリ」「プロセス」「カーネル」等の用語に少し怖気づくところがあったのですが、今ではフラットに向き合えるかなと思います。きっと以前より低レイヤの話に付いていけるはず。

今後業務で使うかはわからないですが、ソフトウェアエンジニアとして楽しめるものが一つ増えたということはとても嬉しいです。

難しかったこと

2ヶ月間ではそこまで深く学習できなかった

どこまでやったら「深く」なのかは人によるかと思いますが、自分の場合「(教材などで)提供されているものを実装すること」はできたのですが「自分で設計から始めて実装すること」や「既存のOSやコンパイラをカスタマイズすること」はできませんでした。

逆に言うと、提供されているものであれば、CPU・アセンブラ・コンパイラ・OSと実装できたので、その点は満足しています。

自分で作ったり、実際のコードを読んだりしたら、さらに楽しめるんじゃないかなという思いもあるので、また時間が取れたらチャレンジしたいなと思います。

教材を選ぶのが難しい

ネットで調べれば良い教材の情報はたくさん出てくるのですが、その全てが自分のレベル・学習したい内容とマッチしているわけではありません。マッチしていない教材を選んでしまうと学習効率も落ちてしまうし、自分のモチベーションも下がって、勉強生活自体の存続も危うくなってしまいます。

結局いい解決方法を見つけられたわけではないのですが、「実際にその教材をやった人のアドバイスを聞く」というのはとても有効だと思います。私が取り組んだ6冊の本はどれも前職の同僚達から教えてもらったものです。とても助かりました。ありがとうございました。

私として特におすすめなのは「コンピュータシステムの理論と実装」「CPUの創りかた」「Operating System Concepts」です。よかったらどうぞ。

インプットだけだと理解が浅いことに気づきにくい

手を動かして学習している時は、バグが出たり、思ったように動かなかったりして、自分の間違いに気づくチャンスが多いのですが、本を読んでインプットしている時は、なかなか自分の理解が浅いことに気づきにくいなと思いました。本を読んでるとなんとなく理解した気になっちゃうんですよね。

ただそのまま放置してしまうともったいないので、自分の場合は怪しい用語や概念をあとで復習するようにしました。この問題に気付いたのが最後の方だったので、今回は2ヶ月経ってからすべての復習の時間をとったのですが、今後はもう少し定期的に復習タイムを設けようと思います。

終わりに

2ヶ月間あっという間に感じていましたが、こうして振り返ってみるといろいろなことを学んだなと思える2ヶ月間でした。

どの教材もけっこう時間がかかったので、まず学習時間を確保することが大変だと思いますが、自分としては意義のある楽しい時間となりました。

低レイヤを学習する方(また学び直しを考えている方)にとって、この記事が少しでも参考になれば嬉しいです。

次は3〜4ヶ月かけてアルゴリズムの学習に取り組もうと思っているので、今回の反省を活かしつつ、よりよい勉強生活を送っていこうと思います。がんばります。

Share this post