チャネル・コントローラ

**チャネル・コントローラ**(*channel controller*)は、コンピュータシステムの一部であり、周辺機器とメモリの間のデータのやりとりを制御する単純なプロセッサ(CPU)である。設計の洗練度によって「周辺プロセッサ」あるいは「DMAコントローラ」とも呼ばれる。また、チャネル・コントローラを使った入出力方式を**チャネルI/O**（英: **Channel I/O**）と呼ぶ。

## 概要
多くの入出力タスクは複雑であり、データのフォーマットを変換するなどの処理をする必要がある。このような場合コンピュータのCPUはそのタスクを周辺デバイスに任せるが、周辺デバイスの処理は遅いため、CPUはその間ずっと何もしないで待っていることになる。このような状況を「I/Oバウンド」と呼ぶ。

チャネル・コントローラはこの問題を解決する。そのような入出力に関わる処理を行うためのCPUとメモリと回路を備えている。チャネル・コントローラはあまり高性能である必要はなく、柔軟性もないが、その仕事をするには十分である。実際にはコプロセッサの一種と見なすこともできる。

CPUは小さなチャネルプログラムをコントローラに送り、I/Oジョブを任せる。チャネル・コントローラはCPUの助けを借りずにそのジョブを完了させる。完了すると(あるいはエラーが発生すると)、チャネル・コントローラは割り込みでCPUに通知する。なお、プログラムのロードや仮想記憶におけるデマンドページングなどの基本的なシステムタスクの場合、完了時以外にもプログラム制御割り込みをチャネルプログラム内で使用することがある。

チャネル・コントローラはコンピュータの主記憶装置に直接アクセスするので「DMAコントローラ」とも呼ばれる(DMAは*[[Direct Memory Access|direct memory access]]*)。しかし、DMAコントローラの定義はもっと広く、プログラム不可能なデバイスでもそのように呼ばれる。

## 歴史
最初のチャネルI/Oを採用したのは、真空管を使ったメインフレーム IBM 709 である。その周辺機器である Model 766 Data Synchronizer が世界初のチャネル・コントローラであり、1957年に登場した。709 をトランジスタ化した後継機 IBM 7090 では、2つ以上のチャネル (7607) を備え、最大8個のチャネルを制御できるチャネル・マルチプレクサ (7606) も取り揃えていた。

その後、System/360や初期のSystem/370の大型機でも、セレクタ・チャネルやマルチプレクサ・チャネルが大掛かりで高価な別プロセッサとして構成されている。例えば、IBM 2860（セレクタ・チャネル）、IBM 2870（マルチプレクサ・チャネル）、IBM 2880（ブロック・マルチプレクサ・チャネル）などがある。System/360でも小型機では、CPU内のマイクロコードでチャネルを実装し、CPU自体が「CPUモード」と「チャネルモード」の2つのモードで動作した。その後、チャネル・コントローラはCPUと同じ筐体内の別個のオンボードプロセッサとなった。

アムダールは、System/370互換機でチャネルI/Oを全く異なる方法で実装した。"C-Unit" と呼ばれる単一の内部ユニットで最大16本のチャネルをサポートしている。C-Unit は最大2個搭載可能で、全部で32本までのチャネルを制御できる。C-Unit は特殊な有限状態機械 (FSM) のように機能してプロセスをそれぞれ独立に実行する。これを「チャネル状態シフト (shifting channel state)」と呼ぶ。CPUサイクル毎（470/V6およびV5では32ナノ秒ごと、470/V7およびV8では26ナノ秒ごと）に、C-Unit が優先順位に従って次のチャネルの状態を完全に読み取る。チャネルの最新状態によって必要な動作が決定されており、そのチャネルの「タグ」が実行される。すなわち、主記憶上のデータの読み書きを行い、チャネルプログラムにOS通知が指定されていたらOSに通知を行い、C-Unitがそのチャネルの次の状態を格納完了すると、次の優先順位のチャネルへと移行する。C-UnitにはFIFOストレージが十分あり、全チャネルがFSMによってエミュレートされる。IBM 2860/2870/2880のエミュレーションが可能であり、制御卓からコマンドを発行することでエミュレーション方式を変更できる。本家よりも柔軟性が高かったため、IBMが等価な機能を実装するため設計変更を余儀なくされたほどである。

IBM（および互換機）以外で最初にチャネル・コントローラを使ったのは1965年の CDC 6600 スーパーコンピュータであり、10個の「周辺プロセッサ」(*peripheral processor*、*PP*)と呼ぶコンピュータを備えていた。PPは極めて強力で、実のところCDCの初期のコンピュータ CDC 160A の改良版だった。オペレーティングシステムはPP0上で動作していた。その後、チャネル・コントローラはほとんどのメインフレームで採用されており、より小型のコンピュータと比較した際の重要な利点となっていた。

チャネル・コントローラはシングルチップで複数チャネルを操作するものも作られ、NeXTコンピュータでも使われた。しかし、最近のコンピュータの性能向上が激しいため、またオペレーティングシステムが入出力待ち状態で停止することがなくなったため、小さなマシンでは使われなくなっていった。

チャネル・コントローラの機能はバスマスタリング周辺機器に受け継がれている。PCIのDMAデバイスなどがある。主記憶とデバイス間のデータ転送をCPUの代わりに行い、処理完了時にCPUに割り込むということで、基本概念はチャネルI/Oと同じである。

## 解説
チャネルI/Oのリファレンス実装とされているのは、IBM System/360 とその後継メインフレームのものであるが、同様の実装は他のメインフレーム（CDC、Bull、GE、ハネウェル、ユニシス）でも採用されている。

チャネルI/O方式を採用したシステムには、システムのCPUとは全く独立して入出力操作全体を制御する専用のハードウェア部品が存在する。チャネルI/O方式のシステムのCPUでは入出力のための機械語命令は一種類だけ存在するのが一般的である。その命令は「チャネルプログラム」の形式でI/O専用ハードウェアに入出力コマンド群を渡すための命令である。その命令を実行後、入出力処理はCPUを煩わせることなく行われ、オペレーティングシステムに通知すべきイベントが発生すると、I/OハードウェアがCPUに対して割り込みを通知する。

チャネルは独立したハードウェアコンポーネントであり、配下のコントローラや周辺機器の入出力を行う。名前が暗に示しているような単なる通信媒体ではない。I/O操作のリスト（チャネルプログラム）を与えられ、それを解釈してI/O処理を行うインテリジェントなハードウェア機器である。

各チャネルには1つ以上のコントローラや周辺機器が接続される。チャネルプログラムにはチャネル自身へのコマンドと、接続された各種コントローラや周辺機器へのコマンドが含まれる。ただし、1つのチャネルプログラムが対象とするのは、1つのデバイスのみである。OSは、必要なコマンド群を用意すると、そのチャネルプログラムを起動するための機械語命令を実行する。その後、チャネルは指定された処理が完了するまで動作する。

非常に複雑なチャネルプログラムを書くことも可能で、データの値を調べ、その値によってチャネルプログラム内で条件分岐することもできる。この柔軟性があるため、CPUは個々の入出力操作を起動/監視/管理するオーバヘッドから解放される。チャネル機構は入出力専用であり、CPUよりも効率的に入出力処理が可能で、かつCPUと完全に並行動作できる。チャネルI/Oは Direct Memory Access (DMA) よりも複雑で機能が豊富である。多くのメインフレームのOSはチャネルI/Oの機能を完全には使いこなしていなかった。

大型メインフレームでは、CPU は並行して動作する強力なハードウェアコンポーネントの1つに過ぎない。様々な入出力コントローラ（メーカーによって名称は異なる）が入出力を専門に処理し、それらがやはり入出力専用のチャネルに接続されている。1つのシステムには複数のCPUと複数のI/Oプロセッサが存在することもある。このアーキテクチャにより、CPUの性能を犠牲にすることなく入出力性能を最適化する。メインフレームの実際のアプリケーションでは入出力性能が重要であり、このアーキテクチャによってメインフレームは非常に高いスループットを実現し、他のクラスのコンピュータとは一線を画していた。

IBMのESA/390では、ツリー状または階層状のI/Oサブシステム内のパラレルデータ接続をチャネルと呼ぶ。System/390のI/O筐体では、筐体内のデバイスを接続するケーブルをチャネルと呼ぶ（ESCONケーブル、FICONケーブルなど）。また、I/O筐体からOAフロアの下を通って、磁気テープシステムやDASDなどを接続するケーブルもチャネルと呼ばれた。

## チャネルプログラム
チャネルコマンド語（channel command word、CCW）とは、チャネルに接続された機器の入出力操作（"read" や "seek" など）を指示するコマンドである。

CCW によってチャネルプログラムが構成される。チャネルプログラムはOSか何らかの独立したソフトウェア（診断プログラムなど）が作成する。CPUが上述の機械語命令を実行すると、独立した入出力処理ユニットに信号が送られ、その装置が要求されたI/Oに責任を持つ。システムのメインCPUはその間別の作業ができる。I/O操作処理中にOSに通知すべき事象が発生すると、入出力プロセッサはCPUに割り込みを送信し、OSにその後の処理を任せる。

IBMメインフレームの初期の機種では、チャネルは1つの周辺装置と1対1に対応していた。その後、RISCプロセッサをチャネル・プロセッサとして使用するようになり、全チャネルを1つのチャネル・プロセッサで扱うようになっていった。

チャネルI/Oでは入出力をかなり簡略化できる。例えば、IBM の  では、DASD（Direct Access Storage Device）のトラック全体のフォーマットを1つのチャネルプログラム（つまり1回のI/O命令）だけで実行できる。その間、メインCPUは別の作業が可能である。

CCW（チャネルコマンド語、channel command word）は、チャネル・プロセッサ専用の命令セットであり、チャネル・プロセッサは一種の有限状態機械である。チャネルに接続されたデバイスに対して "read"、"write"、"sense" といったI/O操作を行う。一般に、チャネルI/Oを採用したアーキテクチャでは、全周辺機器はチャネルに接続され、入出力は全てCCWを使って行われる。

### チェーニング
IBMのCCWはチェーニングによってチャネルプログラムを構成する。CCW内のビットで記憶装置上の次の位置にあるデータが同じチャネルプログラムを構成するCCWかどうかを示している。チャネルプログラムは例外発生や分岐CCW実行といった事象が発生するまで逐次的に実行され、チェーニング指定が途切れたところで終了する。チェーニングには「コマンドチェーニング」と「データチェーニング」がある。コマンドチェーニングは次のCCWが新たなコマンドであることを示す。データチェーニングは次のCCWが現在のコマンドの追加データのアドレスであることを示し、例えばデバイスに書き込む1レコード分のデータが主記憶上でばらばらに存在している場合などに対応できる。

### 自己書き換え型のチャネルプログラム
チャネルプログラムを実行中に読み取ったデータに基づいてチャネルプログラム自身を書き換えることもできる。この技法はよく使われており、例えばOS/360の ISAM などで使われている。

### 具体例
以下の例は、ディスク上のレコードをキーで検索して読み取るチャネルプログラムである。そのレコードを含むトラックと所望されるキーの値は不明である。このデバイスの制御装置は要求されたレコードを見つけるためトラックを検索する。

```
SEEK             <cylinder/head number>
  SEARCH KEY EQUAL <key value>
  TIC              *-8
  READ DATA        <address of record>
```

TIC (transfer in channel) は一致するキーを持つレコードが見つかるまで（あるいはトラックの終端に到達するまで）直前のSEARCHコマンドに分岐するCCWである。キーが一致するレコードが見つかると分岐せず、次のREADコマンドを実行することになる。

## 仮想記憶とチャネルプログラム

多くの場合、チャネル・コントローラは物理アドレスで処理を行うが、チャネルプログラムは仮想アドレスを使用して書かれる。OSはチャネルプログラムを実行する前に仮想アドレスから物理アドレスへの変換（翻訳）をしなければならない。I/O処理で使用するデータを含むページ群は物理メモリ内に「ロック」または「固定」される。チャネル・プログラムは仮想アドレスを物理アドレスに変換しつつコピーされ、その後I/O操作が開始される。処理完了後、それらのページはアンロックされる。

## チャネルI/Oでのブート
チャネルI/O方式のシステムでは、ブートの最初の段階で、小さなチャネルプログラムをメモリ上にロードする処理が行われ、そのチャネルプログラムを実行することでブートプログラムを主記憶にロードする。そのチャネルプログラムが完了するとCPUに割り込みが送られ、ロードされたブートプログラムが実行される。

## 脚注・出典

## 参考文献
* 
* 

## 関連項目
* System/360
* GCOS
* UNIVAC
* I2O
* ブート
* z/Architecture

## 外部リンク
* IBM System/370 Principles Of Operation (GA22-7000-4), see chapter on Input/Output Operations