コース一覧へ戻る
AI031 Professional

コンピュータシステム:プログラマーの視点から(グローバル版)

コンピュータシステムがプログラムを実行し、情報を格納する仕組みについての包括的な解説。このコースでは、高レベルなプログラミングと下位のハードウェアの間に存在するギャップを埋め、マシンレベルの表現、プロセッサアーキテクチャ、メモリ階層、並行プログラミングについて学びます。

5.0
36.0h
955 受講者
0 いいね
人工知能

コース概要

📚 コンテンツ概要

コンピュータシステムがプログラムを実行し、情報を格納する仕組みについての包括的な深掘り。このコースでは、高レベルなプログラミングと下位のハードウェアとの間のギャップを埋め、マシンレベルでの表現、プロセッサアーキテクチャ、メモリ階層、並行プログラミングについて学びます。

ハードウェアとソフトウェアのインターフェースを理解することで、システムプログラミングの技術を習得しよう。

著者: Randal E. Bryant, David R. O'Hallaron

謝辞: カーネギー・メロン大学の15-213コースの学生および教員による支援。Manasa S. および Mohit Tahiliani からの貢献も含まれます。

🎯 学習目標

  1. 情報がビットとシステム内の文脈を使ってどのように表現されるかを特定する。
  2. ソースコードから実行可能ファイルに至るまでのコンパイルシステムの4段階を追跡する。
  3. ハードウェアの構成とストレージデバイスの階層的性質を説明する。
  4. 10進数、2進数、16進数の表記法の相互変換を行い、マシンレベルのアドレス指定(エンディアン)を説明する。
  5. C言語におけるビット演算および論理演算を行い、算術シフトの結果を予測する。
  6. 整数符号化を分析し、オーバーフローの脆弱性やキャストエラーを特定する。
  7. 分析する:C言語の構造(ループ、分岐、手続き)とx86-64アセンブリ命令との対応関係。
  8. 分解する:実行時スタックを解明し、パラメータの渡し方、ローカル変数の保存方法、再帰呼び出しの管理方法を説明する。
  9. 評価する:異種データ構造のメモリレイアウトを評価し、アライメント規則を適用して総合的なストレージ要件を計算する。
  10. Y86-64プログラマー可視状態を定義し、命令をバイト列にエンコード・デコードする。

🔹 レッスン1:コンピュータシステムの概観

概要: このレッスンでは、コンピュータシステムが情報をどのように表現し、プログラムを翻訳し、複雑なハードウェアとソフトウェアの相互作用を通じて命令を実行するかについて、包括的な概観を提供します。ソースコードから実行までの一連の流れ、プロセッサとメモリのギャップを克服するためのメモリ階層の重要な役割、オペレーティングシステムが提供する抽象化、そしてシステム性能と並列処理を規定する数学的法則について探求します。

学習成果:

  • 情報がビットとシステム内の文脈を使ってどのように表現されるかを特定する。
  • ソースコードから実行可能ファイルに至るまでのコンパイルシステムの4段階を追跡する。
  • ハードウェアの構成とストレージデバイスの階層的性質を説明する。

🔹 レッスン2:情報の表現と操作

概要: このレッスンでは、デジタルコンピュータがビットレベルで情報をどのように表現し操作するかを探ります。16進数表記やマシンレベルのワードサイズから始まり、整数(符号なし、2の補数)および浮動小数点数(IEEE 754)の複雑な符号化までカバーします。学生は、コンピュータ算術の数学的性質を分析し、オーバーフローのセキュリティ影響や有限精度システムにおける丸めのニュアンスについて学びます。

学習成果:

  • 10進数、2進数、16進数の表記法の相互変換を行い、マシンレベルのアドレス指定(エンディアン)を説明する。
  • C言語でビットレベルおよび論理演算を行い、算術シフトの結果を予測する。
  • 整数符号化を分析し、潜在的なオーバーフローやキャストエラーを特定する。

🔹 レッスン3:プログラムのマシンレベル表現

概要: このレッスンでは、高レベルなCプログラムがどのようにx86-64マシンコードに変換されるかについての包括的な深掘りを行います。プロセッサの基本アーキテクチャ(レジスタとスタック)、制御フロー(条件分岐、ループ、スイッチ)の実装、手続き呼び出しと再帰の仕組み、配列、構造体、共用体といった複雑なデータ構造のマシンレベル表現について学びます。最後に、バッファオーバーフロー解析によるシステムセキュリティの確保と、浮動小数点演算に特化した命令についても扱います。

学習成果:

  • 分析する:C言語の構造(ループ、分岐、手続き)とx86-64アセンブリ命令との対応関係。
  • 分解する:実行時スタックを解明し、パラメータの渡し方、ローカル変数の保存方法、再帰呼び出しの管理方法を説明する。
  • 評価する:異種データ構造のメモリレイアウトを評価し、アライメント規則を適用して総合的なストレージ要件を計算する。

🔹 レッスン4:プロセッサアーキテクチャ

概要: このレッスンでは、プロセッサの基本的なアーキテクチャについて探求し、順次実装(SEQ)から高性能パイプライン実装(PIPE)への移行を、Y86-64命令セットアーキテクチャ(ISA)を使用して検討します。命令のエンコード方法、各段階(フェッチ、デコード、実行、メモリ、書き戻し)での処理、および制御論理、ステール、フォワーディングを用いたハードウェアハザードの管理を通じて、スループットを最大化する方法を分析します。

学習成果:

  • Y86-64プログラマー可視状態を定義し、命令をバイト列にエンコード・デコードする。
  • HCL(ハードウェア制御言語)を用いて組み合わせ回路および逐次回路のハードウェア制御論理を実装する。
  • 順次プロセッサの6段階における命令の流れをトレースし、クロックの影響を特定する。

🔹 レッスン5:プログラムパフォーマンスの最適化

概要: このレッスンでは、高レベルコード、最適化コンパイラ、現代のマイクロプロセッサアーキテクチャとの相互作用を理解することによって、プログラムパフォーマンスを向上させる体系的なアプローチを探ります。メモリ別名化などの「最適化ブロッカー」を識別し、ループアンロールや再結合といった低レベル変換を適用し、GPROFのようなプロファイリングツールを活用してパフォーマンスのボトルネックを効果的にターゲット化する方法を学びます。

学習成果:

  • メモリ別名化や手続き呼び出しのオーバーヘッドなどの最適化ブロッカーを識別し、緩和する。
  • エレメントあたりサイクル数(CPE)という指標を使ってプログラムのパフォーマンスを定量的に評価する。
  • ループアンロール、複数の蓄積器、再結合変換を適用し、命令レベル並列性を活用する。

🔹 レッスン6:メモリ階層

概要: このレッスンでは、メモリ階層の構造的かつ機能的な設計について探求し、速度、コスト、容量の間のトレードオフに焦点を当てます。現代のシステムを支える技術—SRAM、DRAM、ディスク、SSD—について詳細に説明し、局所性の原則(時間的局所性、空間的局所性)が小さな高速キャッシュメモリがプログラムパフォーマンスを顕著に向上させることを説明します。学生は、キャッシュマッピング(直接マッピング、セットアソシエイティブ、フルアソシエイティブ)を分析し、ループの再順序付けやブロッキングといった最適化技術を用いてキャッシュに優しいコードを書く方法を学びます。

学習成果:

  • SRAM、DRAM、ROM、フラッシュメモリの技術の違いを区別し、階層における役割を説明する。
  • 構造と動作要素に基づいたディスクのストレージ容量とアクセス時間の計算を行う。
  • メモリアドレスを分析し、異なるマッピング方式におけるキャッシュセットインデックス、タグ、ブロックオフセットを決定する。

🔹 レッスン7:リンキング

概要: このレッスンでは、コードとデータを集約して1つのファイルにまとめ、メモリにロードして実行できるようにする、重要なシステムレベルのプロセスであるリンクについて探ります。ソースコードから実行可能バイナリへの移行を理解し、リンカーがシンボル参照を解決し、リロケーションを通じてセクションをマージし、静的および動的ライブラリを管理する方法を学びます。最後に、現代の共有ライブラリで使われる高度な技術として、ライブラリのインタポレーションと位置独立コード(PIC)について学びます。

学習成果:

  • コンパイラドライバを通じたソースファイルの変換から最終的な実行可能ファイルまでの流れを追跡する。
  • ELFオブジェクトファイルを分析し、シンボルタイプとセクション構成を特定する。
  • シンボル解決ルールを適用して、重複名やリンク時の依存関係を管理する。

🔹 レッスン8:例外的な制御フロー

概要: このレッスンでは、コンピュータシステムがシステム状態の変化に反応する仕組みである例外的な制御フロー(ECF)について探ります。ハードウェアによってトリガーされる例外、オペレーティングシステムレベルのコンテキストスイッチプロセス制御(fork、wait、execve)、ソフトウェアレベルのシグナル非ローカルジャンプなど、システムのあらゆるレベルで実装されていることを検討します。学生は並行処理の管理、システムエラーの処理、信頼性の高いシグナル安全なコードの書き方を学びます。

学習成果:

  • ハードウェアレベルの4種類の例外(割込み、トラップ、故障、中止)の違いとその処理メカニズムを区別する。
  • fork(プロセス作成)、waitpid(収集)、execve(実行)といったシステムコールを用いてプロセスライフサイクルを管理する。
  • 並行性、非キューイングシグナル、非同期シグナル安全性を考慮した安全なシグナルハンドラを実装する。

🔹 レッスン9:仮想メモリ

概要: このレッスンでは、仮想メモリ(VM)という基本的な抽象化について探ります。これは各プロセスに大きな連続したプライベートアドレス空間を提供します。その主な3つの役割について学びます:DRAM上の効率的なキャッシュ手段、メモリ管理と保護のメカニズム、メモリマッピングの基盤。さらに、アドレス変換(TLB)、動的メモリ割り当て(ヒープ管理)、自動ガベージコレクションの原理について深く掘り下げ、Cプログラミングにおける重大なメモリ関連の落とし穴についても述べます。

学習成果:

  • 物理アドレスと仮想アドレスの違いを区別し、メモリ管理ユニット(MMU)の役割を説明する。
  • ページテーブルとトランレーションルックアサイドバッファ(TLB)を用いて仮想アドレスから物理アドレスへの変換を行う。
  • 動的メモリ割り当て戦略(暗黙的/明示的リスト、コールセーシング)を分析し、実装する。

🔹 レッスン10:システムレベルのI/O

概要: このレッスンでは、Linuxオペレーティングシステムとアプリケーションプログラムとの間の基本的な入出力インターフェースについて探ります。基本的なUnix I/Oシステムコール、Linuxファイルシステムで遭遇するさまざまなファイルタイプ、それらを管理するためにカーネルが使用するデータ構造について学びます。さらに、"ショートカウント"に対応するための堅牢なI/O(RIO)パッケージを導入し、ネットワークプログラミングなどの異なるプログラミング文脈において、標準I/OとシステムレベルI/Oの選択基準を提示します。

学習成果:

  • 実装する:Unix I/Oインターフェース(openclosereadwrite)を使って基本的なファイル操作を行う。
  • 区別する:通常のファイル、ディレクトリ、リンクの違いを把握し、statを使ってファイルのメタデータを照会する。
  • 利用する:RIOパッケージを用いて堅牢なバッファ付きおよびバッファなしI/O操作を行う。

🔹 レッスン11:ネットワークプログラミング

概要: このレッスンでは、クライアントサーバー型プログラミングモデルとグローバルIPインターネットを中心とした、ネットワークベースのアプリケーションの基本的なアーキテクチャについて探ります。システムレベルのネットワーク通信の主要なAPIであるソケットインターフェースを理解し、静的ファイルと動的コンテンツを提供できる機能的なウェブサーバー(TINY)を実装するまで進みます。動的コンテンツは共通ゲートウェイインターフェース(CGI)を通じて提供されます。

学習成果:

  • クライアントサーバーモデルのリクエスト-レスポンスサイクルと、グローバルIPインターネットのハードウェア/ソフトウェア階層を理解する。
  • getaddrinfo などのプロトコル非依存関数を用いて、IPアドレス、ドメイン名、ソケット構造体を操作・変換する。
  • ロバストなイテレーティブウェブサーバーと、プロセス制御およびI/Oリダイレクションを利用して動的コンテンツを提供するCGIプログラムを実装する。

🔹 レッスン12:並行プログラミング

概要: このレッスンでは、並行処理の基本モデルであるプロセス、I/Oマルチプレクシング、スレッドについて探ります。競合状態を解消するためのセマフォを使った同期の深い掘り下げ、生産者-消費者やプリスレッドサーバーといった一般的なアーキテクチャパターン、並列性能を評価するための指標について学びます。最後に、スレッドセーフ、再入可能、デッドロック防止といった重要な信頼性問題について取り上げます。

学習成果:

  • プロセスベース、I/Oマルチプレクシング、スレッドベースの並行モデルの違いを区別する。
  • セマフォ操作(PおよびV)を適用し、排他制御を確保し、同期パターンを解決する。
  • スケーリング法に応じたスピードアップや効率といった並列性能指標を計算する。