【知らなきゃ損】Linuxの父がC言語を使い続ける合理的な理由
はじめに
どうも、私立YouTube高専校長です。
あなたは、C言語を学習した経験はあるでしょうか。 高専や大学でプログラミングの授業を受けたことのある方は、C言語に触れたことがある人も多いかもしれません。 しかし、もしかしたら、その時、こう思ったのではないでしょうか? いまどき、こんな古い言語が使われてるのか?勉強するする意味あるのか??無駄なんじゃないのか?と。
C言語は50年以上前に開発された言語で、とても古いので、時代遅れと錯覚しがちですが、今でもバリバリ現役の素晴らしい言語です。 民間企業の製品開発でも、C言語が使われることはいまだに多く、おそらく10年後も20年後も使われ続けている言語でしょう。 しかし、Go、Java、Ruby、TypeScript、Pythonのように新しく優れた言語が次々開発される中で、 なぜ、このような古い言語が今でも、そして、これからも使われ続けると言えるのでしょうか?
それには、明確且つ合理的な理由があります。 身近な例でいうと、世界中のサーバーやスマートフォンで使用されている、LinuxというオープンソースのOSは、今でもC言語で開発されています。 Linuxは、Linusさんを主体に、世界中のスーパーエンジニアが貢献している、世界最大規模のオープンソースです。
このような、極めて洗練されたソフトウェアの一つである、Linuxにおいて、C言語が使われ続ける理由について、Linuxの創設者であるLinusさんが2012年の講演会でコメントしていたので、 今日はそれをご紹介したいと思います。
また今回ご紹介する情報以外にも、こういった有益なコンピュータ関連の技術情報を発信しているので、 そういった動画を見逃したくない方は、今のうちにチャンネル登録しておいて貰えればと思います。
それでは、本編どうぞ
Linusさんのコメント
早速ですが、Linuxの開発において、なぜ、今だにC言語が使われ続けるのでしょうか? Linusさんのコメントを見ていきましょう。 こちらは、2012年の講演会において、Linux開発において、C言語以外の言語の採用を検討しているかどうかという質問があり、Linusさんがそれについて答えています。
内容が難しくて、分かりにくいと思うので、超意訳してご紹介します。元動画に、興味のある方は、リンクを動画詳細欄のブログに貼っているので、是非見てみてください。 Linusさんはこのように答えています。
私がそもそもOS開発に興味を持った理由は、ハードウェアをソフトウェアの観点から干渉することに関心があるからです。 そして、その目的において、C言語に近しいものすらありません。 C言語は、コンピュータの原理に沿って、自然に書くことができます。 つまり、C言語は、ソースコードがコンパイラによって、どのようなアセンブリに変換され、どのようにハードウェアによって実行されるかが、想像できます。それが重要です。 例えば、単一命令レベルやキャッシュレベルでの最適化をしようとすると、Cでしかできません。 このような、ミクロな最適化はすべきではないと言う人もいますが、このようなミクロな最適化が好きな人は、ミクロな最適化をすべきです。もちろん、マクロなアルゴリズムの最適化はしたうえでね。笑 おかげで、Linuxでは他の誰よりも早く検索できます。そして、それは1000個のCPUを使用しても、並列に競合なく処理が可能です。これは、実際に手掛けるまでは分かりませんが、すごいことなのです。
ということです。 これには、私も、思わず、頷きながら聞いてしまいました。 しかし、これだけだといくつか専門的な用語が使われているので、分かりにくいかと思われますので、もう少し背景を含めて、分かりやすく解説したいと思います。
コメント解説
まず、OSというのは、そもそもどんなソフトウェアで何が求められるのか振り返ってみましょう。 OSとは、ハードウェアやソフトウェアの資源を管理するためのソフトウェアで、サーバーやスマートフォンのような複雑なコンピュータシステムでは必須のソフトウェアです。あなたが今使用している、スマートフォンやタブレットやパソコンも、OSなしでは成立しません。
OSは資源を管理するために、プロセッサーやメモリやストレージやUSBやマウスなどのハードウェアを直接制御する必要があります。 したがって、OS開発には、ハードウェアレベルの制御や最適化というのが必須になります。 Linusさんは、この目的において、Cに近しいものすらないと言っています。
実際に、CとPythonで比較して、Pythonが、ハードウェアの制御や最適化において、不適格な理由を解説したいと思います。
例えば、変数の代入を比べてみましょう。文法上は同じような、等号を使用した変数の代入でも、その意味がC言語とPythonでは、まったく違います。 まず、C言語で、簡単な代入文をコンパイルしてみましょう。
C言語だと、プログラムが、実際にハードウェアによってどのように実行されるのか明確です。 アセンブリを見ると、reusltは自動変数なので、1をスタックにコピーしています。スタックは、DRAMにあるので、物理的になにが起きているかというと、この赤線で示した、命令で、DRAMに命令に組み込まれた定数である1を書き込んでいるという事が分かります。
このように、C言語だと、ソースコードやアセンブリを見て、プロセッサーが具体的にどのようにそれを実行するかを想像したり、確認することができます。
さらに、今は、DRAM上のアドレスにMOV命令で、1を書き込んでいましたが、実は、ハードウェアの制御というのは、メモリマップドI/Oといって、メモリ空間のなかで、特定の範囲のアドレスに値を読み書きすと、そのアドレスが周辺機器のハードウェアを制御するレジスタに対応していて、プロセッサによるメモリアクセスによってソフトウェアからハードウェアに干渉することができます。C言語は、このメモリマップドI/Oを使用することによって、様々なハードウェを制御する事ができます。
一方で、Pythonではどうでしょうか? 同じように、代入文を見てみましょう。 Pythonでは、ソースコードを動的に解析しながら、実行エンジンが実行していくので、これがハードウェアによって、物理的にどのように実行されているのかを追いかけることは極めて困難です。不可能とまでは言いませんが、できたとしても、それはPythonの実行エンジンの実装に依存するので、それをソースコードから制御することは効率的ではありません。
C言語では扱えたメモリマップドI/Oも、Pythonはハードウェアを高度に抽象化しており、メモリ空間という概念がないので、メモリマップドI/Oを使うことができないので、ハードウェアを制御することができません。 しかし、OSは、ハードウェアを制御するためのソフトウェアなので、PythonでOS開発は不適格なのです。
次に、Linusさんが言及していた、最適化という観点でみてみましょう。
先程、Linusさんのコメントで、キャッシュという言葉が出てきました。キャッシュとは、メモリの内容に高速でアクセスするための、一時的な保管場所のようなハードウェアです。 このキャッシュの存在によって、どう変わるというと、例えば、C言語では、二次元配列に連続でアクセスするときに、どの次元の方向に連続でアクセスするかによって、アクセスの速さが変わります。 これは、例えば、今見えている、1024x1024の大きさのmatrixという配列がメモリ上に展開されると、メモリ空間上で横方向に見て、連続配置されているため、横方向にアクセスすると、ほぼ確実に、キャッシュヒットする一方で、縦方向で連続にアクセスすると、キャッシュミスする可能性が高いため、アクセスが遅くなるのです。 したがって、C言語だと、二次元配列をつかった処理を行うときは、結果的に同じ処理をするとしても、アクセスの順番を変えると、処理を高速化することが出来ます。これが、キャッシュレベルの最適化です。
この図でいうと、例えばキャッシュサイズが4KBだった場合、横方向は、全てキャッシュに乗るので、横方向で連続でアクセスすると、高速でアクセスできます。一方で、縦方向だと毎回、キャッシュミスが発生するので、アクセスが非常に遅くなるというような事があります。厳密性に欠ける説明なのですが、いずれにせよ、C言語だと、このように物理的配置が明確なので、キャッシュを意識した最適化が可能です。
一方で、Pythonは、二次元リストがどのようにメモリに配置されているのか、そもそもどういうサイズのどんなデータなのかというのが抽象化されているので、キャッシュレベルでの最適化をしようにも、しようがありません。 二次元リストの物理的な配置は、Pythonの実行エンジンがリストをどう実装しているかに依存するので、ソースコードによって、キャッシュレベルでの最適化は行うことはできないのです。 このような理由から、Linusさんは、OS開発ではC言語が、現在でもなお、最良の選択肢として考えています。
またOS開発だけでなく、ハードウェアを制御する必要のある、組み込みソフトでも、同じような理由で、C言語が使用されます。組み込みソフトとは、ロボットや車のような機械や家電を制御するためのソフトウェアです。また、処理速度が求められるような、ライブラリやミドルウェアでも、C言語は良く使用されています。
これが、C言語が、50年たった今でも、世界中で使用されている理由で 今後数十年も使われるであろう理由になります。ご納得いただけたでしょうか??
しかし、実はこの講演会から、10年経過した今、黒船が来航しています。
Rustの到来
それが、Rustです。Rustは近年、C/C++言語に置き換わる言語として、注目され、Linux 6.1において、初めてマージされました。 まだ、言語仕様も言語拡張も安定していないようなので、まだ少し先の話ではありますが、近い将来、OS開発でも、ドライバーのような、比較的上位のソフトウェアから、Rustが使用されていくようになるんじゃないかと思います。
私も、実は、まだ勉強してないので、殆ど何も知らないのですが、これから徐々に勉強していきたいと思います。
まとめ
コンピュータ関連の技術の進歩は非常に激しいですが、コンピュータの基礎的な原理は50年前とほとんど変わっていません。 逆に言えば、コンピュータの基礎的な原理さえ理解していれば、見かけ上の技術が進化しても、すぐにキャッチアップすることができます。
その分学習コストも高いですが、安心してください。私のチャンネルでは、コンピュータの基礎的な原理を理解するために必要な、知識を分かりやすく解説しています。 この動画を見ているあなたは、進歩が著しいコンピュータ技術に追従できるようになるかと、不安になる必要はまったくありません。
なぜかというと、こんなC言語が使われる理由を説明するだけの動画を、10分も聞ける、あなたはポテンシャルの塊だからです。 自信を持って好奇心のままに勉強してください。自信を無くして、投げ出してしまう人が殆どです。 5年後には、天地の差が開いています。
もし、まだなにか分からない事があったら、ぜひコメントで教えてください。
自分もまだまだ知らないことはあるので、一緒に勉強していきましょう。 私が高専・東大・スタートアップ・日系大手メーカー・外資ハイテク企業と、、、人生の大半をコンピュータに投下して、学んできた全てをこのチャンネルにぶつけるので、私の動画を見ることによって、他では得られないコンピュータの原理的な考え方が身に付きます。
絶対にできます!一緒に頑張りましょう!
本日の動画の内容は以上になります。ここまでご視聴ありがとうございました。