そもそもプログラムって何?仮想化の何が嬉しいの?
本日は仮想化を理解するために、プログラムとは何かを考えてみたい。最低限のプログラムの概念を理解することで、何故仮想化やクラウドが流行したかを改めて考え、グローバルでも自信を持って議論や交渉できる一つの基準として欲しい。なお、概念の説明上、詳細は多少間違っていることがあるが、その点は目を瞑って頂きたい。
1. プログラムの動作とは?
現状多くの汎用コンピュータはノイマン型コンピュータと呼ばれており、多くのプログラムもノイマン型コンピュータで動作することを前提に設計されている。
コンピュータの基本構成
ノイマン型コンピュータは主に演算部・制御部(CPU)、記憶装置(メモリ)、入出力補助装置で構成される。記憶装置(メモリ+HDD)にあるプログラムとデータを制御部・演算部(CPU)によって実行し、結果を入出力装置(ディスプレイ or 印刷 or 保存媒体)に出力する構成となっている。
プログラムの実行
ノイマン型コンピュータでは、プログラムは、実行コード領域の命令を順番に演算部で計算されることで実行される。プログラムで記載された計算結果は、スタック領域とヒープ領域に保持される。CPUは現在実行コード領域上のどこを演算しているかをプログラムカウンタで記憶している。
2. 性能向上の工夫
昔のコンピュータは各部品(CPU, メモリ, バス等)の性能が低かったため、 限られたコンピュートリソースを有効利用するために様々な工夫がされていた。
メモリの大規模化
メモリは容量及び速度共に性能に限界があったため、キャッシュとSWAPを利用しページング方式によって効率的なデータ転送を実現していた。ページング頻度が多くなる(4回/秒程度)と性能劣化に繋がるため、ページング頻度を抑止するような処理の見直しが求められた。
マルチタスク
実行主体であるCPUは少数(数十程度)であったため、マルチタスクという仕組みを利用してプログラムを同時に複数実行することを実現していた。マルチプロセスは、1つのプログラム毎にUSER領域及びプログラムカウンタを管理(プロセス)し、これらのプロセスを高速で切り替えていく(コンテキストスイッチ)方式である。
マルチスレッド
プロセスを切り替えるためにはコンテキストスイッチが必要であり、コンテキストスイッチの度にコスト(レジスタやプログラムカウンタの更新)がかかるため、同時処理する必要のあるプログラムが増えていくとオーバーヘッドが大きくなる。そこで、プロセスは切り替えず、プロセスの中の処理を切り替えていく方法をスレッドと呼ぶ。スレッドは同一メモリ空間で動作するため、同時メモリアクセスによるデータ競合が問題となることがある。
3. OSの役割
プログラムを効率的に動作させるために、多くの場合コンピュータにはOSがインストールされている。
Kernel
プログラムがコンピュートのリソースを適切かつ効率的に利用できるように、Kernelは共通機能を提供している。
- プログラムに共通的に必要となる機能(リソースへのアクセス、タスクスケジュール、異常処理)を提供する
- 各プロセスに対するリソース(メモリ、CPU、入出力装置)の割り当て及びスケジュール管理を行う。
File system
デバイス(キーボード,HDD,CDROM,オーディオ,その他)が持つデータの集まりを“ファイル”と定義することで、入出力装置の操作が効率的に利用できる。
- プログラムはファイルとのデータ送受信という考えのみでデバイス制御が可能
- カーネルが一律にデバイスへアクセスすることで性能を劣化させない
4. 今のコンピュート性能と仮想化が流行した背景
ノイマン型コンピュータが1945年、Kernel(OS)の標準化POSIXが1988年に提案されたことを踏まえると、当時から20年程度経過した。その間にコンピュータの性能は飛躍的に向上した。
コンピュート性能の向上
2010年頃から、64bit CPUの台頭や、メモリ価格な低価格化、新規方式によるCPU〜メモリ転送量の高速化等が起き、最近ではメモリは容量、及び、速度共に大幅な性能が改善され、コンピュート要因のプログラムの制約はほぼ無くなった。その結果、プログラムのトレンドとしては2つの方向性に進んでいる。
- (プログラムの再設計&再実装は大変なので)高性能で安価なサーバをフルに利用する方向
→プラグラムは変えずに、1コンピュートで複数のプログラムをVMとして利用することでサーバのリソース利用効率を改善 - メモリを多量に使う新プログラムの開発
→AIの導入等、高性能なサーバを活用した新しいタイプのプログラムを作成
仮想化のメリット
2000年頃のITバブルによって、多くのアプリケーションが開発され、企業もIT化を推進した。その結果、従来型の仕組みで動作するアプリケーションが多量に増えた。これらのアプリケーションは、元々メモリを4GB、同時実行数を数十〜数百程度で動作させる前提で設計されたものであり、コンピュートの性能向上にプログラムの方がついていけず、コンピュートのリソースを使い切れなくなった。
一方で、新しいコンピュートの性能に合わせてプログラムを再設計すると膨大な費用がかかる上に、コンピュートの進化は速いのでついていくのは厳しいだろう。その結果、仮想化機能によってコンピュートリソースを分割するようになっていった。
仮想化の良いところは、プログラムの構造をあまり変えること無く、複数のプログラムを同一コンピュートに搭載させ、リソースを効率良く利用できるところであろう。
リクエストがあれば、仮想化やコンテナの技術についてもう少し考えてみたい。
初めて学ぶこと、分かりそうな説明はあるのにわからない、ことが多かった分野の詳細な解説でものすごく貴重な資料だと思いました。その中でもKernelは何度ググっても理解できなかったため、個人的には本当にありがたいです。
返信削除コメントありがとうございます。プログラムの動作はIT系に携わる場合の基礎知識として重要ですが、学生時代になかなか触れる機会の無いところですので、このような記事が役に立つようであれば継続して書いていきたいと思います。今後ともよろしくお願いします。
削除