<!doctype linuxdoctr system>
<article>
<title>Linux Parallel Processing HOWTO
<author>Hank Dietz, <tt>pplinux@ecn.purdue.edu</tt>
<date>v980105, 5 January 1998
<trans>高橋 聡 <tt>hisai@din.or.jp</tt>
<tdate> 2001/5/15

<abstract>

<!--
<bf>Parallel Processing</bf> refers to the concept of speeding-up the
execution of a program by dividing the program into multiple fragments
that can execute simultaneously, each on its own processor.  A program
being executed across <em>N</em> processors might execute <em>N</em>
times faster than it would using a single processor.  This document
discusses the four basic approaches to parallel processing that are
available to Linux users:  SMP Linux systems, clusters of networked
Linux systems, parallel execution using multimedia instructions (i.e.,
MMX), and attached (parallel) processors hosted by a Linux system.
-->
<bf>並列処理</bf>とはプログラムの実行速度を上げる考えの 1 つを指し、
プログラムを同時に実行可能な複数の部分に分け、それぞれをプロセッサ上
で動かします。プログラムを <em>N</em> 個のプロセッサに分けて実行すれば、
1 つのプロセッサで動かすのに比べて <em>N</em> 倍速く実行できると考え
られます。このドキュメントでは、基本的な 4 つの並列処理の方法を検討します。
いずれも Linux ユーザが利用できる方法で、SMP Linux システム、ネット
ワークでつながっている Linux システムでクラスタを組む、マルチメディア
命令(すなわち、MMX)を使った並列処理、そして Linux システムに(独立して)
搭載されている付加プロセッサを利用するというのがそれに当たります。

<toc>

<!-- <sect>Introduction -->
<sect>はじめに
<p>

<!--
<bf>Parallel Processing</bf> refers to the concept of speeding-up the
execution of a program by dividing the program into multiple fragments
that can execute simultaneously, each on its own processor.  A program
being executed across <em>n</em> processors might execute <em>n</em>
times faster than it would using a single processor.
-->
<bf>並列処理</bf>とはプログラムの実行速度を上げる考えで、プログラムを
同時に実行可能な複数の部分に分け、それぞれをプロセッサ上で動かします。
プログラムを <em>n</em> 個のプロセッサに分けて実行すれば、1 つのプロ
セッサで動かすのに比べて <em>n</em> 倍速く実行できると考えられます。
<p>

<!--
Traditionally, multiple processors were provided within a specially
designed "parallel computer"; along these lines, Linux now supports
<bf>SMP</bf> systems (often sold as "servers") in which multiple
processors share a single memory and bus interface within a single
computer.  It is also possible for a group of computers (for example,
a group of PCs each running Linux) to be interconnected by a network
to form a parallel-processing <bf>cluster</bf>.  The third alternative
for parallel computing using Linux is to use the <bf>multimedia
instruction extensions</bf> (i.e., MMX) to operate in parallel on
vectors of integer data.  Finally, it is also possible to use a Linux
system as a "host" for a specialized <bf>attached</bf> parallel
processing compute engine.  All these approaches are discussed in
detail in this document.
-->
これまで複数のプロセッサを持つシステムは、特注で設計した「並列
コンピュータ」として世の中に存在していました。現状では、これに加えて 
Linux が <bf>SMP</bf> システム(「サーバ」として販売されていること
が多い)を提供しています。
これは 1 台のコンピュータで複数のプロセッサが 1 つのメモリとバスの
インタフェースを共用しています。もちろんコンピュータを複数用意して
(例えば Linux が動いている複数の PC を用意する)ネットワークでつないで
並列処理<bf>クラスタ</bf>を組むこともできます。Linux を使った並列演算
の 3 番目の方法は、<bf>マルチメディア拡張命令</bf>(すなわち MMX)を
使って、整数データのベクトルを並列に扱う方法です。最後は、専用に
<bf>搭載されている</bf>並列処理計算エンジンを利用するのに Linux システム 
をホストにしてしまう、という方法です。このドキュメントでは、これらすべて
のアプローチを詳しく検討していくことにします。

<!-- <sect1>Is Parallel Processing What I Want?  -->
<sect1>何を並列処理に求めるのか？
<p>

<!--
Although use of multiple processors can speed-up many operations, most
applications cannot yet benefit from parallel processing.  Basically,
parallel processing is appropriate only if:
-->
複数のプロセッサは確かに多くの処理を高速にしますが、並列処理によって
恩恵を受けないアプリケーションも多数存在します。一般的には並列処理
で効果が出るのは下記の場合に限定されます。

<itemize>
<!--
<item>Your application has enough parallelism to make good use of
multiple processors.  In part, this is a matter of identifying
portions of the program that can execute independently and
simultaneously on separate processors, but you will also find that
some things that <em>could</em> execute in parallel might actually slow
execution if executed in parallel using a particular system.  For
example, a program that takes four seconds to execute within a single
machine might be able to execute in only one second of processor time
on each of four machines, but no speedup would be achieved if it took
three seconds or more for these machines to coordinate their actions.
-->
<item>アプリケーションが複数プロセッサを効率的に使用するよう並列化
がほどこしてあること。ある面で、これはプログラムの一部分が独立して動作
でき、かつその部分が独立したプロセッサで並列して動作するとみなすことに
ほかならない。ただし、並列で実行<em>できる</em>ことが特定のシステム
ではかえって処理速度が遅くなってしまう可能性があることもわかっている。
例えば、1 つのプロセッサで実行に 4 秒かかるプログラムがあったとする。
そのプログラムが、4 つのマシンでそれぞれ 1 秒で実行できたとしても、
これらのマシンが協調して動作するのに 3 秒以上かかってしまえば、結局は
処理速度が上がったことにはならない

<!--
<item>Either the particular application program you are interested in
already has been <bf>parallelized</bf> (rewritten to take advantage of
parallel processing) or you are willing to do at least some new coding
to take advantage of parallel processing.
-->
<item>実行したいと思っているアプリケーションが<bf>並列化</bf>されて
いる(並列処理向きに手直ししてある)か、少なくとも並列処理で効果がでる
ように新たにアプリケーションに手をいれるつもりがあること

<!--
<item>You are interested in researching, or at least becoming familiar
with, issues involving parallel processing.  Parallel processing using
Linux systems isn't necessarily difficult, but it is not familiar to
most computer users, and there isn't any book called "Parallel
Processing for Dummies"...  at least not yet.  This HOWTO is a good
starting point, not all you need to know.
-->
<item>並列処理に関連する事柄についの研究に興味があるか、少なくとも
理解する意志があること。システムで並列処理を使用することは必ずしも困難
なことではないが、コンピュータの利用者の大半は並列処理に詳しくなく、
今のところ「初めての並列処理」というような書籍も存在しない。この HOWTO 
は理解するきっかけとしては恰好のものだが、すべてを網羅しているわけでは
ない
</itemize>
<p>

<!--
The good news is that if all the above are true, you'll find that
parallel processing using Linux can yield supercomputer performance
for some programs that perform complex computations or operate on
large data sets.  What's more, it can do that using cheap hardware...
which you might already own.  As an added bonus, it is also easy to
use a parallel Linux system for other things when it is not busy
executing a parallel job.
-->
幸いなことに上記すべてが本当であっても、Linux を利用した並列処理は
スーパーコンピュータ並のパフォーマンスで複雑な計算や巨大なデータセット
を扱えます。何よりも、安価なハードウェア(既に所有しているような)で実現
できるのが魅力です。さらに良いことには、並列に処理をするほど忙しくなけ
れば、並列 Linux システムで他の処理も簡単に実行できます。

<!--
If parallel processing is <em>not</em> what you want, but you would
like to achieve at least a modest improvement in performance, there are
still things you can do.  For example, you can improve performance of
sequential programs by moving to a faster processor, adding memory,
replacing an IDE disk with fast wide SCSI, etc.  If that's all you are
interested in, jump to section 6.2; otherwise, read on.
-->
並列処理を望んでいる<em>わけではない</em>が、それなりにパフォーマンス
の向上を達成したいと思っているなら、打つ手は他にまだあります。例えば、
逐次実行するプログラムのパフォーマンスを上げるには、より高速なプロセッサ
への換装やメモリの増設、ディスクを IDE から Fast Wide SCSI に交換する等
の方法があります。この点に関心があるなら、セクション 6.2 に進んでください。
そうでなければこのまま読み進めてください。

<!-- <sect1>Terminology -->
<sect1>専門用語
<p>

<!--
Although parallel processing has been used for many years in many
systems, it is still somewhat unfamiliar to most computer users.
Thus, before discussing the various alternatives, it is important to
become familiar with a few commonly used terms.
-->
並列処理はこれまで様々なシステムで行われてきていますが、コンピュータ
ユーザの大部分にとって、まだそれほどなじみがあるわけではありません。
そこで、いろいろな並列処理について論じる前に、よく使われる用語のいくつか
を理解しておきましょう。

<descrip>
<tag>SIMD:</tag>
<!--
SIMD (Single Instruction stream, Multiple Data stream) refers to a
parallel execution model in which all processors execute the same
operation at the same time, but each processor is allowed to operate
upon its own data.  This model naturally fits the concept of
performing the same operation on every element of an array, and is
thus often associated with vector or array manipulation.  Because all
operations are inherently synchronized, interactions among SIMD
processors tend to be easily and efficiently implemented.
-->
SIMD(Single Instruction stream, Multiple Data stream)は並列実行モデル
の 1 つで、プロセッサすべてが同じ演算を同時に行う。しかし、それぞれの
プロセッサは固有のデータしか扱えない。そもそもこのモデルは、配列の
各要素に対して同様な演算するという、ベクトルや配列に関連した操作を得意と
する。理由は、演算すべてがもともと同期していて、SIMD プロセッサ間の
やりとりが簡単かつ効率良く実装しやすいからである

<tag>MIMD:</tag>
<!--
MIMD (Multiple Instruction stream, Multiple Data stream) refers to a
parallel execution model in which each processor is essentially acting
independently.  This model most naturally fits the concept of
decomposing a program for parallel execution on a functional basis;
for example, one processor might update a database file while another
processor generates a graphic display of the new entry.  This is a
more flexible model than SIMD execution, but it is achieved at the
risk of debugging nightmares called <bf>race conditions</bf>, in which
a program may intermittently fail due to timing variations reordering
the operations of one processor relative to those of another.
-->
MIMD(Multiple Instruction stream, Multiple Data stream)は並列実行
モデルの 1 つで、基本的にプロセッサそれぞれは独立して動作する。そもそも
このモデルは複数のプログラムを利用して、機能ベースで並列に実行する
ことに長けている。例えば、あるプロセッサがデータベースの更新を行って
いる間、他のプロセッサは新たに入力された画像の表示を処理しているという
具合に。
このモデルは SIMD よりも自由度が高いが、悪夢のデバックが必要となる
<bf>競合状態</bf>に陥る可能性があり、プログラムが断続的に落ちる危険性
がある。これはプロセッサが再実行を行うタイミングの問題で、他のプロセッサ
のタイミングとの関係によって生じる問題である

<tag>SPMD:</tag>
<!--
SPMD (Single Program, Multiple Data) is a restricted version of MIMD
in which all processors are running the same program.  Unlike SIMD,
each processor executing SPMD code may take a different control flow
path through the program.
-->
SPMD(Single Program, Multiple Data)は機能を限定した MIMD で、プロセッサ
すべてが同じプログラムを実行する。SIMD とは異なり、SPMD のコードを実行する
プロセッサはプログラム中でそれぞれ異なった制御の流れをとる

<!-- <tag>Communication Bandwidth:</tag> -->
<tag>通信帯域幅 (Communication Bandwidth):</tag>
<!--
The bandwidth of a communication system is the maximum amount of data
that can be transmitted in a unit of time...  once data transmission
has begun.  Bandwidth for serial connections is often measured in
<bf>baud</bf> or <bf>bits/second (b/s)</bf>, which generally
correspond to 1/10 to 1/8 that many <bf>Bytes/second (B/s)</bf>.  For
example, a 1,200 baud modem transfers about 120 B/s, whereas a 155
Mb/s ATM network connection is nearly 130,000 times faster,
transferring about about 17 MB/s.  High bandwidth allows large blocks
of data to be transferred efficiently between processors.
-->
通信系の帯域幅とは、転送がはじまってから単位時間当たりに転送できる
最大のデータ量を表す。シリアル接続の帯域幅は <bf>ボー(baud)</bf> や 
<bf>ビット/秒 (b/s)</bf>で表すのが普通だが、これは<bf>バイト/秒 (B/s)
</bf>のだいたい 1/10 から 1/8 に当たる。例えば 1200 ボーのモデムは、約 
120 ビット/秒伝送し、155 M ビット/秒の ATM 回線は、モデムの 130,000 倍
速く、17 M ビット/秒伝送できる。帯域が広ければ大きなブロックのデータを
伝送することができ、プロセッサ間で効率良くデータがやり取りできる

<!-- <tag>Communication Latency:</tag> -->
<tag>通信遅延(Communication Latency):</tag>
<!--
The latency of a communication system is the minimum time taken to
transmit one object, including any send and receive software
overhead.  Latency is very important in parallel processing because it
determines the minimum useful <bf>grain size</bf>, the minimum run
time for a segment of code to yield speed-up through parallel
execution.  Basically, if a segment of code runs for less time than it
takes to transmit its result value (i.e., latency), executing that
code segment serially on the processor that needed the result value
would be faster than parallel execution; serial execution would avoid
the communication overhead.
-->
通信系の遅延は、ある「もの」を伝送するのにかかる最小時間である。これ
には送受信にかかるソフトウェアのオーバーヘッドも含まれている。並列処理
にとって遅延はとても重要であり、これが有効な最小の<bf>粒度</bf>を決定
する。コード単位を実行している時間が短いほど、並列実行が高速になる。
基本的に、コード単位を実行する時間がその実行結果を返す時間(例えば、
遅延)より短ければ、プロセッサ上で返り値を必要とする連続したコードの実行
は、並列実行より速くなるはずである。連続した処理の実行は、通信のオーバー
ヘッドを避ける必要がある

<!-- <tag>Message Passing:</tag> -->
<tag>メッセージ通信(Message Passing):</tag>
<!--
Message passing is a model for interactions between processors within
a parallel system.  In general, a message is constructed by software
on one processor and is sent through an interconnection network to
another processor, which then must accept and act upon the message
contents.  Although the overhead in handling each message (latency)
may be high, there are typically few restrictions on how much
information each message may contain.  Thus, message passing can yield
high bandwidth making it a very effective way to transmit a large
block of data from one processor to another.  However, to minimize the
need for expensive message passing operations, data structures within
a parallel program must be spread across the processors so that most
data referenced by each processor is in its local memory...  this task
is known as <bf>data layout</bf>.
-->
メッセージ通信は、並列システム内でプロセッサ間でやりとりするモデルの 
1 つである。普通はあるプロセッサ上のソフトウェアがメッセージを作成し、
相互に接続しているネットワークを経由して送られる。送られたメッセージは
受信され、メッセージの内容を実行する必要がある。メッセージを扱う
オーバーヘッド(遅延)が大きいかもしれないが、通常はメッセージにどのくらい
情報を含められるかについてはほとんど制限がない。したがって、メッセージ
通信は広い帯域を生かしつつ、データを大きなブロックにすることにより、
プロセッサ間でとても効率的にやりとりができる。しかし、メッセージ通信
は時間がかかる処理なので、その必要性を最小限にしなければならない。
並列処理プログラムのデータ構造は、広くプロセッサ間にまたがっているので、
それぞれのプロセッサが参照するデータは、ローカルなメモリ上にある必要が
ある。この作業を<bf>データ配置</bf>と言う

<!-- <tag>Shared Memory:</tag> -->
<tag>共有メモリ(Shared Memory):</tag>
<!--
Shared memory is a model for interactions between processors within a
parallel system.  Systems like the multi-processor Pentium machines
running Linux <bf>physically</bf> share a single memory among
their processors, so that a value written to shared memory by one
processor can be directly accessed by any processor.  Alternatively,
<bf>logically</bf> shared memory can be implemented for
systems in which each processor has it own memory by converting each
non-local memory reference into an appropriate inter-processor
communication.  Either implementation of shared memory is generally
considered easier to use than message passing.  Physically shared
memory can have both high bandwidth and low latency, but only when
multiple processors do not try to access the bus simultaneously; thus,
data layout still can seriously impact performance, and cache effects,
etc., can make it difficult to determine what the best layout is.
-->
共有メモリは、並列システムにおけるプロセッサ間のやりとりについての
モデルの 1 つである。Pentium をいくつか搭載しているような複数プロセッサ
マシンで Linux が動いている場合は、プロセッサは 1 つのメモリを<bf>物理的
</bf>に共有している。したがってあるプロセッサが共有メモリに値を書き込む
と他のどのプロセッサからも直接アクセスが可能になる。これとは別に
<bf>論理的</bf>に共有しているメモリを実装しているシステムもある。その各々
のプロセッサは独自のメモリを持ち、ローカルでないメモリへの参照をプロセス
間通信に適宜置き換える。普通どちらの共有メモリの実装をとっても、メッセージ
通信よりも扱いやすい。物理的に共有されたメモリは広い帯域幅を使えるだけでなく、
遅延も少ない。しかしそれは複数のプロセッサが同時にバスにアクセスしないように
した場合だけである。したがって、データ配置はやはりパフォーマンスに重大な
影響を与え、キャッシュの効果等でどのデータ配置が最適なのかを判断するのは
難しい

<!-- <tag>Aggregate Functions:</tag> -->
<tag>集合演算(Aggregate Functions):</tag>
<!--
In both the message passing and shared memory models, a communication
is initiated by a single processor; in contrast, aggregate function
communication is an inherently parallel communication model in which
an entire group of processors act together.  The simplest such action
is a <bf>barrier synchronization</bf>, in which each individual
processor waits until every processor in the group has arrived at the
barrier.  By having each processor output a datum as a side-effect of
reaching a barrier, it is possible to have the communication hardware
return a value to each processor which is an arbitrary function of the
values collected from all processors.  For example, the return value
might be the answer to the question "did any processor find a
solution?"  or it might be the sum of one value from each processor.
Latency can be very low, but bandwidth per processor also tends to be
low.  Traditionally, this model is used primarily to control parallel
execution rather than to distribute data values.
-->
メッセージ通信、共有メモリ両モデルとも、通信のきっかけは単独のプロセッサ
が引き金となる。それとは対照的に、生来の並列処理モデルである集約演算の通信
では、各プロセッサが統合され、協調して動作する。そのような動作は<bf>
バリア同期(barrier synchronization)</bf>と呼ばれている。個々のプロセッサ
は、統合されたプロセッサのそれぞれが処理上のある境界に達するまで待機する。
プロセッサ毎にある境界に達したことを示す基準値を生成することで、通信機器
はそれぞれのプロセッサに値を返すことが可能になる。そのプロセッサは、独自
の演算で得られた値をすべて収集した結果を通信機器の返り値として返すことが
できる。それは例えば「どのプロセッサが解答を見つけたか？」という問への返答
が返り値になる場合もあるし、それぞれのプロセッサからの値の合計が返り値に
なる場合もある。
遅延が極めて少ない反面、プロセッサ毎の帯域幅も狭い傾向にある。元来、この
モデルはデータ値を分散させるというよりも、並列実行を制御することを第一の
目的としている場合が多い

<!-- <tag>Collective Communication:</tag> -->
<tag>集合通信(Collective Communication):</tag>
<!--
This is another name for aggregate functions, most often used when
referring to aggregate functions that are constructed using multiple
message-passing operations.
-->
集合演算の別名で、集合演算を複数のメッセージ通信を使って実現する場合に
よく使われる

<tag>SMP:</tag>
<!--
SMP (Symmetric Multi-Processor) refers to the operating system concept
of a group of processors working together as peers, so that any piece
of work could be done equally well by any processor.  Typically, SMP
implies the combination of MIMD and shared memory.  In the IA32 world,
SMP generally means compliant with MPS (the Intel MultiProcessor
Specification); in the future, it may mean "Slot 2"....
-->
SMP(Symmetric Multi-Processor)はオペレーティング・システムの概念で、対等
に協調して動作するプロセッサの集合を表す。つまり、プロセッサそれぞれが処理
の部分部分をうまい具合に処理しあう。普通、SMP は MIMD と共有メモリを組み
合わせて実現する。IA32 を使ったシステムでは、SMP は MPS(the Intel 
MultiProcessor Specification)に準拠している。将来的には、「Slot 2」…を
意味することになるかもしれない

<tag>SWAR:</tag>
<!--
SWAR (SIMD Within A Register) is a generic term for the concept of
partitioning a register into multiple integer fields and using
register-width operations to perform SIMD-parallel computations across
those fields.  Given a machine with <em>k</em>-bit registers, data
paths, and function units, it has long been known that ordinary
register operations can function as SIMD parallel operations on as
many as <em>n</em>, <em>k</em>/<em>n</em>-bit, field values.  Although
this type of parallelism can be implemented using ordinary integer
registers and instructions, many high-end microprocessors have
recently added specialized instructions to enhance the performance of
this technique for multimedia-oriented tasks.  In addition to the
Intel/AMD/Cyrix <bf>MMX</bf> (MultiMedia eXtensions), there are:
Digital Alpha <bf>MAX</bf> (MultimediA eXtensions), Hewlett-Packard
PA-RISC <bf>MAX</bf> (Multimedia Acceleration eXtensions), MIPS
<bf>MDMX</bf> (Digital Media eXtension, pronounced "Mad Max"), and Sun
SPARC V9 <bf>VIS</bf> (Visual Instruction Set).  Aside from the three
vendors who have agreed on MMX, all of these instruction set
extensions are roughly comparable, but mutually incompatible.
-->
SWAR(SIMD Within A Register)はレジスタを複数の整数領域に分割する考え方で、
レジスタ長命令を使ってこれらの分割された領域で SIMD 並列演算を実行する。
<em>k</em> ビットのレジスタとデータパスと演算装置を持つマシンでは、通常の
レジスタ処理は SIMD の並列処理で動くことが知られている。つまり 
<em>k</em>/<em>n</em> ビットの領域の値として <em>n</em> 個実行できる。
このタイプの並列処理化は整数レジスタや整数命令を使って実行されるのが一般的
だが、最近のハイエンドなマイクロプロセッサの多くは特殊な命令を追加して、
マルチメディア関連処理のパフォーマンスを向上させている。Intel や AMD、Cyrix 
の <bf>MMX</bf>(MultiMedia eXtensions)がそれに当り、他にも Digital Alpha 
の <bf>MAX</bf>(MultimediA eXtensions)や Hewlett-Packard PA-RISC の 
<bf>MAX</bf>(Multimedia Acceleration eXtensions)、MIPS の <bf>MDMX</bf>
(Digital Media eXtension "Mad Max" という)、Sun SPARC V9 の <bf>VIS</bf>
(Visual Instruction Set)がある。MMX を採用しているベンダー 3 社を除いて、
これらの命令セットすべては、似ていることは似ているが、それぞれ別個のもの
である

<!-- <tag>Attached Processors:</tag> -->
<tag>付加プロセッサ(コプロセッサ):</tag>
<!--
Attached processors are essentially special-purpose computers that are
connected to a <bf>host</bf> system to accelerate specific types of
computation.  For example, many video and audio cards for PCs contain
attached processors designed, respectively, to accelerate common
graphics operations and audio <bf>DSP</bf> (Digital Signal
Processing).  There is also a wide range of attached <bf>array
processors</bf>, so called because they are designed to accelerate
arithmetic operations on arrays.  In fact, many commercial
supercomputers are really attached processors with workstation hosts.
-->
本来、付加プロセッサは特別な用途向けのコンピュータで、<bf>ホスト</bf>
となるシステムに装着され、特殊な計算を高速に実行する。例えば、PC の
ビデオカードやオーディオカードの多くには付加プロセッサが載っており、
それぞれに共通している画像処理やオーディオの <bf>DSP</bf>(Digital Signal 
Processing)処理を高速化する。またあちこちに<bf>アレイ・プロセッサ</bf>
も存在する。こう呼ばれる理由は、アレイ状(配列状)に配置された付加プロセッサ
上で、数学的演算を高速に実行するからである。現実的には、商用のスーパーコン
ピュータの多くはワークステーションというホストに付加プロセッサが載った
ものである

<tag>RAID:</tag>
<!--
RAID (Redundant Array of Inexpensive Disks) is a simple technology for
increasing both the bandwidth and reliability of disk I/O.  Although
there are many different variations, all have two key concepts in
common.  First, each data block is <bf>striped</bf> across a group of
<em>n+k</em> disk drives such that each drive only has to read or
write 1/<em>n</em> of the data...  yielding <em>n</em> times the
bandwidth of one drive.  Second, redundant data is written so that
data can be recovered if a disk drive fails; this is important because
otherwise if any one of the <em>n+k</em> drives were to fail, the
entire file system could be lost.  A good overview of RAID in general
is given at <url url="http://www.dpt.com/uraiddoc.html">, and
information about RAID options for Linux systems is at <url
url="http://linas.org/linux/raid.html">.  Aside from specialized RAID
hardware support, Linux also supports software RAID 0, 1, 4, and 5
across multiple disks hosted by a single Linux system; see the
Software RAID mini-HOWTO and the Multi-Disk System Tuning mini-HOWTO
for details.  RAID across disk drives <em>on multiple machines in a
cluster</em> is not directly supported.
-->
RAID(Redundant Array of Inexpensive Disks)は、ディスク入出力の帯域幅と
信頼性を向上させる技術を指す。バリエーションがいくつもあるが、共通して 
鍵となる考え方が 2 つある。第 1 は、データブロックそれぞれは <em>n+k
</em> 個のディスクドライブ群に<bf>ストライプ</bf>されており、それぞれ
のドライブはデータの 1/<em>n</em> だけ読み書きしなければいけない…と
いうことを利用して、1 つのドライブに対して従来の <em>n</em> 倍の帯域幅
を実現することである。第 2 は、データを冗長に書くことによって、ディスク
ドライブが 1 つ壊れてもデータを復旧できることである。これは重要なことで、
冗長化していないと、<em>n+k</em> 個のディスクドライブのどれか 1 つでも
駄目になった場合、ファイルシステムが完全に壊れてしまうことになる。RAID 
についての概要を知りたいならば、
<url 
url="http://www.adaptec.com/worldwide/product/prodtechindex.html?cat=%2fTechnology%2fRAID"> 
を、Linux システムの RAID がどのようなものがあるかを知りたければ、
<url url="http://linas.org/linux/raid.html"> を参照のこと。RAID 専用の
ハードウェアのサポートは別として、Linux はソフトウェアで RAID 0、1、4、
5 をサポートしており、複数のディスクを 1 台の Linux システムで扱える。
詳細は、Software RAID mini-HOWTO や the Multi-Disk System Tuning 
mini-HOWTO を参照のこと。<em>クラスタを組んだ複数のマシン</em>上で
複数のディスクドライブにまたがって RAID を組むことは、デフォルトでは
サポートされていない
<p>
【訳註：Multi-Disk System Tuning mini-HOWTO の日本語訳は <url 
url="http://www.linux.or.jp/JF/JFdocs/Multi-Disk-HOWTO.html"> 
です】

<tag>IA32:</tag>
<!--
IA32 (Intel Architecture, 32-bit) really has nothing to do with
parallel processing, but rather refers to the class of processors whose
instruction sets are generally compatible with that of the Intel 386.
Basically, any Intel x86 processor after the 286 is compatible with
the 32-bit flat memory model that characterizes IA32.  AMD and Cyrix
also make a multitude of IA32-compatible processors.  Because Linux
evolved primarily on IA32 processors and that is where the commodity
market is centered, it is convenient to use IA32 to distinguish any of
these processors from the PowerPC, Alpha, PA-RISC, MIPS, SPARC, etc.
The upcoming IA64 (64-bit with EPIC, Explicitly Parallel Instruction
Computing) will certainly complicate matters, but Merced, the first
IA64 processor, is not scheduled for production until 1999.
-->
IA32(Intel Architecture, 32-bit)は並列処理とは無関係だが、あるプロセッサ
の命令セットが Intel の 386 と互換性があるかについてふれている。
基本的に、Intel の 286 以後の x86 プロセッサは、32 ビットのフラットな
メモリモデルを持っていて、それが IA32 の特徴となっている。AMD と Cyrix 
も、IA32 互換のプロセッサを数多く製造している。Linux が主として IA32 
プロセッサで発展し、商品市場が IA32 を中心として形成された理由は、
PowerPC や Alpha、PA-RISC、MIPS、SPARC 他のそれ以外のプロセッサと比べて
利用しやすかった点にある。
きたるべき IA64(64-bit with EPIC, Explicitly Parallel Instruction
Computing)はきっとそううまくはいかないだろう。Merced と呼ばれる最初の
IA64 プロセッサは 1999 年の時点では製造の見通しが立っていない。
<p>
【訳註：Merced はプロセッサのコア名となり、プロセッサ名としては、
「Itanium」が正式名称となりました。製品版は 2001 年の中ごろになる予定です。
既に第 2 世代コアの「McKinley」もアナウンスされていて、2001 年後半に登場
する予定です。一方 AMD は、「ClawHammer」と呼ばれる 64 ビットチップを 
2002 年後半に登場させる予定です】

<!-- <tag>COTS:</tag> -->
<tag>市販の既成品:</tag>
<!--
Since the demise of many parallel supercomputer companies, COTS
(Commercial Off-The-Shelf) is commonly discussed as a requirement for
parallel computing systems.  Being fanatically pure, the only COTS
parallel processing techniques using PCs are things like SMP Windows
NT servers and various MMX Windows applications; it really doesn't pay
to be that fanatical.  The underlying concept of COTS is really
minimization of development time and cost.  Thus, a more useful, more
common, meaning of COTS is that at least most subsystems benefit from
commodity marketing, but other technologies are used where they are
effective.  Most often, COTS parallel processing refers to a cluster
in which the nodes are commodity PCs, but the network interface and
software are somewhat customized...  typically running Linux and
applications codes that are freely available (e.g., copyleft or public
domain), but not literally COTS.
-->
多くの並列スーパーコンピュータ企業が消えていく中、並列計算システムの
必要性から市販の既成品が論じられている。Windows に傾倒しているなら、
市販の既成品で PC を使った並列処理技術を生かせるのは、SMP の Windows 
NT サーバと MMX を使った様々な Windows のアプリケーションということに
なるが、その考え方には何も得るところがない。
市販の既成品に対する考え方の背景には、開発にかかる時間と費用の削減がある。
したがって、便利かつ普通に入手できる市販の既成品は、少なくともサブシステム
に対して商品市場戦略の恩恵をもたらしてくれる。ただ戦略が目指しているもの
とは違った技術が効果的に利用されることのなるのだが。
大抵の場合、市販の既成品を用いた並列処理とはクラスタを指し、ノードを普通
の PC で構成する。しかしネットワーク・インタフェースやソフトウェアは何
かしらカスタマイズしてある…普通は Linux 上でフリーで利用できる(例えば、
コピーレフトやパブリック・ドメイン)アプリケーションが動いているが、これは
市販の既成品ではない
</descrip>

<!-- <sect1>Example Algorithm -->
<sect1>アルゴリズムの例
<p>

<!--
In order to better understand the use of the various parallel
programming approaches outlined in this HOWTO, it is useful to have an
example problem.  Although just about any simple parallel algorithm
would do, by selecting an algorithm that has been used to demonstrate
various other parallel programming systems, it becomes a bit easier to
compare and contrast approaches.  M. J.  Quinn's book, <em>Parallel
Computing Theory And Practice</em>, second edition, McGraw Hill, New
York, 1994, uses a parallel algorithm that computes the value of Pi to
demonstrate a variety of different parallel supercomputer programming
environments (e.g., nCUBE message passing, Sequent shared memory).  In
this HOWTO, we use the same basic algorithm.
-->
この HOWTO でこれから紹介していく様々な並列プログラミング手法を理解する
には、例題を見ていくことが有効な手段です。どんな単純な並列アルゴリズムで
あったとしても、他の様々な並列プログラミングシステムのアプローチを明示
してくれるアルゴリズムを選ぶことで、多少なりとも比較対照が楽になります。
M.J.Quinn 氏の著書である <em>Parallel Computing Theory And Practice</em>, 
second edition, McGraw Hill, New York, 1994 では、円周率を計算する並列
アルゴリズムを挙げることで、いろいろな種類の並列スーパーコンピュータでの
プログラミング環境(例えば nCUBE のメッセージ通信や Sequent の共有メモリ)
を明らかにしています。
この HOWTO では同じ基礎的なアルゴリズムを使っていきます。

<!--
The algorithm computes the approximate value of Pi by summing the area
under <em>x</em> squared.  As a purely sequential C program, the
algorithm looks like:
-->
そのアルゴリズムは、円周率の近似値を <em>x</em> 角形の領域を合計すること
で計算します。C のプログラムで素直に順次実行すると、アルゴリズムは下記の
ようになります。

<code>
#include <stdlib.h>;
#include <stdio.h>;

main(int argc, char **argv)
{
  register double width, sum;
  register int intervals, i;

  /* get the number of intervals */
  intervals = atoi(argv[1]);
  width = 1.0 / intervals;

  /* do the computation */
  sum = 0;
  for (i=0; i<intervals; ++i) {
    register double x = (i + 0.5) * width;
    sum += 4.0 / (1.0 + x * x);
  }
  sum *= width;

  printf("Estimation of pi is %f\n", sum);

  return(0);
}
</code>

<!--
However, this sequential algorithm easily yields an "embarrassingly
parallel" implementation.  The area is subdivided into intervals, and
any number of processors can each independently sum the intervals
assigned to it, with no need for interaction between processors.  Once
the local sums have been computed, they are added together to create a
global sum; this step requires some level of coordination and
communication between processors.  Finally, this global sum is printed
by one processor as the approximate value of Pi.
-->
しかしこの順次実行のアルゴリズムは、「極めて並列性を上げて」実行できます。
領域は間隔単位に細分化され、プロセッサの数の分だけ間隔単位で割り当てた
部分を独立に合計できます。
ここではプロセッサ間の調整作業は必要ありません。ローカルでの合計が計算
されれば、それを合計して総合計をだせばいいわけです。この段階ではプロセッサ
間で何らかの調整と計算が発生します。最終的に、この総合計が円周率の近似値
としてプロセッサの 1 つが値を出力します。

<!--
In this HOWTO, the various parallel implementations of this algorithm
appear where each of the different programming methods is discussed.
-->
この HOWTO では、このアルゴリズムを表現した様々な並列処理の実装を
提示することで、プログラミング手法の様々な相違を検討していきます。

<!-- <sect1>Organization Of This Document -->
<sect1>このドキュメントの構成
<p>

<!--
The remainder of this document is divided into five parts.  Sections
2, 3, 4, and 5 correspond to the three different types of hardware
configurations supporting parallel processing using Linux:
-->
このドキュメントの残りの部分は 5 つに分かれています。セクション 2 と 
3、4、5 それぞれは、Linux を使って並列処理をサポートする 3 種の異なる
ハードウェアの構成にふれています。

<itemize>
<!--
<item>Section 2 discusses SMP Linux systems.  These directly support
MIMD execution using shared memory, although message passing also is
implemented easily.  Although Linux supports SMP configurations up to
16 processors, most SMP PC systems have either two or four identical
processors.
-->
<item>セクション 2 では SMP Linux システムを論じる。このシステムは、
	共有メモリを使って MIMD をそのまま実行できるが、メッセージ通信も
	簡単に実装できる。Linux は最大で 16 個のプロセッサの設定をサポート
	しているが、SMP PC システムの大部分は 2 もしくは 4 個の独立した
	プロセッサを搭載している

<!--
<item>Section 3 discusses clusters of networked machines, each running
Linux.  A cluster can be used as a parallel processing system that
directly supports MIMD execution and message passing, perhaps also
providing logically shared memory.  Simulated SIMD execution and
aggregate function communication also can be supported, depending on
the networking method used.  The number of processors in a cluster can
range from two to thousands, primarily limited by the physical wiring
constraints of the network.  In some cases, various types of machines
can be mixed within a cluster; for example, a network combining DEC
Alpha and Pentium Linux systems would be a <bf>heterogeneous
cluster</bf>.
-->
<item>セクション 3 ではネットワークに接続していて Linux が動作している
	マシンで構成するクラスタについて論じる。クラスタとは並列処理
	システムで用いられ、MIMD の実行とメッセージ通信、もちろん論理的な
	共有メモリもサポートする。SIMD の実行をシミュレートしたり、集合演算
	通信もサポートしているが、これはネットワークの手法に依存している。
	クラスタ当たりのプロセッサの数は 2 から 数千にまで及ぶが、数を制限
	する要因の第 1 はネットワークの取り回しである。1 つのクラスタに様々な
	タイプのマシンを組み込むことが可能である。例えば、DEC の Alpha と 
	Pentium の Linux システムで構成されたネットワークを<bf>異機種クラスタ
	</bf>と呼ぶ
	<p>
	【訳註：DEC は Compaq に吸収されましたが、Alpha マシンは健在です】

<!--
<item>Section 4 discusses SWAR, SIMD Within A Register.  This is a
very restrictive type of parallel execution model, but on the other
hand, it is a built-in capability of ordinary processors.  Recently,
MMX (and other) instruction set extensions to modern processors have
made this approach even more effective.
-->
<item>セクション 4 では、SWAR(SIMD Within A Register)を論じる。これは
	非常に制限のある並列実行モデルではあるが、一般的なプロセッサに組み込
	まれた機能でもある。最近では MMX(やその他類似の)命令セット拡張が
	プロセッサに加えられており、このアプローチがより有効になってきた

<!--
<item>Section 5 discusses the use of Linux PCs as hosts for simple
parallel computing systems.  Either as an add-in card or as an
external box, attached processors can provide a Linux system with
formidable processing power for specific types of applications.  For
example, inexpensive ISA cards are available that provide multiple DSP
processors offering hundreds of MFLOPS for compute-bound problems.
However, these add-in boards are <em>just</em> processors; they
generally do not run an OS, have disk or console I/O capability, etc.
To make such systems useful, the Linux "host" must provide these
functions.
-->
<item>セクション 5 では、Linux PC を単独の並列計算システムを動かすホスト
	として使用する方法を論じる。付加プロセッサは追加のカードもしくは外付け
	機器の形をとって、Linux に特定のタイプのアプリケーションの実行に対して
	圧倒的な処理パワーを提供する。例えば、安価な ISA カードを利用することで、
	そこに搭載している複数の DSP プロセッサを使って計算の比重が大きい問題
	に数 100 MFLOPS の能力を割くことができる。しかしこれらの追加のボード類
	は、<em>まさに</em>プロセッサそのものである。OS が動いているわけでも、
	ディスクや端末の入出力などがあるわけではない。
	そのようなシステムを活用するには、Linux という「ホスト」が上記の機能を
	提供する必要がある
</itemize>
<p>

<!--
The final section of this document covers aspects that are of general
interest for parallel processing using Linux, not specific to a
particular one of the approaches listed above.
-->
このドキュメントの最後のセクションでは、Linux を使った並列処理一般の
関連事項について、上記の特定のアプローチにかかわり無くその特徴を取り
上げます。

<!--
As you read this document, keep in mind that we haven't tested
everything, and a lot of stuff reported here "still has a research
character" (a nice way to say "doesn't quite work like it should" ;-).
However, parallel processing using Linux is useful now, and an
increasingly large group is working to make it better.
-->
このドキュメントを読むに当たって気に止めておいて欲しいことは、すべて
を検証してあるわけではない、ということです。またここであげた多くの事柄
は「まだまだ研究中のものです」(「思うようには動かない」といった方が適切
です ;-)
しかし Linux を使った並列処理は現状でも役に立ちますし、並列処理をより
良いものにするべく、グループとしての活動があちこちで増えつつあります。

<!--
The author of this HOWTO is Hank Dietz, Ph.D., currently Associate
Professor of Electrical and Computer Engineering at Purdue University,
in West Lafayette, IN, 47907-1285.  Dietz retains rights to this
document as per the Linux Documentation Project guidelines.  Although
an effort has been made to ensure the correctness and fairness of this
presentation, neither Dietz nor Purdue University can be held
responsible for any problems or errors, and Purdue University does not
endorse any of the work/products discussed.
-->
この HOWTO の著者は、博士号を持つ Hank Dietz で、現在インディアナ州の 
郵便番号 47907-1285、ウエストラファイエットにあるパーデュ大学において、
Electrical and Computer Engineering の助教授をしています。Dietz はこの
ドキュメントに対して、the Linux Documentation Project のガイドラインに
準拠した権利を有しています。
このドキュメントの発表に当たって、正確で公正になるように努力しましたが、
Dietz 氏およびパーデュ大学はいかなる問題や誤りに対して責任を負えないだけ
でなく、パーデュ大学はここで議論された研究やその成果物に対して、何も保証
しません。
<p>
【訳註：著者の Hank Dietz 氏は、1999 年 9 月にケンタッキー大学に
異動され、それにともない研究活動の中心も同大学に移りました。このドキュメント
でも述べられている彼自身の並列処理の研究は、
<url url="http://aggregate.org/KAOS/" name="KAOS"> グループで継続されて
います。その成果物として 
<url url="http://aggregate.org/KLAT2/" name="KLAT2"> 等が稼働しています。
KLAT2 は、<url url="http://www.sc2000.org/" name="IEEE/ACM SC2000"> にて 
Gordon Bell Award を受けています。パーデュ大学での成果及び最近の研究に
ついては、<url url="http://aggregate.org/" name="The Aggregate"> で見る
ことができます】

<sect>SMP Linux
<p>

<!--
This document gives a brief overview of how to use <url
url="http://www.uk.linux.org/SMP/title.html" name="SMP Linux"> systems
for parallel processing.  The most up-to-date information on SMP Linux
is probably available via the SMP Linux project mailing list; send
email to <htmlurl url="mailto:majordomo@vger.rutgers.edu"
name="majordomo@vger.rutgers.edu"> with the text <tt>subscribe
linux-smp</tt> to join the list.
-->
このドキュメントでは、
<!--
<url url="http://www.uk.linux.org/SMP/title.html" name="SMP Linux"> 
-->
<url url="http://www.linux.org.uk/SMP/title.html" name="SMP Linux"> 
システムを並列処理に使う方法について、要点をかいつまんで見ていきます。
SMP Linux の最新の情報は、SMP Linux プロジェクトのメーリングリスト
で得られます。majordomo@vger.rutgers.edu に <tt>subscribe linux-smp</tt> 
と書いて電子メールを送ると参加できます。

<!--
Does SMP Linux really work?  In June 1996, I purchased a brand new
(well, new off-brand ;-) two-processor 100MHz Pentium system.  The
fully assembled system, including both processors, Asus motherboard,
256K cache, 32M RAM, 1.6G disk, 6X CDROM, Stealth 64, and 15" Acer
monitor, cost a total of &dollar;1,800.  This was just a few hundred
dollars more than a comparable uniprocessor system.  Getting SMP Linux
running was simply a matter of installing the "stock" uniprocessor
Linux, recompiling the kernel with the <tt>SMP=1</tt> line in the
makefile uncommented (although I find setting <tt>SMP</tt> to
<tt>1</tt> a bit ironic ;-), and informing <tt>lilo</tt> about the new
kernel.  This system performs well enough, and has been stable enough,
to serve as my primary workstation ever since.  In summary, SMP Linux
really does work.
-->
SMP Linux は本当に動作するのでしょうか？ 1996 年 6 月に新品の(実はノー
ブランド ;-)100MHz 駆動の Pentium を 2 個搭載したシステムを購入しました。
パーツから組み上げたシステムで、プロセッサと Asus のマザーボード、256 K 
のキャッシュ、32 MB の RAM、1.6 GB のディスク、6 倍速の CD-ROM、ビデオ
カードに Stealth 64、15 インチの Acer のモニターがついて、合計 1,800 
ドルでした。プロセッサが 1 つのシステムと比べて数 100 ドル高くなりました。
SMP Linux を動かすのは難しいことではなく、単独プロセッサ用の「普通について
くる」Linux をインストールして、makefile にある <tt>SMP=1</tt> という行
のコメントを外して、カーネルを再コンパイルし(<tt>SMP</tt> を <tt>1</tt> 
に設定とは、ちょっと皮肉ですね ;-)、<tt>lilo</tt> に新しいカーネルを設定
すればいいだけです。このシステムのパフォーマンスは申し分なく、安定性も
十分です。それ以来メインのワークステーションとして活躍しています。つまり
SMP Linux は実際に動いているのです。

<!--
The next question is how much high-level support is available for
writing and executing shared memory parallel programs under SMP Linux.
Through early 1996, there wasn't much.  Things have changed.  For
example, there is now a very complete POSIX threads library.
-->
次にわからないのは、はたして SMP Linux でどの程度のレベルの高さ
で共有メモリを使った並列プログラムをコーディングして実行できるかと
いうことでしょう。
1996 年前半では、まだ十分とはいえませんでした。しかし状況は変わりました。
例えば、現在では極めて完成度が高い POSIX スレッドライブラリがあります。

<!--
Although performance may be lower than for native shared-memory
mechanisms, an SMP Linux system also can use most parallel processing
software that was originally developed for a workstation cluster using
socket communication.  Sockets (see section 3.3) work within an SMP
Linux system, and even for multiple SMPs networked as a cluster.
However, sockets imply a lot of unnecessary overhead for an SMP.  Much
of that overhead is within the kernel or interrupt handlers; this
worsens the problem because SMP Linux generally allows only one
processor to be in the kernel at a time and the interrupt controller
is set so that only the boot processor can process interrupts.
Despite this, typical SMP communication hardware is so much better
than most cluster networks that cluster software will often run better
on an SMP than on the cluster for which it was designed.
-->
本来の共有メモリ方式と比べてパフォーマンスは劣りますが、SMP Linux 
システムでは、もともとソケット通信を使ったワークステーション上で動く
クラスタ用に開発した並列処理用のソフトウェアのほとんどを利用できます。
ソケット(セクション 3.3 を参照のこと)は、単独の SMP Linux 上で動作し、
クラスタをネットワーク上で組んだ複数の SMP マシンでも動作します。
しかし、ソケットは SMP にとっては必要ないオーバーヘッドがかなり多く
あります。オーバーヘッドのかなりの部分はカーネルや割り込み制御にあり
ます。これが問題をさらに悪化させています。というのも、通常 SMP Linux 
は、カーネル内で同時に動作できるプロセッサは 1 つだけで、割り込み
コントローラとして設定できるプロセッサもたった 1 つだけなのです。
つまりブートしたプロセッサしか割り込みをかけられません。
それにもかかわらず、標準的な SMP の通信機器は、大部分のクラスタを組んだ
ネットワークよりも優れています。クラスタ用に設計されたソフトウェアが、
クラスタ上で動くよりも SMP 上の方がうまく動作することが多いようです。
<p>
【訳註：Linux のカーネルが 2.4 になり SMP 対応が改良されました。
2.2 系列以前では、システムコールが呼び出されるとそれが動いているプロセッサ
がカーネルを離すまでカーネル全体にロックをかけていました。
つまり他のプロセッサがカーネルを利用しようとしても(システムコールを発行
しても)、カーネルのロックがはずれるまで(現在動いているシステムコールの
処理が終わるまで)処理待ちになっていました。2.4 系列ではカーネル全体ではなく、
カーネル内部でプロセッサ間で共有している資源単位でのロックが可能になりました。
ただしすべてが資源単位でのロックに変更されたわけではなく、依然としてカーネル
をロックする部分もあります。
割り込みについても、それぞれのプロセッサからかけることが可能になりました】

<!--
The remainder of this section discusses SMP hardware, reviews the
basic Linux mechanisms for sharing memory across the processes of a
parallel program, makes a few observations about atomicity, volatility,
locks, and cache lines, and finally gives some pointers to other
shared memory parallel processing resources.
-->
このセクションの残りの部分では、SMP のハードウェアについて論じ、Linux で
並列プログラムのプロセスがメモリを共有し合う基本的なしくみを見て行くこと
にします。アトミックな処理や変数の保存、資源のロック、キャッシュ・ライン
について 少し意見を述べて、最後に他の共有メモリ並列処理についての資料を
いくつか紹介したいと思います。

<!-- <sect1>SMP Hardware -->
<sect1>SMP のハードウェア
<p>

<!--
Although SMP systems have been around for many years, until very
recently, each such machine tended to implement basic functions
differently enough so that operating system support was not portable.
The thing that has changed this situation is Intel's Multiprocessor
Specification, often referred to as simply <bf>MPS</bf>.  The MPS 1.4
specification is currently available as a PDF file at <url
url="http://www.intel.com/design/pro/datashts/242016.htm">, and there
is a brief overview of MPS 1.1 at <url
url="http://support.intel.com/oem&lowbar;developer/ial/support/9300.HTM">,
but be aware that Intel does re-arrange their WWW site often.  A wide
range of <url url="http://www.uruk.org/~erich/mps-hw.html"
name="vendors"> are building MPS-compliant systems supporting up to
four processors, but MPS theoretically allows many more processors.
-->
SMP システムはもう何年も動き続けていますが、つい最近まで基本的な機能の
実装がそれぞれのマシンで異なる傾向にあったため、オペレーティングシステム
のサポートは移植性があるとは言えませんでした。
この状況が変わるきっかけになったのが、<bf>MPS</bf> と呼ばれる Intel の 
Multiprocessor Specification です。MPS 1.4 の仕様は、PDF ファイルで
<url url="http://www.intel.com/design/pro/datashts/242016.htm"> から利用
できます。また MPS 1.1 についての概要が <url 
url="http://support.intel.com/oem&lowbar;developer/ial/support/9300.HTM">
【訳註：リンク切れ】にあります。ただ、intel の WWW サイトはよく構成を変える
ので注意してください。
プロセッサを最大 4 つまで搭載する MPS 互換のシステムは、数多くの<url 
url="http://www.uruk.org/~erich/mps-hw.html" name="ベンダー">が構築して
います。しかし MPS は理論上もっと多数のプロセッサをサポートしています。

<!--
The only non-MPS, non-IA32, systems supported by SMP Linux are Sun4m
multiprocessor SPARC machines.  SMP Linux supports most Intel MPS
version 1.1 or 1.4 compliant machines with up to sixteen 486DX,
Pentium, Pentium MMX, Pentium Pro, or Pentium II processors.
Unsupported IA32 processors include the Intel 386, Intel 486SX/SLC
processors (the lack of floating point hardware interferes with the
SMP mechanisms), and AMD &amp; Cyrix processors (they require
different SMP support chips that do not seem to be available at this
writing).
-->
非 MPS で 非 IA-32 なシステムで SMP Linux がサポートしているものは、
Sun4m を載せたマルチプロセッサの SPARC マシンです。SMP Linux は Intel 
の MPS バージョン 1.1 もしくは 1.4 互換のマシンをサポートしており、16 
個までの 486DX、Pentium、Pentium MMX、Pentium Pro、Pentium II をサポート
しています。
サポートしていない IA-32 プロセッサには、Intel の 386 と Intel の 486SX/SLC 
です(SMP のしくみと浮動小数点演算装置をつなぐインタフェースがありません)。
AMD と Cyrix プロセッサ(SMP をサポートするチップが異なるので、この
ドキュメントを書いている時点では利用できません)が上げられます。
<p>
【訳註：先に述べた <url url="http://aggregate.org/KLAT2/" 
name="KLAT2"> は、AMD の Athlon を搭載していて、SWAR として intel の MMX 
に加えて、AMD のマルチメディア拡張命令である 3DNow! も利用しています】

<!--
It is important to understand that the performance of MPS-compliant
systems can vary widely.  As expected, one cause for performance
differences is processor speed:  faster clock speeds tend to yield
faster systems, and a Pentium Pro processor is faster than a Pentium.
However, MPS does not really specify how hardware implements shared
memory, but only how that implementation must function from a software
point of view; this means that performance is also a function of how
the shared memory implementation interacts with the characteristics of
SMP Linux and your particular programs.
-->
大切なのは、MPS 互換のシステムのパフォーマンスが大きくばらつくことを
知っておくことです。皆さんの予想通り、プロセッサの速度はパフォーマンス
の差に影響を与える要因の 1 つです。クロック速度が速ければ速いほど、より
高速なシステムになる傾向にありますし、Pentium Pro は Pentium よりも高速
です。しかし MPS 自体は共有メモリの実装がどのようであるかについて仕様
を決めているわけではなく、ただソフトウェアの点からどのように実装が機能
すべきなのかを決めているに過ぎません。つまりパフォーマンスとは、共有メモリ
の実装がどのように SMP Linux やユーザのプログラムの特性と相互に連係して
いるかの結果でもあります。

<!--
The primary way in which systems that comply with MPS differ is in how
they implement access to physically shared memory.
-->
まず MPS に準拠したシステムそれぞれで見なければいけないのは、どのように
システムが物理的な共有メモリにアクセスできるのかということです。

<!-- <sect2>Does each processor have its own L2 cache?  -->
<sect2>それぞれのプロセッサは独自の L2 キャッシュを持っているか？
<p>

<!--
Some MPS Pentium systems, and all MPS Pentium Pro and Pentium II
systems, have independent L2 caches.  (The L2 cache is packaged within
the Pentium Pro or Pentium II modules.)  Separate L2 caches are
generally viewed as maximizing compute performance, but things are not
quite so obvious under Linux.  The primary complication is that the
current SMP Linux scheduler does not attempt to keep each process on
the same processor, a concept known as <bf>processor affinity</bf>.
This may change soon; there has recently been some discussion about
this in the SMP Linux development community under the title "processor
binding."  Without processor affinity, having separate L2 caches may
introduce significant overhead when a process is given a timeslice on
a processor other than the one that was executing it last.
-->
MPS Pentium の一部やすべての MPS Pentium Pro、Pentium II システムは、
独立した L2 キャッシュを持っています(Pentium Pro や Pentium II はモ
ジュールに組み込まれています)。独立した L2 キャッシュは一般的に
コンピュータのパフォーマンスを最大限に引き出すと見なされていますが、Linux 
ではそれほど単純ではありません。複雑にしている第 1 の原因は、現状の SMP 
Linux のスケジューラがプロセスそれぞれを同じプロセッサに割り当て続け
ないようにしている点にあります。これは<bf>プロセッサ・アフィニティ</bf>
と呼ばれている考え方です。
これはすぐにでも変更されるかもしれません。最近「プロセッサ・バインディ
ング」というタイトルで、SMP Linux の開発コミュニティでこの考え方が
何度か議論されました。プロセッサ・アフィニティがないと、独立した 
L2 キャッシュが存在した場合無視できないオーバーヘッドが発生してしま
います。それは、あるプロセスが最後に実行していたプロセッサではなく、
別のプロセッサでタイムスライスを割り当てられた場合に発生します。
<p>
【訳註：カーネル2.2系列では、特定の CPU に特定のプロセスを割り
当てることは標準ではできませんが、パッチとして PSET - Processor Sets 
for the Linux kernel(<url url="http://isunix.it.ilstu.edu/~thockin/pset/">) 
が用意されています。
2.4 系列では、プロセスを同じプロセッサになるべく処理させるように
スケジューリング方法が変更されています。またプロセッサ・バインディング
は、割り込みについては実装されており、プロセスについては検討中です】

<!--
Many relatively inexpensive systems are organized so that two Pentium
processors share a single L2 cache.  The bad news is that this causes
contention for the cache, seriously degrading performance when running
multiple independent sequential programs.  The good news is that many
parallel programs might actually benefit from the shared cache because
if both processors will want to access the same line from shared
memory, only one had to fetch it into cache and contention for the bus
is averted.  The lack of processor affinity also causes less damage
with a shared L2 cache.  Thus, for parallel programs, it isn't really
clear that sharing L2 cache is as harmful as one might expect.
-->
比較的安価なシステムの多くは、1 つの L2 キャッシュを 2 つの Pentium 
プロセッサで共有しています。困ったことにキャッシュの競合が発生して、複数
の独立した順次処理をするプログラムに対して深刻なパフォーマンスの低下を引き
起こします。逆に良い点は、並列プログラムの多くが実際に共有したキャッシュ
の恩恵を受ける可能性があることです。というのは、両方のプロセッサが
共有メモリの同じラインにアクセスしようとする場合、キャッシュにデータを
フェッチしなければならないのは 1 つのプロセッサだけで、バスの競合が避けられ
ます。プロセッサ・アフィニティがなければ、共有の L2 キャッシュのデータ
不整合をより低く押えることもできます。つまり並列処理にとって、予想していた
ほど、共有の L2 キャッシュに欠点があるとは断定できません。

<!--
Experience with our dual Pentium shared 256K cache system shows quite
a wide range of performance depending on the level of kernel activity
required.  At worst, we see only about 1.2x speedup.  However, we also
have seen up to 2.1x speedup, which suggests that compute-intensive
SPMD-style code really does profit from the "shared fetch" effect.
-->
私達が所有している 2 つの Pentium を搭載した 256 K のキャッシュを持つ
システムを使用した経験からすると、パフォーマンスに非常にばらつきがあり、
その原因はカーネルが負う処理のレベルに依存しています。最悪で約 1.2 倍
の速度向上にしかなりません。しかし 2.1 倍まで高速化ができたことから、
計算中心の SPMD スタイルのコードはまさに「フェッチの共有」効果がでて
いることになります。

<!-- <sect2>Bus configuration?  -->
<sect2>バスの構成？
<p>

<!--
The first thing to say is that most modern systems connect the
processors to one or more PCI buses that in turn are "bridged" to one
or more ISA/EISA buses.  These bridges add latency, and both EISA and
ISA generally offer lower bandwidth than PCI (ISA being the lowest), so
disk drives, video cards, and other high-performance devices generally
should be connected via a PCI bus interface.
-->
最近の大部分のシステムでは、プロセッサに 1 つ以上の PCI バスが接続して
いて、その PCI バスに 1 つ以上の ISA や EISA バスが「ブリッジ」しています。
これらのブリッジが遅延を引き起こし、さらに EISA と ISA は PCI に比べて帯域
も狭くなります(ISA が最も遅い)。そのためディスクドライブやビデオカード他の
高いパフォーマンスを必要とするデバイスは、普通 PCI バスインタフェース経由
で接続すべきです。

<!--
Although an MPS system can achieve good speed-up for many
compute-intensive parallel programs even if there is only one PCI bus,
I/O operations occur at no better than uniprocessor performance...
and probably a little worse due to bus contention from the
processors.  Thus, if you are looking to speed-up I/O, make sure that
you get an MPS system with multiple independent PCI busses and I/O
controllers (e.g., multiple SCSI chains).  You will need to be careful
to make sure SMP Linux supports what you get.  Also keep in mind that
the current SMP Linux essentially allows only one processor in the
kernel at any time, so you should choose your I/O controllers
carefully to pick ones that minimize the kernel time required for each
I/O operation.  For really high performance, you might even consider
doing raw device I/O directly from user processes, without a system
call...  this isn't necessarily as hard as it sounds, and need not
compromise security (see section 3.3 for a description of the basic
techniques).
-->
MPS システムでは、PCI バスが 1 つしかなくても計算が多くを占める並列プロ
グラムを高速に実行できます。しかし入出力処理は、プロセッサが 1 つのもの
より良いとは言えません…恐らくプロセッサによるバスの競合で若干
パフォーマンスが落ちてしまいます。つまり入出力の速度向上に注目するとすれ
ば、複数の独立した PCI バスと入出力コントローラがある MPS システムを手に
入れる方が良いということになります(例えば複数の SCSI 接続)。ここで注意
しなければいけないのは、SMP Linux があなたが所有する部品をサポートして
いるか、ということです。また最新の SMP Linux が基本的にカーネル上では
常に 1 つのプロセッサしか動いていないということも忘れないでください。
そういう訳で、入出力コントローラには入出力処理それぞれに必要となるカーネル
の処理時間が最小のものを選ぶように心がけてください。本当に高性能を目指す
ならば、システムコールを使わないで、ユーザ・プロセスから直接 raw デバイス
を使って入出力することを考慮してもいいのではないでしょうか。これは思った
ほど難しいことではありませんし、セキュリティレベルを下げることにもなり
ません(セクション 3.3 で基本的なやり方を説明します)。

<!--
It is important to note that the relationship between bus speed and
processor clock rate has become very fuzzy over the past few years.
Although most systems now use the same PCI clock rate, it is not
uncommon to find a faster processor clock paired with a slower bus
clock.  The classic example of this was that the Pentium 133 generally
used a faster bus than a Pentium 150, with appropriately
strange-looking performance on various benchmarks.  These effects are
amplified in SMP systems; it is even more important to have a faster
bus clock.
-->
バスの速さとプロセッサのクロックの速さの関係がここ数年でいびつになって
いることをぜひ知っておいてください。
現状ではシステムの大部分は同一の PCI のクロック速度を使用していますが、
高速なプロセッサのクロックと低速なバスのクロックの組合せは、まれなケース
とは言えません。Pentium 133 は Pentium 150 より速いバスを
採用しており、様々なベンチマークで一見不思議な結果を出しているのが良い例
です。これらの影響は SMP システムではさらに大きくなります。より速いバス・
クロックがより重要なのです。
<p>
【訳註：Pentium 133 は 66 MHz の 2 倍速、Pentium 150 は 60 MHz の 
2.5 倍速で駆動します】

<!-- <sect2>Memory interleaving and DRAM technologies?  -->
<sect2>メモリのインタリーブと DRAM の技術？
<p>

<!--
Memory interleaving actually has nothing whatsoever to do with MPS,
but you will often see it mentioned for MPS systems because these
systems are typically more demanding of memory bandwidth.  Basically,
two-way or four-way interleaving organizes RAM so that a block access
is accomplished using multiple banks of RAM rather than just one.
This provides higher memory access bandwidth, particularly for cache
line loads and stores.
-->
本来、メモリをインタリーブすることは MPS とは何の関係もありませんが、
MPS システムではよく触れられる話です。というのも、これらのシステムは
往々にしてメモリの帯域幅をより必要とするからです。普通は、2 way もしくは 
4 way をインタリーブして RAM を構成します。そのためブロック・アクセスは、
1 つのバンクだけではなく、複数のバンクを使用します。
これによって、より広い帯域幅でメモリにアクセスでき、とりわけキャッシュ
のロードやストアに効果があります。
<p>
【訳註：インタリーブとは、メモリ上のデータ読み書きの高速化を
はかるための方法の 1 つで、搭載されているメモリをグループ分けします。
このグループをバンクと呼び、このバンク単位に並列にアクセスする方式を
とります。 2 way は 2 バンク、4 way は 4 バンクにメモリをグループに
分けて並列にアクセスします】

<!--
The waters are a bit muddied about this, however, because EDO DRAM and
various other memory technologies tend to improve similar kinds of
operations.  An excellent overview of DRAM technologies is given in
<url url="http://www.pcguide.com/ref/ram/tech.htm">.
-->
しかしこの効果については、状況が少々混沌としてきました。その理由は、
EDO DRAM と他の様々なメモリ関連技術が同じような種類の操作に改良
を加えてきているためです。DRAM 技術についてとてもよくまとめられた
資料が、
<url url="http://www.pcguide.com/ref/ram/tech.htm"> で見られます。 

<!--
So, for example, is it better to have 2-way interleaved EDO DRAM or
non-interleaved SDRAM?  That is a very good question with no simple
answer, because both interleaving and exotic DRAM technologies tend to
be expensive.  The same dollar investment in more ordinary memory
configurations generally will give you a significantly larger main
memory.  Even the slowest DRAM is still a heck of a lot faster than
using disk-based virtual memory....
-->
それでは、2 way でインタリーブしている EDO DRAM とインタリーブして
いない SDRAM ではどちらがパフォーマンスが優れているでしょうか？ この
質問はとてもいい質問なのですが、簡単には答えらえません。というのも、
インタリーブするのも、魅力ある DRAM 技術も、とても高価になりがちだから
です。同じお金をかけて普通のメモリを購入すれば、より多くのメモリを
確保できるのは明らかです。一番遅い DRAM でも、ディスクベースの仮想
メモリより比べものにならないほど高速です…。
<p>
【訳註：SDRAM と EDO RAM の大きな違いは、SDRAM は PC のベース
クロックと同期して動作するのに対して、EDO RAM はベースクロックとは非
同期に動作する点にあります。しかし SDRAM もはじめのアドレスにあるデータ
にアクセスする時には EDO DRAM と同様に遅延(RAS、CASの)が発生します。次
世代メモリと言われる RDRAM もより広いメモリ帯域幅が実現できますが、DRAM 
を使用することにはかわりなく、やはり遅延が発生してしまいます。
つまり、現在までのメモリの高速化はバーストモードの高速化が中心であって、
DRAM 自体が抱えている遅延の問題を根本的に見直しているわけではありません】

<!-- <sect1>Introduction To Shared Memory Programming -->
<sect1>共有メモリを使ったプログラミングをはじめるにあたって
<p>

<!--
Ok, so you have decided that parallel processing on an SMP is a great
thing to do...  how do you get started?  Well, the first step is to
learn a little bit about how shared memory communication really works.
-->
そろそろ並列処理を SMP で動かすことが、いかに素晴らしいかを理解できたと
思いますが…。どこからはじめたらいいでしょうか？ まずは共有メモリ通信が
実際にどのように動くのか、少しばかり勉強してみましょう。

<!--
It sounds like you simply have one processor store a value into memory
and another processor load it; unfortunately, it isn't quite that
simple.  For example, the relationship between processes and
processors is very blurry; however, if we have no more active
processes than there are processors, the terms are roughly
interchangeable.  The remainder of this section briefly summarizes the
key issues that could cause serious problems, if you were not aware of
them:  the two different models used to determine what is shared,
atomicity issues, the concept of volatility, hardware lock
instructions, cache line effects, and Linux scheduler issues.
-->
あるプロセッサが値をメモリにストアして、あるプロセッサがそれをロード
する―こう言うと単純なことに思われるかもしれませんが、残念ながらそれほど
単純ではありません。例えば、プロセスとプロセッサの関係はきっちり決って
いるわけではありません。しかし、プロセッサの個数以上にプロセスが動いて
いないなら、プロセスとプロセッサという言葉を入れ換えてしまっても、
おおざっぱに言って同じことです。このセクションの残りの部分では、大きな
問題になると思われるキーポイントを概観して、ポイントを外したままになら
ないようにしたいと思います。何を共有すべきかを決めるのに使われるモデルを 
2 つと、アトミックな操作、変数の保存のしかた、ハードウェアのロック操作、
キャッシュ・ラインの効果、Linux におけるプロセスのスケジューリングを
扱います。

<!-- <sect2>Shared Everything Vs. Shared Something -->
<sect2>すべてを共有するのか、一部を共有するのか
<p>

<!--
There are two fundamentally different models commonly used for shared
memory programming:  <bf>shared everything</bf> and <bf>shared
something</bf>.  Both of these models allow processors to communicate
by loads and stores from/into shared memory; the distinction comes in
the fact that shared everything places all data structures in shared
memory, while shared something requires the user to explicitly
indicate which data structures are potentially shared and which are
<bf>private</bf> to a single processor.
-->
共有メモリを使うプログラミングには、根本的に異なる 2 つのモデルがあり
ます。それは<bf>すべてを共有する</bf>場合と<bf>一部を共有する</bf>場合
です。この 2 つのモデルとも、プロセッサが共有メモリからもしくは共有
メモリへロードやストアをしてやりとりできます。違うところは、すべてを
共有する場合がデータ構造すべてを共有メモリに置くのに対して、一部を共有
する場合は、ユーザがはっきりとどのデータ構造が共有メモリを使用する可能性
があり、どのデータ構造が単一プロセッサの<bf>ローカルな</bf>メモリを使用
するかを示す必要があります。

<!--
Which shared memory model should you use?  That is mostly a question of
religion.  A lot of people like the shared everything model because
they do not really need to identify which data structures should be
shared at the time they are declared...  you simply put locks around
potentially-conflicting accesses to shared objects to ensure that only
one process(or) has access at any moment.  Then again, that really
isn't all that simple...  so many people prefer the relative safety of
shared something.
-->
どちらの共有メモリモデルを使うべきでしょうか？ たいていの場合は好みの
問題と言ってもいいと思います。すべてを共有するモデルを好む人々が多いの
は、データ構造のどれが宣言されたその時に共有されるべきか、ということを
区別する必要がまったくないからです。ただ競合しそうなアクセスにロックを
かけて、共有しているものが 1 つのプロセス(プロセッサ)からしか一時に
アクセスしないようにします。繰り返しますが、これも上記のように単純なわけ
ではありません。そこで、比較的安全である共有するものを一部にとどめる方法
を選ぶ人々が多数いるのです。

<!-- <sect3>Shared Everything -->
<sect3>すべてを共有する
<p>

<!--
The nice thing about sharing everything is that you can easily take an
existing sequential program and incrementally convert it into a shared
everything parallel program.  You do not have to first determine which
data need to be accessible by other processors.
-->
すべてを共有する利点は、既にある順次実行プログラムがたやすく手に入ること、
そしてそのプログラムをすべてを共有することを前提にした並列プログラムに、
それほど手間をかけず修正していける点にあります。どのデータが他のプロセッサ
によってアクセスされるかを最初から解決する必要はありません。

<!--
Put simply, the primary problem with sharing everything is that any
action taken by one processor could affect the other processors.  This
problem surfaces in two ways:
-->
簡単に言うと、すべてを共有する上で大きな問題となるのは、あるプロセッサが
処理したことすべてが他のプロセッサに影響を与えてしまうかもしれない点
にあります。この問題が顕著になるケースは 2 つあります。

<itemize>
<!--
<item>Many libraries use data structures that simply are not
sharable.  For example, the UNIX convention is that most functions can
return an error code in a variable called <tt>errno</tt>; if two shared
everything processes perform various calls, they would interfere with
each other because they share the same <tt>errno</tt>.  Although there
is now a library version that fixes the <tt>errno</tt> problem,
similar problems still exist in most libraries.  For example, unless
special precautions are taken, the X library will not work if calls
are made from multiple shared everything processes.
-->
<item>ライブラリの多くは、データ構造が共有されることを前提にしていない。
	例えば、UNIX の慣習として関数の多くは <tt>errno</tt> と呼ばれる変数
	でエラー・コードを返す。すべてを共有している 2 つのプロセスが、様々
	なシステムコールを発行した場合、同じ <tt>errno</tt> を共有してしまい、
	お互いに干渉しあってしまうかもしれない。現在ではこの <tt>errno</tt> 
	の問題を修正したバージョンのライブラリがあるが、同じような問題は依然
	として大部分のライブラリに残っている。例えば、特別な処置をしないと
	複数のすべてを共有するプロセスから X ライブラリを呼んでも動作しない
	のが常である

<!--
<item>Normally, the worst-case behavior for a program with a bad
pointer or array subscript is that the process that contains the
offending code dies.  It might even generate a <tt>core</tt> file that
clues you in to what happened.  In shared everything parallel
processing, it is very likely that the stray accesses will bring the
demise of <em>a process other than the one at fault</em>, making it
nearly impossible to localize and correct the error.
-->
<item>通常最悪のケースとなる動作は、プログラムがポインタや配列の予約を
	間違ってしまい、そのおかしなコードを含んだプロセスが死んでしまうこと
	である。そうすると、おそらく <tt>core</tt> ファイルができて、何が
	起こったかの手掛かりが得られる。すべてを共有する並列処理の場合は、
	不正なアクセスによって、<em>おかしなプロセス以外のプロセス</em>が死んで
	しまうかもしれず、エラーを特定したり、修正したりすることがほとんど
	不可能になる
</itemize>

<!--
Neither of these types of problems is common when shared something is
used, because only the explicitly-marked data structures are shared.
It also is fairly obvious that shared everything only works if all
processors are executing the exact same memory image; you cannot use
shared everything across multiple different code images (i.e., can use
only SPMD, not general MIMD).
-->
上記の類の問題は、一部を共有する方法をとった場合にはほとんど起こり
ません。それは、はっきりと指定したデータ構造だけを共有するためです。
また、すべてを共有する方法が動作するのは、プロセッサすべてが全く同じ
メモリ・イメージを実行している場合だけです。これはほとんど疑う余地が
ないことです。すべてを共有して複数の異なるコード・イメージを扱うこと
はできません(つまり、SPMD は利用できますが、MIMD はできません)。

<!--
The most common type of shared everything programming support is a
<bf>threads library</bf>.  <url
url="http://liinwww.ira.uka.de/bibliography/Os/threads.html"
name="Threads"> are essentially "light-weight" processes that might
not be scheduled in the same way as regular UNIX processes and, most
importantly, share access to a single memory map.  The POSIX <url
url="http://www.mit.edu:8001/people/proven/pthreads.html"
name="Pthreads"> package has been the focus of a number of porting
efforts; the big question is whether any of these ports actually run
the threads of a program in parallel under SMP Linux (ideally, with a
processor for each thread).  The POSIX API doesn't require it, and
versions like <url url="http://www.aa.net/~mtp/PCthreads.html">
apparently do not implement parallel thread execution - all the threads
of a program are kept within a single Linux process.
-->
すべてを共有する場合にプログラムがサポートする典型的なタイプが、<bf>
スレッド・ライブラリ</bf>です。<url 
url="http://liinwww.ira.uka.de/bibliography/Os/threads.html" 
name="Threads"> は、本来「軽量(light-weight)」なプロセスとして、通常
の UNIX 上のプロセスとは違ったスケジュールで動作していました。ここで
とても大切なのは、1 つのメモリ・マップを共有してアクセスする点にあります。
<!--
POSIX <url url="http://www.mit.edu:8001/people/proven/pthreads.html" 
name="Pthreads"> のパッケージは、移植に対してたいへん力を注いできました。
-->
POSIX <url url="http://www.gnu.ai.mit.edu/software/pth/" name="Pthreads"> 
のパッケージは、移植に対してたいへんな労力を注いできました。
ここで非常に疑問なのは、移植されたものが本当に SMP Linux 上のプログラム
のスレッドとして並列に動作するのか、ということです(理想的には、ある
プロセッサでそれぞれのスレッドが動作する)。POSIX API は、そこまでを
求めていませんし、<url url="http://www.aa.net/~mtp/PCthreads.html">
【訳註：リンク切れ】のようなバージョンは、スレッドを並列に実行することを
まったく考慮していません。プログラムから実行されるスレッドはすべて、Linux 
の 1 つのプロセス内で動き続けます。

<!--
The first threads library that supported SMP Linux parallelism was the
now somewhat obsolete bb&lowbar;threads library, <url
url="ftp://caliban.physics.utoronto.ca/pub/linux/">, a very small
library that used the Linux <tt>clone()</tt> call to fork new,
independently scheduled, Linux processes all sharing a single address
space.  SMP Linux machines can run multiple of these "threads" in
parallel because each "thread" is a full Linux process; the trade-off
is that you do not get the same "light-weight" scheduling control
provided by some thread libraries under other operating systems.  The
library used a bit of C-wrapped assembly code to install a new chunk
of memory as each thread's stack and to provide atomic access
functions for an array of locks (mutex objects).  Documentation
consisted of a <tt>README</tt> and a short sample program.
-->
SMP Linux の並列処理を最初にサポートしたスレッド・ライブラリは、既に
過去のものになりつつある bb&lowbar;threads ライブラリで、<url 
url="ftp://caliban.physics.utoronto.ca/pub/linux/"> にあります。これは
とても小規模なライブラリで Linux の <tt>clone()</tt> システムコールを
使い、新たに子プロセスを立ち上げた上で独自のスケジュールで動きます。
ここでは Linux のプロセスすべては 1 つのアドレス空間を共有します。
SMP Linux マシンでは、これらの「スレッド」を複数並行に動作することが
できます。理由は各々の「スレッド」が Linux のプロセスに他ならないから
です。これと引き換えに、他のオペレーティング・システムが提供している
いくつかのスレッド・ライブラリのような「軽量な」スケジュール制御は
できません。このライブラリは、C でラッパーしたアセンブリ・コードが少し
含まれていて、メモリ上にそれぞれのスレッドのスタック領域を確保し、
アトミックなアクセス機能をロックの配列(ミューテック、mutex)で実現します。
ドキュメントは、<tt>README</tt> と短いサンプル・プログラムがあります。

<!--
More recently, a version of POSIX threads using <tt>clone()</tt> has
been developed.  This library, <url
url="http://pauillac.inria.fr/~xleroy/linuxthreads/"
name="LinuxThreads">, is clearly the preferred shared everything
library for use under SMP Linux.  POSIX threads are well documented,
and the <url url="http://pauillac.inria.fr/~xleroy/linuxthreads/README"
name="LinuxThreads README"> and <url
url="http://pauillac.inria.fr/~xleroy/linuxthreads/faq.html"
name="LinuxThreads FAQ"> are very well done.  The primary problem now
is simply that POSIX threads have a lot of details to get right and
LinuxThreads is still a work in progress.  There is also the problem
that the POSIX thread standard has evolved through the standardization
process, so you need to be a bit careful not to program for obsolete
early versions of the standard.
-->
最近になって、<tt>clone()</tt> を使った POSIX スレッドが開発されてい
ます。このライブラリは <url 
url="http://pauillac.inria.fr/~xleroy/linuxthreads/" name="LinuxThreads"> 
で、SMP Linux で使用することを前提にしてすべてを共有することを主目的に
したライブラリです。POSIX スレッドはドキュメントが整備されており、<url 
url="http://pauillac.inria.fr/~xleroy/linuxthreads/README" 
name="LinuxThreads README"> や <url 
url="http://pauillac.inria.fr/~xleroy/linuxthreads/faq.html" 
name="LinuxThreads FAQ"> はとても良い資料です。現状での主な問題は、POSIX 
スレッドは内容が非常に濃いのために、きちんとその内容を理解する必要がある
こと、LinuxThreads は開発途中であることです。また、POSIX スレッド規格は、
標準化作業中という問題もあり、古くなった規格の初期バージョンで作成しない
ように少々注意が必要です。
<p>
【訳註：POSIX スレッドは IEEE 1003.1 として標準化されています。
 各種スレッドライブラリについては <url 
 url="http://www.gnu.org/software/pth/related.html" 
 name="Multithreading Libraries">、マルチスレッドのプログラミングについては
 <url 
url="http://docs.sun.com/ab2/coll.141.7/MTP/@Ab2TocView?Ab2Lang=ja&amp;Ab2Enc=shift_jis" name="マルチスレッドのプログラミング">が役に立ちます】

<!-- <sect3>Shared Something -->
<sect3>一部を共有する
<p>

<!--
Shared something is really "only share what needs to be shared."  This
approach can work for general MIMD (not just SPMD) provided that care
is taken for the shared objects to be allocated at the same places in
each processor's memory map.  More importantly, shared something makes
it easier to predict and tune performance, debug code, etc.  The only
problems are:
-->
実際のところ一部を共有するということは、「共有する必要があるものだけを
共有する」ということです。このアプローチは、一般的には MIMD(SPMD ではない)
に合致していて、それぞれのプロセッサのメモリ・マップ上で同じ位置にある共有
するオブジェクトを扱う点に注意が必要となります。もっと大切なのは、一部を共有
することでパフォーマンスの予測と改善やコードのデバック等が簡単になることです。
ただ問題になるのは、
<itemize>
<!--
<item>It can be hard to know beforehand what really needs to be shared.
-->
<item>何が本当に共有すべきなのかを前もって知ることが難しい

<!--
<item>The actual allocation of objects in shared memory may be awkward,
especially for what would have been stack-allocated objects.  For
example, it may be necessary to explicitly allocate shared objects in
a separate memory segment, requiring separate memory allocation
routines and introducing extra pointer indirections in each reference.
-->
<item>実際、共有メモリ上に割り付けられたオブジェクトは扱いづらく、特に
	スタック上にあるオブジェクトはなおさらである。例えば、共有される
	オブジェクトは、それぞれ独立したメモリセグメント上にきちんと配置する
	必要があるかもしれないし、それぞれのメモリセグメントに配置する作業や
	それぞれの参照情報の中にさらに余分に間接的なポインタを格納する必要が
	あるかもしれない
</itemize>

<!--
Currently, there are two very similar mechanisms that allow groups of
Linux processes to have independent memory spaces, all sharing only a
relatively small memory segment.  Assuming that you didn't foolishly
exclude "System V IPC" when you configured your Linux system, Linux
supports a very portable mechanism that has generally become known as
"System V Shared Memory."  The other alternative is a memory mapping
facility whose implementation varies widely across different UNIX
systems:  the <tt>mmap()</tt> system call.  You can, and should, learn
about these calls from the manual pages...  but a brief overview of
each is given in sections 2.5 and 2.6 to help get you started.
-->
現状では、Linux のプロセスグループを独立したメモリ空間に置くのに非常に
似かよった手法が 2 つあります。共有するものすべては、そのメモリ空間上で
はほんのわずかなセグメントを使用するだけです。Linux システムを設定する
時に「System V IPC」をうっかり外してしまわなければ、 Linux は「System V 
Shared Memory(共有メモリ)」というとても移植性が高いしくみを利用できる
ようになります。他の選択としてメモリのマッピング機能も利用でき、これは
いろいろな UNIX システム間でそれぞれ実装されています。それが <tt>mmap()</tt> 
システムコールです。マニュアルその他でこれらのシステムコールを学習する
ことをお勧めします。簡単な概略はセクションの 2.5 と 2.6 で触れますので、
勉強するきっかけとして利用してください。

<!-- <sect2>Atomicity And Ordering -->
<sect2>アトミックな処理と処理の順序
<p>

<!--
No matter which of the above two models you use, the result is pretty
much the same:  you get a pointer to a chunk of read/write memory that
is accessible by all processes within your parallel program.  Does
that mean I can just have my parallel program access shared memory
objects as though they were in ordinary local memory?  Well, not
quite....
-->
上記どちらのモデルを使うにしても、結果はそれほど違いません。要は並列
プログラムの中から、すべてのプロセッサがアクセスできる読み書き可能な
メモリの一部へのポインタを得るわけです。これが意味するところは、共有
メモリ上のオブジェクトをアクセスする並列プログラムが、そのオブジェクト
がローカルなメモリにあるかのごとく扱える、ということなのでしょうか？ 
そうとも言えるのですが、ちょっと違います…

<!--
<bf>Atomicity</bf> refers to the concept that an operation on an
object is accomplished as an indivisible, uninterruptible, sequence.
Unfortunately, sharing memory access does not imply that all
operations on data in shared memory occur atomically.  Unless special
precautions are taken, only simple load or store operations that occur
within a single bus transaction (i.e., aligned 8, 16, or 32-bit
operations, but not misaligned nor 64-bit operations) are atomic.
Worse still, "smart" compilers like GCC will often perform
optimizations that could eliminate the memory operations needed to
ensure that other processors can see what this processor has done.
Fortunately, both these problems can be remedied...  leaving only the
relationship between access efficiency and cache line size for us to
worry about.
-->
<bf>アトミックな処理</bf>というのは、ある対象に対する操作を部分に分け
たり、割り込みが入ったりすることなく、連続して処理をする考え方です。
残念ながら共有メモリのアクセスでは、共有メモリ上にあるデータに対する
すべての操作がアトミックに行われるわけではありません。何か手を打たない
限り、単純なロードやストア操作のようなバス上での処理が 1 回で済む操作
(つまり、8、16、32 ビットにアラインされた操作。アラインされていなかったり、
64 ビットの操作は異なる)だけが、アトミックな処理になります。
さらに都合が悪いことに、GCC のような「賢い」コンパイラでは最適化が働い
てしまい、あるプロセッサの処理が完了したことを他のプロセッサが検知する
のに必要となるメモリ上の操作を取り除いてしまいがちです。
幸いなことには、これらの問題 2 つとも改善することができます。気になる
アクセスの効率とキャッシュ・ラインの大きさの関係をそのままにして置くのです。

<!--
However, before discussing these issues, it is useful to point-out
that all of this assumes that memory references for each processor
happen in the order in which they were coded.  The Pentium does this,
but also notes that future Intel processors might not.  So, for future
processors, keep in mind that it may be necessary to surround some
shared memory accesses with instructions that cause all pending memory
accesses to complete, thus providing memory access ordering.  The
<tt>CPUID</tt> instruction apparently is reserved to have this
side-effect.
-->
しかしこれらの問題点を論じる前に、それぞれのプロセッサがメモリを参照
する時には、前提としてコーディングした順番で参照するということをはっきり
しておくことは無駄ではありません。Pentium がそうですが、将来の Intel の
プロセッサがそうであるとは限らない、ということも忘れないでください。
そのようなわけで、気に止めておいて欲しいことがあります。それは将来の
プロセッサが、保留しているメモリへのアクセスを完了させる命令を通じて
共有メモリにアクセスする必要が出てくるかもしれない、ということです。
つまり、メモリへのアクセスに順番を付ける機能を提供するわけです。<tt>CPUID
</tt> 命令は、その命令によって生じる悪影響に対しての予防処置であることは
明らかです。

<!-- <sect2>Volatility -->
<sect2>変数の保存のしかた
<p>

<!--
To prevent GCC's optimizer from buffering values of shared memory
objects in registers, all objects in shared memory should be declared
as having types with the <tt>volatile</tt> attribute.  If this is
done, all shared object reads and writes that require just one word
access will occur atomically.  For example, suppose that <em>p</em>
is a pointer to an integer, where both the pointer and the integer it
will point at are in shared memory; the ANSI C declaration might be:
-->
レジスタにある共有メモリのバッファされているオブジェクトの値を GCC が
最適化しないようにするには、共有メモリ上のすべての実体を <tt>volatile
</tt> という属性をつけて宣言する必要があります。こう宣言すると、共有
するオブジェクトに対する 1 ワードだけのアクセスをともなう読み書きは、
アトミックに行われます。例えば、<em>p</em> が整数へのポインタでポインタ
と整数両方が共有メモリにあるとすると、ANSI C での宣言は次のようになります。

<code>
volatile int * volatile p;
</code>

<!--
In this code, the first <tt>volatile</tt> refers to the <tt>int</tt>
that <tt>p</tt> will eventually point at; the second <tt>volatile</tt>
refers to the pointer itself.  Yes, it is annoying, but it is the
price one pays for enabling GCC to perform some very powerful
optimizations.  At least in theory, the <tt>-traditional</tt> option
to GCC might suffice to produce correct code at the expense of some
optimization, because pre-ANSI K&amp;R C essentially claimed that all
variables were volatile unless explicitly declared as
<tt>register</tt>.  Still, if your typical GCC compile looks like
<tt>cc -O6 <em>...</em></tt>, you really will want to explicitly mark
things as volatile only where necessary.
-->
このコードでは、最初の <tt>volatile</tt> は <tt>int</tt> を参照し、その 
<tt>int</tt> は <tt>p</tt> を指しています。次の <tt>volatile</tt> は、
ポインタそのものを参照しています。ややっこしいのですが、このちょっと
した指定で、GCC があちこちで強力に最適化することが可能になります。少なく
とも理屈上では、GCC に対して <tt>-traditional</tt> オプションをつける
ことで、最適化をいくぶん犠牲にして正しいコードを間違いなく生成できる
と思います。というのは、ANSI が定められる前の K&amp;R の C は、そもそも 
<tt>register</tt> と意図的に指定をしない限り、すべての変数を volatile 
扱いにしていました。GCC でコンパイルする場合に <tt>cc -O6 <em>...</em>
</tt> という様にしているなら、本当に必要な部分にははっきりと volatile 
と指定したくなるに違いありません。

<!--
There has been a rumor to the effect that using assembly-language
locks that are marked as modifying all processor registers will cause
GCC to appropriately flush all variables, thus avoiding the
"inefficient" compiled code associated with things declared as
<tt>volatile</tt>.  This hack appears to work for statically allocated
global variables using version 2.7.0 of GCC...  however, that behavior
is <em>not</em> required by the ANSI C standard.  Still worse, other
processes that are making only read accesses can buffer the values in
registers forever, thus <em>never</em> noticing that the shared memory
value has actually changed.  In summary, do what you want, but only
variables accessed through <tt>volatile</tt> are <em>guaranteed</em>
to work correctly.
-->
プロセッサのすべてのレジスタが更新されたことを知らせる役目であるアセンブリ
言語のロックを使うと、GCC が適切にすべての変数をフラッシュして、
<tt>volatile</tt> と宣言したことに関連したコードが「非効率」にコンパイル
されることを防ぐ、という噂があります。この裏技は、GCC のバージョン 2.7.0 
を使って static で確保した外部変数に対して効果を発揮します…がこれは ANSI 
C 標準に沿った機能では<em>ありません</em>し、なおまずいことに読み込みだけ
を行う他のプロセッサは、レジスタにずっと値をバッファしてしまいます。つまり、
共有メモリ上の値が変更されていることを<em>全く</em>知りようがありません。
まとめると、望みの動作を行うには <tt>volatile</tt> を使って変数にアクセス
するしか正しく動作することが<em>保証されない</em>、ということです。

<!--
Note that you can cause a volatile access to an ordinary variable by
using a type cast that imposes the <tt>volatile</tt> attribute.  For
example, the ordinary <tt>int i;</tt> can be referenced as a volatile
by <tt>*((volatile int *) &amp;i)</tt>; thus, you can explicitly
invoke the "overhead" of volatility only where it is critical.
-->
通常の変数に対して <tt>volatile</tt> 属性を指定してタイプキャストをする
ことで、volatile なアクセスが行えるということを理解しておいてください。
例えば、通常の <tt>int i;</tt> は <tt>*((volatile int *) &amp;i)</tt> 
とすることで、volatile に参照できるようになります。つまり、重要な部分に
対してだけ「オーバーヘッド」をともなう volatile な操作を意図して呼び
出すことができます。

<!-- <sect2>Locks -->
<sect2>ロック
<p>

<!--
If you thought that <tt>++i;</tt> would always work to add one to a
variable <tt>i</tt> in shared memory, you've got a nasty little
surprise coming:  even if coded as a single instruction, the load and
store of the result are separate memory transactions, and other
processors could access <tt>i</tt> between these two transactions.
For example, having two processes both perform <tt>++i;</tt> might
only increment <tt>i</tt> by one, rather than by two.  According to
the Intel Pentium "Architecture and Programming Manual," the
<tt>LOCK</tt> prefix can be used to ensure that any of the following
instructions is atomic relative to the data memory location it
accesses:
-->
<tt>++i;</tt> が、共有メモリにある変数 <tt>i</tt> に常に 1 を加える
と思っているなら、「なんだ、これは」という事態になります。単一な命令
を実行するようにコーディングされていても、ロードやストアは結果的に独立
してメモリに対する命令を発行し、他のプロセッサは <tt>i</tt> に対する
この 2 つの命令の間にアクセスできてしまいます。例えば、2 つのプロセスが
両者から <tt>++i;</tt> を実行すると、<tt>i</tt> は 2 増えるのではなく、
1 増えることになるかもしれません。Intel による Pentium の「Architecture 
and Programming Manual」によると、<tt>LOCK</tt> という単語が頭について
いると、その後にくる命令が何であっても、メモリ上のデータへのアクセスに
関連する操作はアトミックであることが保証されています。

<code>
BTS, BTR, BTC                     mem, reg/imm
XCHG                              reg, mem
XCHG                              mem, reg
ADD, OR, ADC, SBB, AND, SUB, XOR  mem, reg/imm
NOT, NEG, INC, DEC                mem
CMPXCHG, XADD
</code>

<!--
However, it probably is not a good idea to use all these operations.
For example, <tt>XADD</tt> did not even exist for the 386, so coding
it may cause portability problems.
-->
しかしこれらの命令を全面的に採用することは、良い思い付きとはいえない
でしょう。例えば、<tt>XADD</tt> は 386 プロセッサでは使用できません
ので、移植の面で問題が生じてしまうでしょう。

<!--
The <tt>XCHG</tt> instruction <em>always</em> asserts a lock, even
without the <tt>LOCK</tt> prefix, and thus is clearly the preferred
atomic operation from which to build higher-level atomic constructs
such as semaphores and shared queues.  Of course, you can't get GCC to
generate this instruction just by writing C code...  instead, you must
use a bit of in-line assembly code.  Given a word-size volatile object
<em>obj</em> and a word-size register value <em>reg</em>, the GCC
in-line assembly code is:
-->
<tt>XCHG</tt> 命令は、<tt>LOCK</tt> という単語が頭についていなくても
<em>常に</em>ロックをかけますし、この方法は明らかにアトミックな操作と
して、より高級なアトミックのしくみであるセマフォやキューの共有よりも
優れています。もちろん C でコーディングしたものを GCC にかけても、この
命令は生成できません…そのかわりに、少しばかりインラインでアセンブリ・
コードの記述が必要になります。1 ワードの volatile なオブジェクトである 
<em>obj</em> とやはり 1 ワードのレジスタ値である <em>reg</em> を定義
すると、GCC のインラインでのアセンブリ・コードは下記のようになります。

<code>
__asm__ __volatile__ ("xchgl %1,%0"
                      :"=r" (reg), "=m" (obj)
                      :"r" (reg), "m" (obj));
</code>

<!--
Examples of GCC in-line assembly code using bit operations for locking
are given in the source code for the <url
url="ftp://caliban.physics.utoronto.ca/pub/linux/"
name="bb&lowbar;threads library">.
-->
GCC のインラインのアセンブリ・コードで、ビット操作を使ってロックを
かける例は、<url url="ftp://caliban.physics.utoronto.ca/pub/linux/" 
name="bb&lowbar;threads library"> にあります。

<!--
It is important to remember, however, that there is a cost associated
with making memory transactions atomic.  A locking operation carries a
fair amount of overhead and may delay memory activity from other
processors, whereas ordinary references may use local cache.  The best
performance results when locking operations are used as infrequently
as possible.  Further, these IA32 atomic instructions obviously are not
portable to other systems.
-->
しかし、おぼえておいて欲しいことがあります。それはメモリ操作をアトミック
に行うと、それなりにコストがかかるということです。ロックをかける操作は
かなり大きなオーバーヘッドがかかり、通常の参照がローカルなキャッシュを
利用するのに比べ、他のプロセッサからのメモリ参照は遅延が生じてしまうこと
になるでしょう。最適なパフォーマンスを得るには、できるだけロック操作を
使用しないことです。また、これら IA32 でのアトミックな命令は、当然ですが
他のシステムには移植できません。

<!--
There are many alternative approaches that allow ordinary instructions
to be used to implement various synchronizations, including <bf>mutual
exclusion</bf> - ensuring that at most one processor is updating a
given shared object at any moment.  Most OS textbooks discuss at least
one of these techniques.  There is a fairly good discussion in the
Fourth Edition of <em>Operating System Concepts</em>, by Abraham
Silberschatz and Peter B. Galvin, ISBN 0-201-50480-4.
-->
この他にも解決方法はいろいろあります。通常の命令に対して、同期をいろいろ
ととるための実装がいくつも用意されています。その中には <bf>相互排他
(mutual exclusion。略称 mutex))</bf>があり、少なくとも 1 つのプロセッサ
がいつでも共有しているオブジェクトを更新できることを保証しています。
たいていの OS のテキストでは、これらのテクニックの内のいくつかを論じて
います。Abraham Silberschatz 氏 と Peter B. Galvin 氏の共著である、
<em>Operating System Concepts</em>、ISBN 0-201-50480-4 の第 4 版で非常に
優れた議論がなされています。

<!-- <sect2>Cache Line Size -->
<sect2>キャッシュ・ラインの大きさ
<p>
<!--
One more fundamental atomicity concern can have a dramatic impact on
SMP performance:  cache line size.  Although the MPS standard requires
references to be coherent no matter what caching is used, the fact is
that when one processor writes to a particular line of memory, every
cached copy of the old line must be invalidated or updated.  This
implies that if two or more processors are both writing data to
different portions of the same line a lot of cache and bus traffic may
result, effectively to pass the line from cache to cache.  This problem
is known as <bf>false sharing</bf>.  The solution is simply to try to
<em>organize data so that what is accessed in parallel tends to come
from a different cache line for each process</em>.
-->
アトミックな操作に関して必須で、SMP のパフォーマンスに劇的な影響を
あたえることがもう 1 つあります。それはキャッシュ・ラインの大きさです。
MPS 規格ではキャッシュが使われていてもいなくても、同期するための参照が
必要とされています。しかし 1 つのプロセッサがメモリのあるラインに書き
込みを行うと、以前書き込まれたライン上にあるキャッシュしてあるものは、
すべてを無効にするか更新する必要があります。2 つ以上のプロセッサどれもが
データを同じラインの違う部分に書くとすると、キャッシュやバスに多量のやり
取りが発生してしまうかもしれません。これは事実上キャッシュ・ラインから
受渡しが起こることを意味しています。この問題は、<bf>偽共有(false sharing)
</bf> と言われています。解決するのはいたって単純で、<em>並列にアクセスする
場合は、それぞれのプロセスに対して、データをできるだけ異なるキャッシュ・
ラインから取ってくるようにデータを構成することです</em>。

<!--
You might be thinking that false sharing is not a problem using a
system with a shared L2 cache, but remember that there are still
separate L1 caches.  Cache organization and number of separate levels
can both vary, but the Pentium L1 cache line size is 32 bytes and
typical external cache line sizes are around 256 bytes.  Suppose that
the addresses (physical or virtual) of two items are <em>a</em> and
<em>b</em> and that the largest per-processor cache line size is
<em>c</em>, which we assume to be a power of two.  To be very precise,
if <tt>((int) <em>a</em>) &amp; ~(<em>c</em> - 1)</tt> is equal to
<tt>((int) <em>b</em>) &amp; ~(<em>c</em> - 1)</tt>, then both
references are in the same cache line.  A simpler rule is that if
shared objects being referenced in parallel are at least <em>c</em>
bytes apart, they should map to different cache lines.
-->
偽共有は、CPU が共通して使用する L2 キャッシュを持っているシステムには
関係ない問題と思われるかもしれませんが、独立して存在する L1 キャッシュ
を忘れてはいけません。キャッシュの構成や独立したレベルの数は両者とも
変動するもので、Pentium の L1 のキャッシュ・ラインの大きさは 32 バイトで
外部キャッシュ・ラインの典型的な大きさは 256 バイト程度です。仮に 2 つの
要素のアドレス(物理、仮想どちらでも)が <em>a</em> と <em>b</em> として、
プロセッサ毎の最大のキャッシュ・ラインの大きさが <em>c</em> としてそれが 
2 の累乗の大きさとします。厳密に言うと、もし <tt>((int) <em>a</em>) &amp; 
~(<em>c</em> - 1)</tt> が <tt>((int) <em>b</em>) &amp; ~(<em>c</em> - 1)
</tt> と等しければ、どちらも同じキャッシュ・ラインを参照することになりま
す。共有するオブジェクトが並列に参照される場合、少なくとも <em>c</em> 
バイト離れた位置にあるならば、異なるキャッシュ・ラインに置かれるべきだ、
というのが原則です。

<!-- <sect2>Linux Scheduler Issues -->
<sect2>Linux のスケジューラの問題点
<p>

<!--
Although the whole point of using shared memory for parallel
processing is to avoid OS overhead, OS overhead can come from things
other than communication per se.  We have already said that the number
of processes that should be constructed is less than or equal to the
number of processors in the machine.  But how do you decide exactly
how many processes to make?
-->
並列処理で共有メモリを使用する際には、あらゆる部分で OS のオーバー
ヘッドを避けなければいけませんが、OS のオーバーヘッドは通信それ自体
以外のところから発生する可能性があります。既にこれまでに述べてきました
が、プロセスの数はマシンに付けてあるプロセッサ数以下にするように
構成すべきです。でもどうやって動かすプロセス数を正確に決められるので
しょうか？

<!--
For best performance, <em>the number of processes in your parallel
program should be equal to the expected number of your program's
processes that simultaneously can be running on different
processors</em>.  For example, if a four-processor SMP typically has
one process actively running for some other purpose (e.g., a WWW
server), then your parallel program should use only three processes.
You can get a rough idea of how many other processes are active on
your system by looking at the "load average" quoted by the
<tt>uptime</tt> command.
-->
最高のパフォーマンスを得るには、<em>並列プログラムで動かすプロセス
数は、そのプログラムで起動するプロセスが同時に異なるプロセッサで
動かせると思われる数と同じにすべきです</em>。例えば、4 つのプロセッサ
を持つ SMP システムでは、通常 1 つのプロセッサは何か別の目的(例えば 
WWW サーバ)に使われているとすると、3 つのプロセッサだけで並列プログ
ラムを動かすことになるはずです。
おおまかにどのくらいのプロセスがシステムでアクティブなのかは、
<tt>uptime</tt> コマンドで見られる「load average(平均負荷)」を見れば
わかります。

<!--
Alternatively, you could boost the priority of the processes in your
parallel program using, for example, the <tt>renice</tt> command or
<tt>nice()</tt> system call.  You must be privileged to increase
priority.  The idea is simply to force the other processes out of
processors so that your program can run simultaneously across all
processors.  This can be accomplished somewhat more explicitly using
the prototype version of SMP Linux at <url
url="http://luz.cs.nmt.edu/~rtlinux/">, which offers real-time
schedulers.
-->
これとはまた別の方法があり、並列プログラムで使っているプロセスの実行
優先順位を引き上げることが可能です。例えば、<tt>renice</tt> コマンドや 
<tt>nice()</tt> システムコールです。優先度を上げるには、特権が必要に
なります。このアイディアは単純で、他のプロセスをプロセッサから追い出
して、自分のプロセスをすべてのプロセッサで同時に動かしてしまおうと
いう考えです。この考えをプロトタイプ版の SMP Linux を使用してもう
少しきちんと実現したものが <url url="http://www.rtlinux.org/"> 
で、リアルタイムなスケジューリングを提供しています。

<!--
If you are not the only user treating your SMP system as a parallel
machine, you may also have conflicts between the two or more parallel
programs trying to execute simultaneously.  This standard solution is
<bf>gang scheduling</bf> - i.e., manipulating scheduling priority so
that at any given moment, only the processes of a single parallel
program are running.  It is useful to recall, however, that using more
parallelism tends to have diminishing returns and scheduler activity
adds overhead.  Thus, for example, it is probably better for a
four-processor machine to run two programs with two processes each
rather than gang scheduling between two programs with four processes
each.
-->
SMP システムを並列処理マシンをただ一人で扱うユーザでないなら、2 つ以上
の並列プログラムを同時に実行しようとすると、プログラム間で衝突が起こる
恐れがあります。普通これを解決する方法は、<bf>ギャングスケジューリング
(gang scheduling)</bf>をとります。すなわち、スケジューリングの優先度を
操作して、いつでもただ 1 つの並列プログラムに関するプロセスだけが動いて
いるようにします。しかし思い出してみてください。並行処理を行えば行うほど
結果を得られにくくなり、スケジューラにオーバーヘッドが加わります。つまり
例えば、4 つのプロセッサを持つマシンが、強制スケジュールを使って 2 つの
プログラムをそれぞれ 4 つのプロセスで動かすよりも、2 つのプログラムを
それぞれ 2 つのプロセスで動かす方が効率良いのは確かです。

<!--
There is one more twist to this.  Suppose that you are developing a
program on a machine that is heavily used all day, but will be fully
available for parallel execution at night.  You need to write and test
your code for correctness with the full number of processes, even
though you know that your daytime test runs will be slow.  Well, they
will be <em>very</em> slow if you have processes <bf>busy waiting</bf>
for shared memory values to be changed by other processes that are not
currently running (on other processors).  The same problem occurs if
you develop and test your code on a single-processor system.
-->
さらにもう 1 つこの問題をややこしくしている事があります。あるマシンで
プログラムを開発していて、そのマシンは終日とても忙しく動いているが、
夜間は並列処理に丸々使えるとします。プロセスすべてを立ち上げて正しく動く
ようにコードを書いて、それをテストしなければいけませんが、昼間のテストは
遅いことを思い知らされると思います。実のところ<em>とても</em>遅くなり
ます。もし現在動いていない(他のプロセッサ上の)他のプロセスが変更した共有
メモリ上の値を<bf>ビジーウエイト</bf>しているプロセスがあるならば。同様
の問題は、プロセッサが 1 つしかないシステムでコードを開発したりテストし
たりする時にも起こります。

<!--
The solution is to embed calls in your code, wherever it may loop
awaiting an action from another processor, so that Linux will give
another process a chance to run.  I use a C macro, call it
<tt>IDLE&lowbar;ME</tt>, to do this:  for a test run, compile with
<tt>cc -DIDLE&lowbar;ME=usleep(1); ...</tt>; for a "production" run,
compile with <tt>cc -DIDLE&lowbar;ME={} ...</tt>.  The
<tt>usleep(1)</tt> call requests a 1 microsecond sleep, which has the
effect of allowing the Linux scheduler to select a different process
to run on that processor.  If the number of processes is more than
twice the number of processors available, it is not unusual for codes
to run ten times faster with <tt>usleep(1)</tt> calls than without
them.
-->
解決方法は、コードに呼び出しを組み込むことです。どんな場合でも、他の
プロセスからの動きをループを使って待つようにします。そうすると Linux 
は、他のプロセスが動く機会を与えることができます。私は C のマクロを
使って <tt>IDLE&lowbar;ME</tt> のように呼び出しています。テストで動かす
時には、<tt>cc -DIDLE&lowbar;ME=usleep(1); ...</tt> とコンパイルし、
「製品」として動かす場合には <tt>cc -DIDLE&lowbar;ME={} ...</tt> と
コンパイルしています。<tt>usleep(1)</tt> を呼び出すと、1 ミリ秒間スリープ
するようになり、Linux のスケジューラがそのプロセッサ上で別のプロセスを
選べるようになります。プロセスが使用可能なプロセッサの 2 倍以上の数に
なると、コードの中で <tt>usleep(1)</tt> を使うと、使わない場合の 10 倍
速くなることも珍しくありません。

<sect1>bb&lowbar;threads
<p>

<!--
The bb&lowbar;threads ("Bare Bones" threads) library, <url
url="ftp://caliban.physics.utoronto.ca/pub/linux/">, is a remarkably
simple library that demonstrates use of the Linux <tt>clone()</tt>
call.  The <tt>gzip tar</tt> file is only 7K bytes!  Although this
library is essentially made obsolete by the LinuxThreads library
discussed in section 2.4, bb&lowbar;threads is still usable, and it is
small and simple enough to serve well as an introduction to use of
Linux thread support.  Certainly, it is far less daunting to read this
source code than to browse the source code for LinuxThreads.  In
summary, the bb&lowbar;threads library is a good starting point, but
is not really suitable for coding large projects.
-->
bb&lowbar;threads (「Bare Bones」(必要最低限の) threads)ライブラリは、
<url url="ftp://caliban.physics.utoronto.ca/pub/linux/"> にある非常に
簡素なライブラリです。Linux の <tt>clone()</tt> システムコールを使って
実装されています。<tt>gzip tar</tt> ファイルでたった 7 KB です！ この
ライブラリは、2.4 で論じた LinuxThreads ライブラリが世に出たことで
過去のものになってしまいましたが、bb&lowbar;threads はまだまだ役に立ち
ます。小さく、シンプルで、とりあえず最初に Linux のスレッドを使用する
には十分です。このソース・コードを読んでも、LinuxThreads のソースを眺めた
時のように威圧感を感じることはないのは確かです。まとめてみると、
bb&lowbar;threads ライブラリは最初に試してみるのには良いライブラリですが、
正直なところ大きなプロジェクトのコーディングで使用するのには適していません。

<!-- The basic program structure for using the bb&lowbar;threads library is: -->
bb&lowbar;threads ライブラリを使った基本的なプログラムの構築方法は、
下記の通りです。

<enum>
<!-- <item>Start the program running as a single process.  -->
<item>プログラムは、1 つのプロセスとしてスタートさせること

<!--
<item>You will need to estimate the maximum stack space that will be
required for each thread.  Guessing large is relatively harmless (that
is what virtual memory is for ;-), but remember that <em>all</em> the
stacks are coming from a single virtual address space, so guessing
huge is not a great idea.  The demo suggests 64K.  This size is set to
<em>b</em> bytes by
<tt>bb&lowbar;threads&lowbar;stacksize(<em>b</em>)</tt>.
-->
<item>それぞれのスレッドで必要になるスタック空間の最大値を見積ること。
	大きく見積っても害はない(仮想記憶がそうであるように ;-)。
	しかし忘れないで欲しいことは、スタック<em>すべて</em>は単独の仮想アドレス
	空間に由来しているため、大きいことはいいことだ、というわけにはいかないこと
	である。64 K がお試しの大きさである。
	<tt>bb&lowbar;threads&lowbar;stacksize(<em>b</em>)</tt> とすると、
<em>b</em> バイトに設定できる

<!--
<item>The next step is to initialize any locks that you will need.
The lock mechanism built-into this library numbers locks from 0 to
<tt>MAX&lowbar;MUTEXES</tt>, and initializes lock <em>i</em> by
<tt>bb&lowbar;threads&lowbar;mutexcreate(<em>i</em>)</tt>.
-->
<item>次のステップは、必要となるすべてのロックを初期化することである。
	ロックのしくみはこのライブラリに組み込まれていて、0 から 
	<tt>MAX&lowbar;MUTEXES</tt> までの番号が設定でき、<em>i</em> という
	ロックを初期化するには、<tt>bb&lowbar;threads&lowbar;mutexcreate
	(<em>i</em>)</tt> と設定する

<!--
<item>Spawning a new thread is done by calling a library routine that
takes arguments specifying what function the new thread should execute
and what arguments should be transmitted to it.  To start a new thread
executing the <tt>void</tt>-returning function <em>f</em> with the
single argument <em>arg</em>, you do something like
<tt>bb&lowbar;threads&lowbar;newthread(<em>f</em>, &amp;arg)</tt>,
where <em>f</em> should be declared something like <tt>void
<em>f</em>(void *arg, size&lowbar;t dummy)</tt>.  If you need to pass
more than one argument, pass a pointer to a structure initialized to
hold the argument values.
-->
<item>新しいスレッドを起こすには、ライブラリのルーチンを呼び出して何の
	関数をスレッドとして実行し、その関数に渡される引数は何かを指定する。
	新しいスレッドを開始するには、<tt>void</tt> を返り値とする関数である 
	<em>f</em> を単独の <em>arg</em> を引数として持つ必要があり、
	<tt>bb&lowbar;threads&lowbar;newthread(<em>f</em>, &amp;arg)</tt> 
	という感じで指定することになる。ここで <em>f</em> は <tt>void 
	<em>f</em>(void *arg, size&lowbar;t dummy)</tt> というように宣言して
	おくべきである。引数が 1 つ以上になる場合は、引数の値で初期化してある
	構造体へのポインタを指定してする

<!--
<item>Run parallel code, being careful to use
<tt>bb&lowbar;threads&lowbar;lock(<em>n</em>)</tt> and
<tt>bb&lowbar;threads&lowbar;unlock(<em>n</em>)</tt> where <em>n</em>
is an integer identifying which lock to use.  Note that the lock and
unlock operations in this library are very basic spin locks using
atomic bus-locking instructions, which can cause excessive
memory-reference interference and do not make any attempt to ensure
fairness.
-->
<item>並列コードを実行する。実行に当っては、
	<tt>bb&lowbar;threads&lowbar;lock(<em>n</em>)</tt> と 
	<tt>bb&lowbar;threads&lowbar;unlock(<em>n</em>)</tt> を慎重に使用する
	こと。<em>n</em> は整数で、どのロックを使用するかを指定する。この
	ライブラリでのロックをかけることとロックを解除する操作は、アトミック
	にバスをロックする命令を使って、ありふれたスピン・ロックで実現している。
	この方法では必要以上にメモリ参照の輻輳が生じ、プロセスを公平に実行する
	ことが保証できない

<!--
The demo program packaged with bb&lowbar;threads did not correctly use
locks to prevent <tt>printf()</tt> from being executed simultaneously
from within the functions <tt>fnn</tt> and <tt>main</tt>...  and
because of this, the demo does not always work.  I'm not saying this
to knock the demo, but rather to emphasize that this stuff is <em>very
tricky</em>; also, it is only slightly easier using LinuxThreads.
-->
	bb&lowbar;threads についているデモ・プログラムは正しくロックを扱えず、
	<tt>printf()</tt> が <tt>fnn</tt> や <tt>main</tt>などの関数内で同時
	に実行されてしまう。そのようなわけでこのデモは常に動くとは限らない。
	デモを非難するつもりはないが、ロックには<em>細心の注意</em>が必要で
	あることを強調しておきたい。また、LinuxThreads を使えばわずかではあるが
	使いやすくなることも付け加えたい

<!--
<item>When a thread executes a <tt>return</tt>, it actually destroys
the process...  but the local stack memory is not automatically
deallocated.  To be precise, Linux doesn't support deallocation, but
the memory space is not automatically added back to the
<tt>malloc()</tt> free list.  Thus, the parent process should reclaim
the space for each dead child by
<tt>bb&lowbar;threads&lowbar;cleanup(wait(NULL))</tt>.
-->
<item>あるスレッドが<tt>返り値</tt>を戻す時点で、そのプロセスが実際に
	破棄される…しかし、ローカルなスタック・メモリは自動的に解放されない。
	正確に言うと Linux はメモリの解放をサポートしておらず、そのメモリ空間は 
	<tt>malloc()</tt> のメモリの空きリストに自動的に戻されない。つまり、親
	プロセスは <tt>bb&lowbar;threads&lowbar;cleanup(wait(NULL))</tt> を
	呼び出して、死んでしまった子プロセスのスペースを再利用のために再宣言し
	なければいけない
</enum>
<p>

<!--
The following C program uses the algorithm discussed in section 1.3 to
compute the approximate value of Pi using two bb&lowbar;threads
threads.
-->
下記の C プログラムはセクション 1.3 で論じたアルゴリズムを元に、2 つの 
bb&lowbar;threads を使って円周率の近似値を求めています。

<code>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "bb_threads.h"

volatile double pi = 0.0;
volatile int intervals;
volatile int pids[2];      /* Unix PIDs of threads */

void
do_pi(void *data, size_t len)
{
  register double width, localsum;
  register int i;
  register int iproc = (getpid() != pids[0]);

  /* set width */
  width = 1.0 / intervals;

  /* do the local computations */
  localsum = 0;
  for (i=iproc; i<intervals; i+=2) {
    register double x = (i + 0.5) * width;
    localsum += 4.0 / (1.0 + x * x);
  }
  localsum *= width;

  /* get permission, update pi, and unlock */
  bb_threads_lock(0);
  pi += localsum;
  bb_threads_unlock(0);
}

int
main(int argc, char **argv)
{
  /* get the number of intervals */
  intervals = atoi(argv[1]);

  /* set stack size and create lock... */
  bb_threads_stacksize(65536);
  bb_threads_mutexcreate(0);

  /* make two threads... */
  pids[0] = bb_threads_newthread(do_pi, NULL);
  pids[1] = bb_threads_newthread(do_pi, NULL);

  /* cleanup after two threads (really a barrier sync) */
  bb_threads_cleanup(wait(NULL));
  bb_threads_cleanup(wait(NULL));

  /* print the result */
  printf("Estimation of pi is %f\n", pi);

  /* check-out */
  exit(0);
}
</code>

<sect1>LinuxThreads
<p>

<!--
LinuxThreads <url
url="http://pauillac.inria.fr/~xleroy/linuxthreads/"> is a fairly
complete and solid implementation of "shared everything" as per the
POSIX 1003.1c threads standard.  Unlike other POSIX threads ports,
LinuxThreads uses the same Linux kernel threads facility
(<tt>clone()</tt>) that is used by bb&lowbar;threads.  POSIX
compatibility means that it is relatively easy to port quite a few
threaded applications from other systems and various tutorial
materials are available.  In short, this is definitely the threads
package to use under Linux for developing large-scale threaded
programs.
-->
LinuxThreads(<url 
url="http://pauillac.inria.fr/~xleroy/linuxthreads/">) は、POSIX 1003.1c 
のスレッド標準規格に基づいて「すべてを共有する」ことを申し分なくしっかり
と実装しています。他の POSIX 準拠のスレッドの移植と違い、LinuxThreads は
カーネルのスレッド機能(<tt>clone()</tt>)を使っており、これは 
bb&lowbar;threads と同様な手法をとっています。POSIX 互換だとスレッドを
使ったアプリケーションを他のシステムへ移植することが他スレッドと比べて
かなり容易になり、チュートリアル類もいろいろ利用できます。つまり、Linux 
で大規模にスレッド化されたプログラムを開発するなら、間違いなくこの
パッケージが適切です。

<!-- The basic program structure for using the LinuxThreads library is: -->
LinuxThreads ライブラリを使った基本的なプログラムの構築のしかたは、
下記の通りです。

<enum>
<!-- <item>Start the program running as a single process.  -->
<item>プログラムは、1 つのプロセスとしてスタートさせること

<!--
<item>The next step is to initialize any locks that you will need.
Unlike bb&lowbar;threads locks, which are identified by numbers, POSIX
locks are declared as variables of type
<tt>pthread&lowbar;mutex&lowbar;t lock</tt>.  Use
<tt>pthread&lowbar;mutex&lowbar;init(&amp;lock,val)</tt> to initialize
each one you will need to use.
-->
<item>次のステップは、必要となるあらゆるロックを初期化することである。
	bb&lowbar;threads のロックが番号を指定するのとは異なり、
	<tt>pthread&lowbar;mutex&lowbar;t lock</tt> という変数を宣言するのが
	POSIX 流である。<tt>pthread&lowbar;mutex&lowbar;init(&amp;lock,val)</tt> 
	を使って、必要なそれぞれのスレッドを初期化する

<!--
<item>As with bb&lowbar;threads, spawning a new thread is done by
calling a library routine that takes arguments specifying what
function the new thread should execute and what arguments should be
transmitted to it.  However, POSIX requires the user to declare a
variable of type <tt>pthread&lowbar;t</tt> to identify each thread.  To
create a thread <tt>pthread&lowbar;t thread</tt> running <tt>f()</tt>,
one calls <tt>pthread&lowbar;create(&amp;thread,NULL,f,&amp;arg)</tt>.
-->
<item>bb&lowbar;threads と同様に、新しいスレッドを起こすにはライブラリの
	ルーチンを呼び出し、何の関数をスレッドとして実行し、その関数に渡される
	引数は何かを指定する。しかし、POSIX ではユーザが 
	<tt>pthread&lowbar;t</tt> という変数を宣言してスレッドを区別する。
	スレッドを起こすには、<tt>pthread&lowbar;t thread</tt> で <tt>f()</tt> 
	を動かすには、<tt>pthread&lowbar;create(&amp;thread,NULL,f,&amp;arg)</tt>
	を呼び出す

<!--
<item>Run parallel code, being careful to use
<tt>pthread&lowbar;mutex&lowbar;lock(&amp;lock)</tt> and
<tt>pthread&lowbar;mutex&lowbar;unlock(&amp;lock)</tt> as appropriate.
-->
<item>並列コードを動かすには、
	<tt>pthread&lowbar;mutex&lowbar;lock(&amp;lock)</tt> と
	<tt>pthread&lowbar;mutex&lowbar;unlock(&amp;lock)</tt> 適切なところで
	慎重に使用すること

<!--
<item>Use <tt>pthread&lowbar;join(thread,&amp;retval)</tt> to clean-up
after each thread.
-->
<item><tt>pthread&lowbar;join(thread,&amp;retval)</tt> を使って、スレッド
	の後始末をすること
<!--
<item>Use <tt>-D&lowbar;REENTRANT</tt> when compiling your C code.
-->
<item>C のコードをコンパイルする時には、<tt>-D&lowbar;REENTRANT</tt> 
	を使うこと
</enum>

<!--
An example parallel computation of Pi using LinuxThreads follows.  The
algorithm of section 1.3 is used and, as for the bb&lowbar;threads
example, two threads execute in parallel.
-->
次にあげるのは、円周率の計算を LinuxThreads を使って並列に行う例です。
セクション 1.3 で使ったアルゴリズムが使用されていて、bb&lowbar;threads 
と同様に 2 つのスレッドを並列に実行します。

<code>
#include <stdio.h>
#include <stdlib.h>
#include "pthread.h"

volatile double pi = 0.0;  /* Approximation to pi (shared) */
pthread_mutex_t pi_lock;   /* Lock for above */
volatile double intervals; /* How many intervals? */

void *
process(void *arg)
{
register double width, localsum;
register int i;
register int iproc = (*((char *) arg) - '0');

/* Set width */
width = 1.0 / intervals;

/* Do the local computations */
localsum = 0;
for (i=iproc; i<intervals; i+=2) {
register double x = (i + 0.5) * width;
localsum += 4.0 / (1.0 + x * x);
}
localsum *= width;

/* Lock pi for update, update it, and unlock */
pthread_mutex_lock(&ero;pi_lock);
pi += localsum;
pthread_mutex_unlock(&ero;pi_lock);

return(NULL);
}

int
main(int argc, char **argv)
{
pthread_t thread0, thread1;
void * retval;

/* Get the number of intervals */
intervals = atoi(argv[1]);

/* Initialize the lock on pi */
pthread_mutex_init(&ero;pi_lock, NULL);

/* Make the two threads */
if (pthread_create(&ero;thread0, NULL, process, "0") ||
  pthread_create(&ero;thread1, NULL, process, "1")) {
fprintf(stderr, "%s: cannot make thread\n", argv[0]);
exit(1);
}

/* Join (collapse) the two threads */
if (pthread_join(thread0, &ero;retval) ||
  pthread_join(thread1, &ero;retval)) {
fprintf(stderr, "%s: thread join failed\n", argv[0]);
exit(1);
}

/* Print the result */
printf("Estimation of pi is %f\n", pi);

/* Check-out */
exit(0);
}
</code>

<!-- <sect1>System V Shared Memory -->
<sect1>System V の共有メモリ
<p>

<!--
The System V IPC (Inter-Process Communication) support consists of a
number of system calls providing message queues, semaphores, and a
shared memory mechanism.  Of course, these mechanisms were originally
intended to be used for multiple processes to communicate within a
uniprocessor system.  However, that implies that it also should work
to communicate between processes under SMP Linux, no matter which
processors they run on.
-->
System V の IPC(プロセス間通信(Inter-Process Communication))は、
システムコールを数多く提供してます。メッセージ・キューやセマフォ、
共有メモリといったしくみです。もちろん本来このしくみは、複数の
プロセスをプロセッサが 1 つのシステムで動かすことを目的としていました。
しかし、SMP Linux で複数のプロセス間での通信にも使えるはずです。たとえ
どんなプロセッサであっても。

<!--
Before going into how these calls are used, it is important to
understand that although System V IPC calls exist for things like
semaphores and message transmission, you probably should not use
them.  Why not?  These functions are generally slow and serialized
under SMP Linux.  Enough said.
-->
これらのシステムコールの使い方の説明に入る前に、System V の IPC に含まれて
いるセマフォやメッセージ通信のようなシステムコールを使用すべきではないこと
を理解しておいてください。どうしてでしょうか？ SMP Linux ではこれらの機能は
概して処理が遅く、順次実行されるからです。説明はこれで十分ですね。

<!--
The basic procedure for creating a group of processes sharing access
to a shared memory segment is:
-->
共有メモリのセグメントに一様にアクセスするために、プロセスのグループを作成
する基本的な手続きは次の通りです。

<enum>
<!--
<item>Start the program running as a single process.
-->
<item>プログラムは、1 つのプロセスとしてスタートさせること

<!--
<item>Typically, you will want each run of a parallel program to have
its own shared memory segment, so you will need to call
<tt>shmget()</tt> to create a new segment of the desired size.
Alternatively, this call can be used to get the ID of a pre-existing
shared memory segment.  In either case, the return value is either the
shared memory segment ID or -1 for error.  For example, to create a
shared memory segment of <em>b</em> bytes, the call might be <tt>shmid
= shmget(IPC&lowbar;PRIVATE, <em>b</em>, (IPC&lowbar;CREAT | 0666))</tt>.
-->
<item>普通、それぞれの並列処理のプログラムを自分の共有メモリのセグメント
	を使って動かしたいかと思われるので、その場合は <tt>shmget()</tt> 
	を呼んで必要な大きさのセグメントを新しく作成する。またこのシステム
	コールは、既存の共有メモリの ID を得るためにも使われる。どちらの場合も
	返り値は共有メモリの ID か、エラーを表す -1 である。例えば、<em>b</em> 
	バイトの大きさの共有メモリを作るなら、<tt>shmid = 
	shmget(IPC&lowbar;PRIVATE, <em>b</em>, (IPC&lowbar;CREAT | 0666))</tt> 
	と呼び出す

<!--
<item>The next step is to attach this shared memory segment to this
process, literally adding it to the virtual memory map of this process.
Although the <tt>shmat()</tt> call allows the programmer to specify
the virtual address at which the segment should appear, the address
selected must be aligned on a page boundary (i.e., be a multiple of
the page size returned by <tt>getpagesize()</tt>, which is usually
4096 bytes), and will override the mapping of any memory formerly at
that address.  Thus, we instead prefer to let the system pick the
address.  In either case, the return value is a pointer to the base
virtual address of the segment just mapped.  The code is <tt>shmptr =
shmat(shmid, 0, 0)</tt>.
-->
<item>次のステップはプロセスにこの共有メモリをアタッチして、文字通り
	このプロセスの仮想メモリマップに加える。
	プログラマーは <tt>shmat()</tt> を呼ぶことで、仮想アドレス上のどこに
	共有メモリのセグメントがあるのかがわかる。しかしそのアドレスはページ境界に
	合っていなければならない(すなわち <tt>getpagesize()</tt> が返す大きさは
	ページの大きさの倍数になっていて、通常は 4096 バイトである)。また、以前
	そのアドレスをメモリにマップしたものは無効になる。
	つまり以前マップしていたもののかわりに、そのアドレスを使用するように
	システムに指示するのである。どちらの場合も返り値はマップされたセグメント
	の仮想アドレスへのポインタである。コードは、<tt>shmptr =
	shmat(shmid, 0, 0)</tt> となる

<!--
Notice that you can allocate all your static shared variables into
this shared memory segment by simply declaring all shared variables as
members of a <tt>struct</tt> type, and declaring <em>shmptr</em> to be
a pointer to that type.  Using this technique, shared variable
<em>x</em> would be accessed as
<em>shmptr</em><tt>-&gt;</tt><em>x</em>.
-->
	注意すべき点は、共有メモリセグメントに置く共有する static 変数はすべて
	<tt>構造体</tt>のメンバーにして宣言することで確保できる、ということだ。
	そして <em>shmptr</em> をその構造体のポインタにする。このテクニックを
	使うと、<em>x</em> は <em>shmptr</em><tt>-&gt;</tt><em>x</em> と参照
	できる

<!--
<item>Since this shared memory segment should be destroyed when the
last process with access to it terminates or detaches from it, we need
to call <tt>shmctl()</tt> to set-up this default action.  The code is
something like <tt>shmctl(shmid, IPC&lowbar;RMID, 0)</tt>.
-->
<item>この共有メモリのセグメントを解放しなければならない時は、この
	セグメントにアクセスする最後のプロセスが終了するかデタッチする場合である。
	<tt>shmctl()</tt> を呼び出して、初期状態に設定する必要がある。コードは、
	<tt>shmctl(shmid, IPC&lowbar;RMID, 0)</tt> のようになる

<!--
<item>Use the standard Linux <tt>fork()</tt> call to make the desired
number of processes...  each will inherit the shared memory segment.
-->
<item>Linux 標準の <tt>fork()</tt> システムコールを使って、必要なプロセス
	を立ち上げる…。それぞれのプロセスは共有メモリのセグメントを継承する

<!--
<item>When a process is done using a shared memory segment, it really
should detach from that shared memory segment.  This is done by
<tt>shmdt(shmptr)</tt>.
-->
<item>プロセスが共有メモリのセグメントを使い終ったら、共有メモリの
	セグメントを必ずデタッチする。これは <tt>shmdt(shmptr)</tt> とすれば良い
</enum>
<p>

<!--
Although the above set-up does require a few system calls, once the
shared memory segment has been established, any change made by one
processor to a value in that memory will automatically be visible to
all processes.  Most importantly, each communication operation will
occur without the overhead of a system call.
-->
このようにいくつかのシステムコールが設定の際に必要となりますが、一度
共有メモリのセグメントが確保されれば、どのプロセッサがメモリ上の値を変え
ても自動的にすべてのプロセッサから見ることができます。最も大切なことは、
システムコールのオーバーヘッドなしに操作ができることです。

<!--
An example C program using System V shared memory segments follows.
It computes Pi, using the same algorithm given in section 1.3.
-->
System V の共有メモリのセグメントを使った C のプログラム例です。これ
は円周率を計算するもので、セクション 1.3 で使ったのと同じアルゴリズム
を利用しています。

<code>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ipc.h>
#include <sys/shm.h>

volatile struct shared { double pi; int lock; } *shared;

inline extern int xchg(register int reg,
volatile int * volatile obj)
{
  /* Atomic exchange instruction */
__asm__ __volatile__ ("xchgl %1,%0"
                      :"=r" (reg), "=m" (*obj)
                      :"r" (reg), "m" (*obj));
  return(reg);
}

main(int argc, char **argv)
{
  register double width, localsum;
  register int intervals, i;
  register int shmid;
  register int iproc = 0;;

  /* Allocate System V shared memory */
  shmid = shmget(IPC_PRIVATE,
                 sizeof(struct shared),
                 (IPC_CREAT | 0600));
  shared = ((volatile struct shared *) shmat(shmid, 0, 0));
  shmctl(shmid, IPC_RMID, 0);

  /* Initialize... */
  shared->pi = 0.0;
  shared->lock = 0;

  /* Fork a child */
  if (!fork()) ++iproc;

  /* get the number of intervals */
  intervals = atoi(argv[1]);
  width = 1.0 / intervals;

  /* do the local computations */
  localsum = 0;
  for (i=iproc; i<intervals; i+=2) {
    register double x = (i + 0.5) * width;
    localsum += 4.0 / (1.0 + x * x);
  }
  localsum *= width;

  /* Atomic spin lock, add, unlock... */
  while (xchg((iproc + 1), &ero;(shared->lock))) ;	
  shared->pi += localsum;
  shared->lock = 0;

  /* Terminate child (barrier sync) */
  if (iproc == 0) {
    wait(NULL);
    printf("Estimation of pi is %f\n", shared->pi);
  }

  /* Check out */
  return(0);
}
</code>

<!--
In this example, I have used the IA32 atomic exchange instruction to
implement locking.  For better performance and portability, substitute
a synchronization technique that avoids atomic bus-locking
instructions (discussed in section 2.2).
-->
この例では、IA32 のアトミックな交換(exchange)命令を使ってロックを実現
しています。
パフォーマンスと移植性をさらに良くするには、バスをロックする命令を回避
するような同期のしくみに置き換えてください(セクション 2.2 で論じたように)。

<!--
When debugging your code, it is useful to remember that the
<tt>ipcs</tt> command will report the status of the System V IPC
facilities currently in use.
-->
コードをデバッグする場合は、現在使われている System V の IPC 機能の状態
をレポートする <tt>ipcs</tt> コマンドを知っておくと便利です。

<!-- <sect1>Memory Map Call -->
<sect1>メモリマップ・システムコール
<p>

<!--
Using system calls for file I/O can be very expensive; in fact, that is
why there is a user-buffered file I/O library (<tt>getchar()</tt>,
<tt>fwrite()</tt>, etc.).  But user buffers don't work if multiple
processes are accessing the same writeable file, and the user buffer
management overhead is significant.  The BSD UNIX fix for this was the
addition of a system call that allows a portion of a file to be mapped
into user memory, essentially using virtual memory paging mechanisms to
cause updates.  This same mechanism also has been used in systems from
Sequent for many years as the basis for their shared memory parallel
processing support.  Despite some very negative comments in the (quite
old) man page, Linux seems to correctly perform at least some of the
basic functions, and it supports the degenerate use of this system
call to map an anonymous segment of memory that can be shared across
multiple processes.
-->
システムコールはファイル入出力をともなうと重くなります。実際に、ユーザ
レベルでのバッファを介したファイル入出力ライブラリ(<tt>getchar()</tt>、
<tt>fwrite()</tt> 等)があるのはこのためです。しかし、ユーザレベルでの
バッファは、複数のプロセスが同じ書き込み可能なファイルにアクセスした場合
には役立ちません。またこれを管理するオーバーヘッドもばかになりません。
BSD UNIX はこの問題を解決するため、システムコールを 1 つ追加しました。
それはファイルの一部をユーザのメモリ空間にマップして、仮想メモリの
ページング機構を利用して更新を行うものです。Sequent がこれと同様のしくみ
を何年も前から自社の共有メモリを使った並列処理の機能として提供してきました。
(とても古い)man を見ると、とても否定的なコメントが散見されますが、Linux 
では少なくとも基本的な機能のいくつかは正しく動作します。このシステムコール
が複数のプロセスで利用できる共通のメモリ上のセグメントをマップするのに
使用されるのはまれです。

<!--
In essence, the Linux implementation of <tt>mmap()</tt> is a plug-in
replacement for steps 2, 3, and 4 in the System V shared memory scheme
outlined in section 2.5.  To create an anonymous shared memory segment:
-->
本質的に Linux の <tt>mmap()</tt> は、セクション 2.5 の基本的な手続きの
2、3、4 で説明した System V の共有メモリの枠組みで置き換えることができ
ます。

<code>
shmptr =
    mmap(0,                        /* system assigns address */
         b,                        /* size of shared memory segment */
         (PROT_READ | PROT_WRITE), /* access rights, can be rwx */
         (MAP_ANON | MAP_SHARED),  /* anonymous, shared */
         0,                        /* file descriptor (not used) */
         0);                       /* file offset (not used) */
</code>

<!--
The equivalent to the System V shared memory <tt>shmdt()</tt>
call is <tt>munmap()</tt>:
-->
<tt>munmap()</tt> は System V の共有メモリの <tt>shmdt()</tt> システム
コールと同じ機能です。

<code>
munmap(shmptr, b);
</code>

<!--
In my opinion, there is no real benefit in using <tt>mmap()</tt>
instead of the System V shared memory support.
-->
私見ですが、System V の共有メモリのかわりに <tt>mmap()</tt> を使っても、
それほどメリットはないと思います。

<!-- <sect>Clusters Of Linux Systems -->
<sect>Linux システムでクラスタを組む
<p>

<!--
This section attempts to give an overview of cluster parallel
processing using Linux.  Clusters are currently both the most popular
and the most varied approach, ranging from a conventional network of
workstations (<bf>NOW</bf>) to essentially custom parallel machines
that just happen to use Linux PCs as processor nodes.  There is also
quite a lot of software support for parallel processing using clusters
of Linux machines.
-->
このセクションでは、Linux を使ったクラスタによる並列処理をおおまかに
見て行こうと思います。今クラスタは大流行しているだけでなく、アプローチ
のしかたも非常にバラエティに富みます。ごく普通にネットワークにワーク
ステーションをつないで構成したものから(<bf>これですね</bf>)、特注の並列
マシンまであります。そこで動いているプロセッサ・ノードがたまたま Linux 
PC を使っていたということもあります。またソフトウェアも相当な数が Linux 
マシンで組んだクラスタを使った並列処理用に用意されています。

<!-- <sect1>Why A Cluster?  -->
<sect1>なぜクラスタなのか？
<p>

<!-- Cluster parallel processing offers several important advantages: -->
クラスタを組んで並列処理を行うと、大きなメリットがいくつか挙げられます。

<itemize>
<!--
<item>Each of the machines in a cluster can be a complete system,
usable for a wide range of other computing applications.  This leads
many people to suggest that cluster parallel computing can simply
claim all the "wasted cycles" of workstations sitting idle on people's
desks.  It is not really so easy to salvage those cycles, and it will
probably slow your co-worker's screen saver, but it can be done.
-->
<item>クラスタを構成する個々のマシンは単独システムとして完結していて、
	広範囲に他の演算用途に利用できる。このことから、クラスタを組んで並列に
	演算するということは、まさに各人の机上で「無駄な時間」を費している
	ワークステーションすべてに仕事をやらせる、ということに他ならない。実際
	そのような無駄な時間を集めてくることはたやすいことでないが、同僚の
	スクリーンセーバーは遅くなるだろうが、演算は終らせることができるだろう

<!--
<item>The current explosion in networked systems means that most of the
hardware for building a cluster is being sold in high volume, with
correspondingly low "commodity" prices as the result.  Further savings
come from the fact that only one video card, monitor, and keyboard are
needed for each cluster (although you may need to swap these into each
machine to perform the initial installation of Linux, once running, a
typical Linux PC does not need a "console").  In comparison, SMP and
attached processors are much smaller markets, tending toward somewhat
higher price per unit performance.
-->
<item>ここにきてネットワーク化したシステムが急増したことで、クラスタを
	構築するために必要なハードウェアの多くが多量に販売され、それにともない
	結果として安価な「商品」が出まわっている。さらにコストを押える手段として、
	クラスタ個々に必要なビデオカード、モニター、キーボードはたった一揃えしか
	いらない、ということが挙げられる。(Linux を最初にインストールする場合に
	それらを交換して取り付ければ良い。動き出してしまえば、普通の Linux が
	載っている PC は、「コンソール」は不要)。これと比べると、SMP や付加
	プロセッサは非常に商品市場が狭く、ユニット単位のパフォーマンスは高価に
	なりがちである

<!--
<item>Cluster computing can <em>scale to very large systems</em>.
While it is currently hard to find a Linux-compatible SMP with many
more than four processors, most commonly available network hardware
easily builds a cluster with up to 16 machines.  With a little work,
hundreds or even thousands of machines can be networked.  In fact, the
entire Internet can be viewed as one truly huge cluster.
-->
<item>クラスタ化した計算は、<em>非常に大規模なシステムにまで拡張でき
	る</em>。
	現状では、プロセッサを 4 つ以上載せた Linux 互換の SMP を見つけるのは
	非常に困難だが、一般的に利用できるネットワーク機器を使って 16 台のマシン
	まで 1 つのクラスタとして構築できる。もう少し手をかければ、何百、何千と
	いうマシンもネットワーク化できる。実際、インターネットすべてを 1 つの
	巨大なクラスタとみなすこともできる

<!--
<item>The fact that replacing a "bad machine" within a cluster is
trivial compared to fixing a partly faulty SMP yields much higher
availability for carefully designed cluster configurations.  This
becomes important not only for particular applications that cannot
tolerate significant service interruptions, but also for general use
of systems containing enough processors so that single-machine
failures are fairly common.  (For example, even though the average
time to failure of a PC might be two years, in a cluster with 32
machines, the probability that at least one will fail within 6 months
is quite high.)
-->
<item>クラスタの中で「おかしなマシン」を交換することは、部分的に壊れた 
	SMP を修理することに比べて、取るに足らないほど簡単ということは事実
	である。つまり慎重に設計、設定したクラスタは非常に高い可用性をも
	たらすことを示している。これは重要なことで、中断できない重要なサービス
	を提供する特定のアプリケーションに対してだけではなく、普通に利用している
	十分なプロセッサを搭載したシステムにおいてマシンがよくおかしくなる場合
	にも当てはまる。(例えば、PC がおかしくなる平均時間が 2 年だとしても、32 
	台でクラスタを組んでいるシステムでは、少なくとも 6 ヵ月以内に 1 台が
	おかしくなる可能性がある。これは非常に高い確率である)
</itemize>
<p>

<!--
OK, so clusters are free or cheap and can be very large and highly
available...  why doesn't everyone use a cluster?  Well, there are
problems too:
-->
それではクラスタがフリーかつ安価な上に、拡張性が高く、様々な用途
に利用可能…なのに、なぜ皆さんはクラスタを使用しないのでしょうか？ 
それは多分下記のような理由です。

<itemize>
<!--
<item>With a few exceptions, network hardware is not designed for
parallel processing.  Typically latency is very high and bandwidth
relatively low compared to SMP and attached processors.  For example,
SMP latency is generally no more than a few microseconds, but is
commonly hundreds or thousands of microseconds for a cluster.  SMP
communication bandwidth is often more than 100 MBytes/second; although
the fastest network hardware (e.g., "Gigabit Ethernet") offers
comparable speed, the most commonly used networks are between 10 and
1000 times slower.
-->
<item>例外を除いて、ネットワーク機器は並列処理向けに設計されていない。
	通常レベルの遅延が非常に高く、SMP や付加プロセッサシステムに比べ帯域
	幅が相対的に狭い。例えば、SMP の遅延は通常数ミリ秒以上にはならないが、
	クラスタにおいては数 100 から数 1000 ミリ秒生じるのが普通である。SMP 
	通信帯域幅では 100 MB/秒以上の値が度々でる。最速のネットワーク機器
	(例えば「ギガビット・イーサネット」は速度面で SMP に匹敵するが、一般的
	に利用しているネットワークは、その 1/10 〜 1/1000 の速度しか得られない

<!--
The performance of network hardware is poor enough as an <em>isolated
cluster network</em>.  If the network is not isolated from other
traffic, as is often the case using "machines that happen to be
networked" rather than a system designed as a cluster, performance can
be substantially worse.
-->
	ネットワーク機器のパフォーマンスを稼ぐには、<em>クラスタのために独立した
	ネットワーク</em>だけでは不十分である。そのネットワークが他のトラフィック
	の影響を受けないとしても、「たまたまネットワークに接続しているマシン」
	を使うと、クラスタ向け設計したシステムよりも実際にパフォーマンスが悪くなる
	ケースが多い

<!--
<item>There is very little software support for treating a cluster as a
single system.  For example, the <tt>ps</tt> command only reports the
processes running on one Linux system, not all processes running
across a cluster of Linux systems.
-->
<item>クラスタを 1 つのシステムとして扱えるソフトウェアがほとんど皆無。
	例えば、<tt>ps</tt> コマンドは 1 台の Linux システム上のプロセスをレポート
	するだけで、Linux システムで構成されたクラスタ全体のすべてのプロセスを
	レポートできるわけではない
</itemize>
<p>

<!--
Thus, the basic story is that clusters offer great potential, but that
potential may be very difficult to achieve for most applications.  The
good news is that there is quite a lot of software support that will
help you achieve good performance for programs that are well suited to
this environment, and there are also networks designed specifically to
widen the range of programs that can achieve good performance.
-->
つまり大筋ではクラスタは秘めたる潜在能力があるものの、アプリケーション
の大部分でその能力を引き出すことが非常に困難なようです。ただ幸いなのは、
クラスタ環境にマッチするようにプログラムのパフォーマンス向上を支援する
ソフトウェアがかなりたくさん存在していること、そしてより広範囲なプログラム
がクラスタ環境で高いパフォーマンスを上げられるように特別に設計したネット
ワークが存在することです。

<!-- <sect1>Network Hardware -->
<sect1>ネットワーク機器
<p>

<!--
Computer networking is an exploding field...  but you already knew
that.  An ever-increasing range of networking technologies and
products are being developed, and most are available in forms that
could be applied to make a parallel-processing cluster out of a group
of machines (i.e., PCs each running Linux).
-->
コンピュータのネットワーク化は、急成長の分野です…が、そんなことは既に
ご存じでしょう。現在も広がりつつあるネットワーク技術とその製品は継続
して開発されており、それらの大部分はひとかたまりのマシン群(例えば、
それぞれの PC で Linux が動いている)から構成されている並列処理クラスタ
でも利用できます。

<!--
Unfortunately, no one network technology solves all problems best; in
fact, the range of approach, cost, and performance is at first hard to
believe.  For example, using standard commercially-available hardware,
the cost per machine networked ranges from less than &dollar;5 to over
&dollar;4,000.  The delivered bandwidth and latency each also vary
over four orders of magnitude.
-->
ただ残念なことに、どのネットワーク技術も問題すべてを完璧に解決するわけでは
ありません。実際問題、アプローチのしかた、コスト、パフォーマンスの問題が
すぐに片づくとは思えません。例えば、一般的に販売しているハードウェアの場合、
ネットワーク化するのには 5 ドル未満から 4,000 ドルまでの幅があります。提供
できる帯域幅や遅延もまちまちで、大きく分けて 4 段階以上になります。

<!--
Before trying to learn about specific networks, it is important to
recognize that these things change like the wind (see <url
url="http://www.uk.linux.org/NetNews.html"> for Linux networking news),
and it is very difficult to get accurate data about some networks.
-->
特定のネットワークについて勉強をしようとする前に、ネットワークというもの
<!--
は、常々変化しているものであることを知っておいてください(<url 
url="http://www.uk.linux.org/NetNews.html"> に Linux 関連のネットワーク
-->
は、常々変化しているものであることを知っておいてください(<url 
url="http://www.linux.org.uk/NetNews.html"> に Linux 関連のネットワーク
についてのニュースがあります)。そしてネットワークの中には、正確なデータ
が得られにくいものがあるということも知っておいてください。

<!--
Where I was particularly uncertain,
I've placed a <em>?</em>.  I have spent a lot of time researching this
topic, but I'm sure my summary is full of errors and has omitted many
important things.  If you have any corrections or additions, please
send email to <htmlurl url="mailto:pplinux@ecn.purdue.edu"
name="pplinux@ecn.purdue.edu">.
-->
確かな情報が得られなかった部分には、<em>?</em> と書いておきます。この
話についてはかなりの時間を割きましたが、間違いがないとも限りませんし、
重要な事柄が抜けていないとも限りません。訂正する箇所や追加したいことが
あれば、pplinux@ecn.purdue.edu まで電子メールをください。

<!--
Summaries like the LAN Technology Scorecard at <url
url="http://web.syr.edu/~jmwobus/comfaqs/lan-technology.html"> give
some characteristics of many different types of networks and LAN
standards.  However, the summary in this HOWTO centers on the network
properties that are most relevant to construction of Linux clusters.
The section discussing each network begins with a short list of
characteristics.  The following defines what these entries mean.
-->
<!--
LAN 技術の性能評価をまとめたものが、<url
url="http://web.syr.edu/~jmwobus/comfaqs/lan-technology.html"> にあり、
-->
LAN 技術の性能評価をまとめたものが、<url
url="http://www.system75.com/documentation/dcom/lan-technology.html"> にあり、
様々なタイプのネットワークや LAN 標準 の特徴がいくつか載っています。
しかしこの HOWTO では、Linux クラスタの構築に密接に関係する属性に焦点を
当ててまとめてみます。
このセクションでは、まずそれぞれのネットワークの特徴を簡単にまとめてから、
その意味について定義していきます。

<descrip>
<!-- <tag>Linux support:</tag> -->
<tag>Linux の対応:</tag>

<!--
If the answer is <em>no</em>, the meaning is pretty clear.  Other
answers try to describe the basic program interface that is used to
access the network.  Most network hardware is interfaced via a kernel
driver, typically supporting TCP/UDP communication.  Some other
networks use more direct (e.g., library) interfaces to reduce latency
by bypassing the kernel.
-->
答えが <em>no</em> なら結果は言うまでもない。そうでなければ、プログラム
からネットワークにアクセスするために必要となる基本的なインタフェースに
ついて説明する。ネットワーク機器のほとんどは、カーネルのドライバ経由で
接続していて、普通は TCP や UDP 通信に対応している。他のネットワークの
いくつかは、よりダイレクトに(例えばライブラリを使って)接続していて、
カーネルを経由しないことで遅延を抑えている。
<p>
【訳註：現在の Linux の対応は、このドキュメントが書かれた時点よりも
広がっています。カーネル 2.2.18 でサポートしているものは、各項目で訳註
で補足します。それ以外は…ごめんなさい】

<!--
Years ago, it used to be considered perfectly acceptable to access a
floating point unit via an OS call, but that is now clearly ludicrous;
in my opinion, it is just as awkward for each communication between
processors executing a parallel program to require an OS call.  The
problem is that computers haven't yet integrated these communication
mechanisms, so non-kernel approaches tend to have portability problems.
You are going to hear a lot more about this in the near future, mostly
in the form of the new <bf>Virtual Interface (VI) Architecture</bf>,
<url url="http://www.viarch.org/">, which is a standardized method for
most network interface operations to bypass the usual OS call layers.
The VI standard is backed by Compaq, Intel, and Microsoft, and is sure
to have a strong impact on SAN (System Area Network) designs over the
next few years.
-->
数年前であれば、OS のシステムコールによって浮動小数点演算装置にアクセス
することが当たり前のこととして行われていたが、現在ではまったく意味のない
方法になっている。私見だが、並列処理プログラムを実行するのに OS を呼び
出してプロセッサ間の通信を行うことはスマートではないと思われる。問題なのは、
コンピュータがいまだにこれらを統合した通信手段を持ち合わせていない点にあり、
そのためにカーネルを経由しない解決手段が移植性の問題を抱えてしまいがちに
なる。
近い将来もっと色々な話題を聞くようになると思われることがある。それは<bf>
仮想インタフェース・アーキテクチャ(Virtual Interface (VI) Architecture)
</bf>(<url url="http://www.viarch.org/">)のような新しい体系である。これは、
ネットワーク・インタフェースに対する操作を標準化した手法をとることで、
通常の OS のシステムコールを使用しないようにする。
この VI には、Compaq と Intel、Microsoft が参加しており、数年後に登場
する SAN (System Area Network) に大きな影響を与えることは確実である

<!-- <tag>Maximum bandwidth:</tag> -->
<tag>最大帯域幅:</tag>

<!--
This is the number everybody cares about.  I have generally used the
theoretical best case numbers; your mileage <em>will</em> vary.
-->
皆が注目する値。理論的に達成できる最高値をあげておく。実際の成果は
場合によって異なる<em>だろう</em>

<!-- <tag>Minimum latency:</tag> -->
<tag>最低遅延:</tag>

<!--
In my opinion, this is the number everybody should care about even more
than bandwidth.  Again, I have used the unrealistic best-case numbers,
but at least these numbers do include <em>all</em> sources of latency,
both hardware and software.  In most cases, the network latency is just
a few microseconds; the much larger numbers reflect layers of
inefficient hardware and software interfaces.
-->
私見では、最大帯域幅よりも皆が注目すべき値である。上記と同じになるが、
ここでは現実的ではない最良値をあげておく。しかし、この値は少なくとも
ハードウェアとソフトウェア両者による遅延の原因を<em>すべて</em>含んで
いる。多くの場合ネットワークの遅延は数マイクロ秒程度で、これ以上大きな
値になるとハードウェアとソフトウェアのインタフェースのレベルで効率が
悪いことを示している

<!-- <tag>Available as:</tag> -->
<tag>利用できるのは:</tag>

<!--
Simply put, this describes how you get this type of network hardware.
Commodity stuff is widely available from many vendors, with price as
the primary distinguishing factor.  Multiple-vendor things are
available from more than one competing vendor, but there are
significant differences and potential interoperability problems.
Single-vendor networks leave you at the mercy of that supplier
(however benevolent it may be).  Public domain designs mean that even
if you cannot find somebody to sell you one, you or anybody else can
buy parts and make one.  Research prototypes are just that; they are
generally neither ready for external users nor available to them.
-->
簡単に言えば、このタイプのネットワーク機器を手に入れられるかどうかを示す。
市販の製品は多くのベンダーが提供しており、いろいろと利用できるが、価格が
最も大きな要因となっている。複数のベンダーから出ている製品は 1 つ以上の
競合するベンダーから利用可能となっているが、相違点がかなりあり、相互接続
の問題も含んでいる。
単独ベンダーのネットワークでは、業者のいいなりになってしまう(親切な業者も
いるかもしれないが)。パブリック・ドメインな設計では、誰かが販売すること
はないが、その一部を購入したり、自分で作成してしまうこともできる。研究
試作品がそれに当り、一般的には部外者がすぐにでも使える形になってい
ないし、手に入れることすらできない

<!-- <tag>Interface port/bus used:</tag> -->
<tag>ポートもしくはバスのインタフェース:</tag>

<!--
How does one hook-up this network?  The highest performance and most
common now is a PCI bus interface card.  There are also EISA, VESA
local bus (VL bus), and ISA bus cards.  ISA was there first, and is
still commonly used for low-performance cards.  EISA is still around
as the second bus in a lot of PCI machines, so there are a few cards.
These days, you don't see much VL stuff (although <url
url="http://www.vesa.org/"> would beg to differ).
-->
どのようにネットワークに接続するのか？ 最高のパフォーマンスで最も一般的
に普及しているのは PCI バスのインタフェース・カードである。その他にも
EISA や VESA Local バス(VL bus)、ISA バスカードがある。ISA は初期に登場
したもので、パフォーマンスが出ないカードであるものの、いまだに使用されて
いる。EISA は PCI マシンの多くでもう 1 つのバスとして使われてはいるが、
ほとんどカードが存在しない。
今日では、VL バスはほとんど目にしない(<url url="http://www.vesa.org/"> 
ではそうではないと言っているが)
<p>

<!--
Of course, any interface that you can use without having to open your
PC's case has more than a little appeal.  IrDA and USB interfaces are
appearing with increasing frequency.  The Standard Parallel Port (SPP)
used to be what your printer was plugged into, but it has seen a lot
of use lately as an external extension of the ISA bus; this new
functionality is enhanced by the IEEE 1284 standard, which specifies
EPP and ECP improvements.  There is also the old, reliable, slow RS232
serial port.  I don't know of anybody connecting machines using VGA
video connectors, keyboard, mouse, or game ports...  so that's about
it.
-->
もちろん、PC ケースを開けずに使えるインタフェースであれば、どんなものでも
多少なりとも魅力がある。IrDA や USB インタフェースは登場する割合が多くなり
つつある。標準パラレル・ポート(SPP)は、プリンターを取り付ける時に使用する
が、最近では ISA バスの外部拡張と同じ様に見なされている。このインタフェース
の新しい機能拡張は IEEE 1284 規格で、EPP と ECP を拡張している。また、
いにしえの信頼性がある低速な RS232 シリアル・ポートもある。VGA ビデオ
コネクタやキーボード、マウス、ゲームポート…を使ってマシンを接続した例は
聞いたこともないのでこれ以上触れない

<!-- <tag>Network structure:</tag> -->
<tag>ネットワーク構成:</tag>

<!--
A bus is a wire, set of wires, or fiber.  A hub is a little box that
knows how to connect different wires/fibers plugged into it; switched
hubs allow multiple connections to be actively transmitting data
simultaneously.
-->
バスは、1 本のケーブルであったり複数のケーブルの集まりやファイバで
あったりする。ハブは小さなケースで、種類の異なるケーブルやファイバー
を差し込んで、ネットワークに接続する手段を提供する。スイッチング・ハブ
は、複数接続しつつ同時にデータを転送できる。

<!-- <tag>Cost per machine connected:</tag> -->
<tag>接続マシン当りのコスト:</tag>

<!--
Here's how to use these numbers.  Suppose that, not counting the
network connection, it costs &dollar;2,000 to purchase a PC for use as
a node in your cluster.  Adding a Fast Ethernet brings the per node
cost to about &dollar;2,400; adding a Myrinet instead brings the cost
to about &dollar;3,800.  If you have about &dollar;20,000 to spend,
that means you could have either 8 machines connected by Fast Ethernet
or 5 machines connected by Myrinet.  It also can be very reasonable to
have multiple networks; e.g., &dollar;20,000 could buy 8 machines
connected by both Fast Ethernet and TTL&lowbar;PAPERS.  Pick the
network, or set of networks, that is most likely to yield a cluster
that will run your application fastest.
-->
ここではこの値の利用方法を説明する。例えば、ネットワークへの接続を考慮
に入れないと、クラスタで使用するノードの 1 つとして PC を購入するには 
2,000 ドルのコストがかかる。ファースト・イーサネットを追加すると、ノード
当り 2,400 ドルになる。そのかわりに Myrinet を追加すると、およそ 3,800 
ドルになる。もし 20,000 ドル使えるなら、ファースト・イーサネットが付いた 
8 台の マシンもしくは Myrinet が付いた 5 台のマシンが持てることになる。
もちろん、複数のネットワークを利用するのも手頃な価格で実現できる。
例えば 20,000 ドルあれば、ファースト・イーサネットと TTL&lowbar;PAPERS 
をつけた PC が 8 台購入できる。使用するネットワークの種類を選択して、
敷設すれば、アプリケーションを最速に動かすクラスタを実現できる
<p>

<!--
By the time you read this, these numbers will be wrong...  heck,
they're probably wrong already.  There may also be quantity discounts,
special deals, etc.  Still, the prices quoted here aren't likely to be
wrong enough to lead you to a totally inappropriate choice.  It
doesn't take a PhD (although I do have one ;-) to see that expensive
networks only make sense if your application needs their special
properties or if the PCs being clustered are relatively expensive.
-->
これを読まれた時点では、これらの値が間違っているかもしれない…残念だが、
確かに既に間違っている。大幅に値引きしているかもしれないし、読者が特別に
契約を結んでいるかもしれない等で。それでも、ここで挙げた価格は全体的に
間違った選択をしてしまう程おかしなものではない。アプリケーションが特別な
性質を持っていたり、クラスタ化した PC が比較的高価であっても、博士号を
持った人間(私もその一人だが ;-)が高価なネットワークと見なすことはない。
それを納得しさえすれば。
</descrip>

<!-- Now that you have the disclaimers, on with the show....  -->
では、上記の条件を飲んでもらったとして、見ていくことにしましょう…

<sect2>ArcNet
<p>
<itemize>
<!--
<item>Linux support: <em>kernel drivers</em>
<item>Maximum bandwidth: <em>2.5 Mb/s</em>
<item>Minimum latency: <em>1,000 microseconds?</em>
<item>Available as: <em>multiple-vendor hardware</em>
<item>Interface port/bus used: <em>ISA</em>
<item>Network structure: <em>unswitched hub or bus (logical ring)</em>
<item>Cost per machine connected: <em>&dollar;200</em>
-->
<item>Linux のサポート: <em>カーネル組み込みのドライバ</em>
<item>最高帯域幅: <em>2.5 M ビット/秒</em>
<item>最低遅延: <em>1,000 マイクロ秒 ?</em>
<item>利用できるのは: <em>複数のベンダーのハードウェア</em>
<item>ポートもしくはバスのインタフェース: <em>ISA</em>
<item>ネットワーク構成: <em>ダムハブもしくはバス接続(論理的にはリング構成)</em>
<item>接続マシン当りのコスト: <em>200 ドル</em>
</itemize>
<p>

<!--
ARCNET is a local area network that is primarily intended for use in
embedded real-time control systems.  Like Ethernet, the network is
physically organized either as taps on a bus or one or more hubs,
however, unlike Ethernet, it uses a token-based protocol logically
structuring the network as a ring.  Packet headers are small (3 or 4
bytes) and messages can carry as little as a single byte of data.
Thus, ARCNET yields more consistent performance than Ethernet, with
bounded delays, etc.  Unfortunately, it is slower than Ethernet and
less popular, making it more expensive.  More information is available
from the ARCNET Trade Association at <url
url="http://www.arcnet.com/">.
-->
ARCNET は LAN の一種で、そもそもは組込み用途のリアルタイム制御システム
用です。イーサネットのように、物理的にはバス上にタップを設けたり、ハブを 
1 つ以上置いて構築します。イーサネットと違う点は、トークンベースのプロト
コルを使っていて、論理的にはネットワークをリングとして構成します。
パケットのヘッダが小さく(3 もしくは 4 バイト)、メッセージを 1 バイトという
小さなデータとして送ります。
つまり ARCNET は、イーサネットよりも遅延も一定値以下で押えられる等、確実
にデータを伝送する機能を持っています。ただ残念なのは、イーサネットより
も速度が遅い上、あまり利用されておらず、そのせいで価格も高くなっています。
もっと詳しい情報は、the ARCNET Trade Association <url 
url="http://www.arcnet.com/"> で見られます。

<sect2>ATM
<p>
<itemize>
<!--
<item>Linux support: <em>kernel driver, AAL* library</em>
<item>Maximum bandwidth: <em>155 Mb/s</em> (soon, <em>1,200 Mb/s</em>)
<item>Minimum latency: <em>120 microseconds</em>
<item>Available as: <em>multiple-vendor hardware</em>
<item>Interface port/bus used: <em>PCI</em>
<item>Network structure: <em>switched hubs</em>
<item>Cost per machine connected: <em>&dollar;3,000</em>
-->
<item>Linux のサポート: <em>カーネル組込みのドライバと AAL* ライブラリ</em>
<item>最高帯域幅: <em>155 M ビット/秒</em> (まもなく <em>1,200 M ビット/秒
	</em>)
<item>最低遅延: <em>120 マイクロ秒</em>
<item>利用できるのは: <em>複数ベンダーのハードウェア</em>
<item>ポートもしくはバスのインタフェース: <em>PCI</em>
<item>ネットワーク構成: <em>スイッチング・ハブ</em>
<item>接続マシン当りのコスト: <em>3,000 ドル</em>
</itemize>
<p>

<!--
Unless you've been in a coma for the past few years, you have probably
heard a lot about how ATM (Asynchronous Transfer Mode) <em>is</em> the
future...  well, sort-of.  ATM is cheaper than HiPPI and faster than
Fast Ethernet, and it can be used over the very long distances that
the phone companies care about.  The ATM network protocol is also
designed to provide a lower-overhead software interface and to more
efficiently manage small messages and real-time communications (e.g.,
digital audio and video).  It is also one of the highest-bandwidth
networks that Linux currently supports.  The bad news is that ATM isn't
cheap, and there are still some compatibility problems across
vendors.  An overview of Linux ATM development is available at <url
url="http://lrcwww.epfl.ch/linux-atm/">.
-->
過去数年に渡りあなたが昏睡状態になかったとすれば、ATM(Asynchronous 
Transfer Mode)<em>はどんなに</em>明るい未来があり…といった話をいろいろ
聞いているはずです。 ATM は HiPPI より安価で、ファースト・イーサネット
よりも高速です。また非常に長距離間で使用できることから、電話会社が注目
しています。 ATM のネットワーク・プロトコルは、ソフトウェアへのインタ
フェースに対するオーバーヘッドが少なくなるように設計してあり、とても
効率良く小さなメッセージやリアルタイムな通信(例えばデジタル・オーディオ
やビデオ)を扱えるようになっています。また現状 Linux で利用できる帯域幅が
最も広いプロトコルの 1 つでもあります。ただ ATM は安価とはいえず、ベンダー
間で互換性の問題がいくつか生じてしまっています。Linux における ATM 関連の
開発の概要は、 <url url="http://lrcwww.epfl.ch/linux-atm/"> で見られます。

<sect2>CAPERS
<p>
<itemize>
<!--
<item>Linux support: <em>AFAPI library</em>
<item>Maximum bandwidth: <em>1.2 Mb/s</em>
<item>Minimum latency: <em>3 microseconds</em>
<item>Available as: <em>commodity hardware</em>
<item>Interface port/bus used: <em>SPP</em>
<item>Network structure: <em>cable between 2 machines</em>
<item>Cost per machine connected: <em>&dollar;2</em>
-->
<item>Linux のサポート: <em>AFAPI ライブラリ</em>
<item>最高帯域幅: <em>1.2 Mビット/秒</em>
<item>最低遅延: <em>3 マイクロ秒</em>
<item>利用できるのは: <em>市販のハードウェア</em>
<item>ポートもしくはバスのインタフェース: <em>SPP</em>
<item>ネットワーク構成: <em>2 台のマシン間をケーブルで接続</em>
<item>接続マシン当りのコスト: <em>2 ドル</em>
</itemize>
<p>

<!--
CAPERS (Cable Adapter for Parallel Execution and Rapid
Synchronization) is a spin-off of the PAPERS project, <url
url="http://garage.ecn.purdue.edu/~papers/">, at the Purdue University
School of Electrical and Computer Engineering.  In essence, it defines
a software protocol for using an ordinary "LapLink" SPP-to-SPP cable
to implement the PAPERS library for two Linux PCs.  The idea doesn't
scale, but you can't beat the price.  As with TTL&lowbar;PAPERS, to improve
system security, there is a minor kernel patch recommended, but not
required: <url
url="http://garage.ecn.purdue.edu/~papers/giveioperm.html">.
-->
CAPERS(Cable Adapter for Parallel Execution and Rapid Synchronization)
は、パーデュ大学の Electrical and Computer Engineering で行われている 
<!--
PAPERS プロジェクト <url url="http://garage.ecn.purdue.edu/~papers/"> 
-->
PAPERS プロジェクト <url url="http://aggregate.org/AFAPI/"> 
から派生したものです。この方式のポイントは、一般的に使われている「LapLink」
と呼ばれる標準プリンターポート間で使用するケーブルを使って、ソフトウェアで
実現するプロトコルです。PAPERS ライブラリで実装し、2 台の Linux PC を接続
します。このアイディアは拡張性はないものの、価格を気にする必要がありません。
TTL&lowbar;PAPERS を使えば、システムのセキュリティを向上できます。カーネル
にパッチを当てた方がいいのですが、必須ではありません。
<!--
<url url="http://garage.ecn.purdue.edu/~papers/giveioperm.html"> を参照してくだ
-->
<url url="http://aggregate.org/AFAPI/"> を参照してください。
<p>
【訳註：PAPERS 関連の資料は、著者がケンタッキー大学へ異動されたことで
<url url="http://aggregate.org/AFAPI/"> へ移っています】

<!-- <sect2>Ethernet -->
<sect2>イーサネット
<p>
<itemize>
<!--
<item>Linux support: <em>kernel drivers</em>
<item>Maximum bandwidth: <em>10 Mb/s</em>
<item>Minimum latency: <em>100 microseconds</em>
<item>Available as: <em>commodity hardware</em>
<item>Interface port/bus used: <em>PCI</em>
<item>Network structure: <em>switched or unswitched hubs, or hubless bus</em>
<item>Cost per machine connected: <em>&dollar;100</em> (hubless, <em>&dollar;50</em>)
-->
<item>Linux のサポート: <em>カーネル組込みのドライバ</em>
<item>最大帯域幅: <em>10 M ビット/秒</em>
<item>最低遅延: <em>100 マイクロ秒</em>
<item>利用できるものは: <em>市販のハードウェア</em>
<item>ポートもしくはバスのインタフェース: <em>PCI</em>
<item>ネットワーク構成: <em>スイッチングもしくはダムハブか、ハブを使わない
バス接続</em>
<item>接続マシン当りのコスト: <em>100 ドル</em> (ハブ無しだと <em>50 ドル</em>)
</itemize>
<p>

<!--
For some years now, 10 Mbits/s Ethernet has been the standard network
technology.  Good Ethernet interface cards can be purchased for well
under &dollar;50, and a fair number of PCs now have an Ethernet controller
built-into the motherboard.  For lightly-used networks, Ethernet
connections can be organized as a multi-tap bus without a hub; such
configurations can serve up to 200 machines with minimal cost, but are
not appropriate for parallel processing.  Adding an unswitched hub
does not really help performance.  However, switched hubs that can
provide full bandwidth to simultaneous connections cost only about
&dollar;100 per port.  Linux supports an amazing range of Ethernet
interfaces, but it is important to keep in mind that variations in the
interface hardware can yield significant performance differences.  See
the Hardware Compatibility HOWTO for comments on which are supported
and how well they work; also see <url
url="http://cesdis1.gsfc.nasa.gov/linux/drivers/">.
-->
ここ数年来、ネットワーク技術の標準と言えば 10 M ビット/秒のイーサネット
を指していました。イーサネットのインタフェースカードは良いものでも 50 
ドル以下で購入できます。またかなりの数の PC には、マザーボード上にもともと
イーサネットコントローラがついています。それ程負荷の高くないネットワーク
なら、イーサネットはハブを使わずに複数のタップを設けて構成しても十分です。
最小限のコストで作った構成でも 200 台までサービスを提供できますが、
並列処理には向かない環境です。ダムハブを設けてもパフォーマンスを上げる
ことはまったくできません。しかしスイッチング・ハブを設置すれば、帯域幅を
一杯まで使って同時に通信が可能になり、コストもポート当り 100 ドル程度で
すみます。Linux はイーサネットのインタフェースをかなり広範囲にサポートして
いますが、インタフェースのいろいろなハードウェア間でかなりパフォーマンス
に差がでてしまうことを気に止めておいてください。the Hardware Compatibility 
HOWTO を見れば、どれがサポートされていて、どのくらいきちんと動くかについての
コメントが読めます。
<url url="http://www.scyld.com/network/index.html"> も見てください。

<!--
An interesting way to improve performance is offered by the 16-machine
Linux cluster work done in the Beowulf project, <url
url="http://cesdis.gsfc.nasa.gov/linux/beowulf/beowulf.html">, at NASA
CESDIS.  There, Donald Becker, who is the author of many Ethernet card
drivers, has developed support for load sharing across multiple
Ethernet networks that shadow each other (i.e., share the same network
addresses).  This load sharing is built-into the standard Linux
distribution, and is done invisibly below the socket operation level.
Because hub cost is significant, having each machine connected to two
or more hubless or unswitched hub Ethernet networks can be a very
cost-effective way to improve performance.  In fact, in situations
where one machine is the network performance bottleneck, load sharing
using shadow networks works much better than using a single switched
hub network.
-->
パフォーマンスを上げる興味深い方法があります。それは、NASA の CESDIS
(the Center of Excellence in Space Data and Information Sciences)で
<!--
行われている Beowulf プロジェクト(<url 
url="http://cesdis.gsfc.nasa.gov/linux/beowulf/beowulf.html">)です。
-->
行われている Beowulf プロジェクト(<url url="http://www.beowulf.org/">)です。
ここでは、16 台のマシンで Linux クラスタを実現しています。このプロジェクト
には Donald Becker 氏というイーサネットカードのドライバを数多く作成した方
がいて、互いに見えない複数のイーサネットで構成しているネットワークにまたがる
負荷分散を実現するために開発を行っています
(つまり、同じネットワークアドレスを共有するということ)。この負荷分散は、
Linux の標準的なディストリビューションに最初から含まれていて、ソケット
レベルの操作よりも下位の層には隠されています。
ハブのコストはばかになりません。それぞれのマシンを 2 つ以上のハブに接続
しないで済ますか、ダムハブでイーサネットのネットワークに接続できれば、
費用をかけずにパフォーマンスを上げるとても良い方法となります。実際に、
1 台のマシンがネットワークの性能のボトルネックになっている状況では、
隠れたネットワークを使った負荷分散は、1 つのスイッチング・ハブで構成した
ネットワークよりもパフォーマンスに優れています。

<!-- <sect2>Ethernet (Fast Ethernet) -->
<sect2>イーサネット(ファースト・イーサネット)
<p>
<itemize>
<!--
<item>Linux support: <em>kernel drivers</em>
<item>Maximum bandwidth: <em>100 Mb/s</em>
<item>Minimum latency: <em>80 microseconds</em>
<item>Available as: <em>commodity hardware</em>
<item>Interface port/bus used: <em>PCI</em>
<item>Network structure: <em>switched or unswitched hubs</em>
<item>Cost per machine connected: <em>&dollar;400?</em>
-->
<item>Linux のサポート: <em>カーネル組込みのドライバ</em>
<item>最大帯域幅: <em>100 M ビット/秒</em>
<item>最低遅延: <em>80 マイクロ秒</em>
<item>利用できるものは: <em>市販のハードウェア</em>
<item>ポートもしくはバスのインタフェース: <em>PCI</em>
<item>ネットワークの構成: <em>スイッチングもしくはダムハブ</em>
<item>接続マシン当りのコスト: <em>400? ドル</em>
</itemize>
<p>

<!--
Although there are really quite a few different technologies calling
themselves "Fast Ethernet," this term most often refers to a hub-based
100 Mbits/s Ethernet that is somewhat compatible with older "10 BaseT"
10 Mbits/s devices and cables.  As might be expected, anything called
Ethernet is generally priced for a volume market, and these interfaces
are generally a small fraction of the price of 155 Mbits/s ATM cards.
The catch is that having a bunch of machines dividing the bandwidth of
a single 100 Mbits/s "bus" (using an unswitched hub) yields
performance that might not even be as good on average as using 10
Mbits/s Ethernet with a switched hub that can give each machine's
connection a full 10 Mbits/s.
-->
「速いイーサネット」と名前が付けられていますが、かなり異なった技術を採用
しています。しかし、ハブベースで 100 M ビット/秒を実現するイーサネット
として、それ以前の「10 BaseT」と呼ばれる 10 M ビット/秒で使われるデバイス
とケーブルと多少は互換性があるものとしてよく引き合いに出されます。
大方の予想通り、イーサネットと言われるものすべてはおよそ大きな市場向けに
価格設定してあり、そのインタフェースは 155 M ビット/秒の ATM カードに比べる
と取るに足らない価格設定になっています。
難点は 1 本の 100 M ビット/秒の「バス」(ダムハブを使用)の帯域を分割して
複数のマシンがまとまって利用すると、恐らくスイッチング・ハブを使って
それぞれのマシンが 10 M ビット/秒をフルに利用している 10 M ビット/秒の
イーサネットと平均して同じくらいのパフォーマンスが出せない点にあります。

<!--
Switched hubs that can provide 100 Mbits/s for each machine
simultaneously are expensive, but prices are dropping every day, and
these switches do yield much higher total network bandwidth than
unswitched hubs.  The thing that makes ATM switches so expensive is
that they must switch for each (relatively short) ATM cell; some Fast
Ethernet switches take advantage of the expected lower switching
frequency by using techniques that may have low latency through the
switch, but take multiple milliseconds to change the switch path...
if your routing pattern changes frequently, avoid those switches.  See
<url url="http://cesdis1.gsfc.nasa.gov/linux/drivers/"> for information
about the various cards and drivers.
-->
それぞれのマシンが同時に 100 M ビット/秒を利用できるスイッチング・ハブ
はとても高価ですが、価格は日々下がっていてダムハブと比較してネットワーク
全体としての帯域はとても広くできます。ATM スイッチが高価になっている
わけは、ATM のセル(イーサネットと比べて小さい)それぞれをスイッチし
ないといけないからです。ファースト・イーサネット用のスイッチの中には、
スイッチする頻度が低いと思われる場合に、効果を発揮するものがあります。
それを実現している技術は、スイッチを通過する間の遅延は低いのですが、
スイッチのパスが変更されると、数ミリ秒の遅延が発生してしまいす…。
経路の変更が頻繁に起こる場合は、そのようなスイッチは避けましょう。
カードやドライバについてのいろいろな情報は、<url 
url="http://www.scyld.com/network/"> を見てください。

<!--
Also note that, as described for Ethernet, the Beowulf project, <url
url="http://cesdis.gsfc.nasa.gov/linux/beowulf/beowulf.html">, at NASA
has been developing support that offers improved performance by load
sharing across multiple Fast Ethernets.
-->
またイーサネットについては、NASA の Beowulf プロジェクト <url 
url="http://www.beowulf.org/">において
複数のファースト・イーサネット間で負荷分散を行い、パフォーマンスを向上させる
技術を開発していることも忘れないでください。
<p>
【訳註：Beowulf プロジェクトは、Don Becker 氏をはじめとする Beowulf 
プロジェクトのメンバーによって設立された <url url="http://www.scyld.com" 
name="Scyld Computing Corporation"> にその活動の場が移行しています。

<!-- <sect2>Ethernet (Gigabit Ethernet) -->
<sect2>イーサネット(ギガビット・イーサネット)
<p>

<itemize>
<!--
<item>Linux support: <em>kernel drivers</em>
<item>Maximum bandwidth: <em>1,000 Mb/s</em>
<item>Minimum latency: <em>300 microseconds?</em>
<item>Available as: <em>multiple-vendor hardware</em>
<item>Interface port/bus used: <em>PCI</em>
<item>Network structure: <em>switched hubs or FDRs</em>
<item>Cost per machine connected: <em>&dollar;2,500?</em>
</itemize>
-->
<item>Linux のサポート: <em>カーネル組込みのドライバ</em>
<item>最大帯域幅: <em>1,000 M ビット/秒</em>
<item>最低遅延: <em>300 マイクロ秒 ?</em>
<item>利用できるものは: <em>複数ベンダーのハードウェア</em>
<item>ポートもしくはバスのインタフェース: <em>PCI</em>
<item>ネットワークの構成: <em>スイッチング・ハブもしくは FDR
(全二重リピータハブ)</em>
<item>接続マシン当りのコスト: <em>2,500 ドル ?</em>
</itemize>
<p>

<!--
I'm not sure that Gigabit Ethernet, <url
url="http://www.gigabit-ethernet.org/">, has a good technological
reason to be called Ethernet...  but the name does accurately reflect
the fact that this is intended to be a cheap, mass-market, computer
network technology with native support for IP.  However, current
pricing reflects the fact that Gb/s hardware is still a tricky thing
to build.
-->
ギガビット・イーサネットについてはよくわかりません。
<!--
<url url="http://www.gigabit-ethernet.org/"> でなぜイーサネットと呼ぶかの
-->
<url url="http://www.cis.ohio-state.edu/~jain/refs/gbe_refs.htm"> でなぜ
イーサネットと呼ぶかの技術的な説明がありますが…しかし正しくはギガビット・
イーサネットが安価かつ一般市場向けであり、IP をもともとサポートした
コンピュータ向けのネットワークをターゲットにしているということに
他なりません。しかし現在の価格を見ると、まだギガビット・イーサネットの
機材は構築するのにはまだ心配なところがあるのも事実です。

<!--
Unlike other Ethernet technologies, Gigabit Ethernet provides for a
level of flow control that should make it a more reliable network.
FDRs, or Full-Duplex Repeaters, simply multiplex lines, using
buffering and localized flow control to improve performance.  Most
switched hubs are being built as new interface modules for existing
gigabit-capable switch fabrics.  Switch/FDR products have been shipped
or announced by at least <url url="http://www.acacianet.com/">, <url
url="http://www.baynetworks.com/">, <url
url="http://www.cabletron.com/">, <url
url="http://www.networks.digital.com/">, <url
url="http://www.extremenetworks.com/">, <url
url="http://www.foundrynet.com/">, <url
url="http://www.gigalabs.com/">, <url
url="http://www.packetengines.com/">.  <url
url="http://www.plaintree.com/">, <url url="http://www.prominet.com/">,
<url url="http://www.sun.com/">, and <url url="http://www.xlnt.com/">.
-->
他のイーサネット技術とは異なり、ギガビット・イーサネットはフロー制御の
機能を持っていて、より信頼性の高いネットワークが構築できるはずです。
FDR もしくは全二重のリピータ、単純な多重回線などバッファリングや局所的な
フロー制御を行うことで、パフォーマンスが向上します。スイッチング・ハブ
の大部分は、既存のギガビット・イーサネットを利用できる部品を新しいインタ
フェース・モジュールとして組み込んでいます。スイッチや FDR 製品は少なく
とも次のメーカーから出荷されていたり、製品化がアナウンスされています。 
<url url="http://www.acacianet.com/">、<url 
url="http://www.baynetworks.com/">、<url 
url="http://www.cabletron.com/">、<url 
url="http://www.networks.digital.com/">、<url 
url="http://www.extremenetworks.com/">、<url 
url="http://www.foundrynet.com/">、<url 
url="http://www.gigalabs.com/">、<url 
url="http://www.packetengines.com/">、<url 
url="http://www.plaintree.com/">、<url url="http://www.prominet.com/">、
<url url="http://www.sun.com/">、<url url="http://www.xlnt.com/">。

<!--
There is a Linux driver, <url
url="http://cesdis.gsfc.nasa.gov/linux/drivers/yellowfin.html">, for
the Packet Engines "Yellowfin" G-NIC, <url
url="http://www.packetengines.com/">.  Early tests under Linux achieved
about 2.5x higher bandwidth than could be achieved with the best 100
Mb/s Fast Ethernet; with gigabit networks, careful tuning of PCI bus
use is a critical factor.  There is little doubt that driver
improvements, and Linux drivers for other NICs, will follow.
-->
Linux のドライバは <url url="http://www.scyld.com/network/yellowfin.html"> 
に Packet Engines <url url="http://www.packetengines.com/"> 製の「Yellowfin」
G-NIC 用があります。
Linux での初期段階のテストでは、高性能な 100 M ビット/秒の
ファースト・イーサネットが出せる帯域幅のおよそ 2.5 倍の性能がでています。
ギガビット・イーサネットのネットワークでは PCI バスを慎重にチューニング
することがとても大切になります。ドライバが改良され、他の NIC 用の Linux 
ドライバが後を追って出てくることは間違いありません。
<p>
【訳註：上記ドライバに加えて、Alteon の AceNIC と 3Com の 3C985/NetGear 
GA620 Gigabit、Packet Engines の GNIC-II (Hamachi)、SysKonnect の SK-98xx 
がサポートされています】

<!-- <sect2>FC (Fibre Channel) -->
<sect2>FC (ファイバー・チャネル)
<p>
<itemize>
<!--
<item>Linux support: <em>no</em>
<item>Maximum bandwidth: <em>1,062 Mb/s</em>
<item>Minimum latency: <em>?</em>
<item>Available as: <em>multiple-vendor hardware</em>
<item>Interface port/bus used: <em>PCI?</em>
<item>Network structure: <em>?</em>
<item>Cost per machine connected: <em>?</em>
-->
<item>Linux のサポート: <em>no</em>
<item>最大帯域幅: <em>1,062 M ビット/秒</em>
<item>最低遅延: <em>?</em>
<item>利用できるのは: <em>複数ベンダーのハードウェア</em>
<item>ポートもしくはバスのインタフェース: <em>PCI?</em>
<item>ネットワークの構成: <em>?</em>
<item>接続マシン当りのコスト: <em>?</em>
</itemize>
<p>

<!--
The goal of FC (Fibre Channel) is to provide high-performance block
I/O (an FC frame carries a 2,048 byte data payload), particularly for
sharing disks and other storage devices that can be directly connected
to the FC rather than connected through a computer.  Bandwidth-wise,
FC is specified to be relatively fast, running anywhere between 133
and 1,062 Mbits/s.  If FC becomes popular as a high-end SCSI
replacement, it may quickly become a cheap technology; for now, it is
not cheap and is not supported by Linux.  A good collection of FC
references is maintained by the Fibre Channel Association at <url
url="http://www.amdahl.com/ext/CARP/FCA/FCA.html">
-->
FC(ファイバー・チャネル)の目指すところは、高性能なブロック型の入出力
(FC のフレームは 一度に最大 2,048 バイトのデータを伝送できます)で、
特にディスクや他の記憶装置をコンピュータ経由で接続せずに FC に直接接続
して共有できます。帯域幅に関していえば、FC は 比較的高速なものに分類でき、
133 〜 1,062 M ビット/秒の速さの範囲で動作します。FC がハイエンドの 
SCSI にとってかわるほど一般的になれば、急速に安価な技術になると思われ
ます。現状は高価であり、Linux はサポートしていません。FC については、
the Fibre Channel Association が維持管理している 
<!--
<url url="http://www.amdahl.com/ext/CARP/FCA/FCA.html"> が参考文献として良い
-->
<url url="http://www.fibrechannel.com/"> が参考文献として良いでしょう。
<p>
【訳註：上記サイトの日本版は、<url url="http://www.fcaj.org/"> です。また、
Compaq の Fibre Channel 64-bit/66Mhz HBA(SCSI low-level drivers として)や 
Interphase の 5526 Tachyon chipset based adaptor(Token がサポートされています】

<sect2>FireWire (IEEE 1394)
<p>
<itemize>
<!--
<item>Linux support: <em>no</em>
<item>Maximum bandwidth: <em>196.608 Mb/s</em> (soon, <em>393.216 Mb/s</em>)
<item>Minimum latency: <em>?</em>
<item>Available as: <em>multiple-vendor hardware</em>
<item>Interface port/bus used: <em>PCI</em>
<item>Network structure: <em>random without cycles (self-configuring)</em>
<item>Cost per machine connected: <em>&dollar;600</em>
-->
<item>Linux のサポート: <em>no</em>
<item>最大帯域幅: <em>196.608 M ビット/秒</em> (まもなく、<em>393.216 M 
ビット/秒</em>になる)
<item>最低遅延: <em>?</em>
<item>利用できるのは: <em>複数ベンダーのハードウェア</em>
<item>ポートもしくはバスのインタフェース: <em>PCI</em>
<item>ネットワークの構成: <em>ループしていないなら何でも(自動設定)</em>
<item>接続マシン当りのコスト: <em>600 ドル</em>
</itemize>
<p>

<!--
FireWire, <url url="http://www.firewire.org/">, the IEEE 1394-1995
standard, is destined to be the low-cost high-speed digital network
for consumer electronics.  The showcase application is connecting DV
digital video camcorders to computers, but FireWire is intended to be
used for applications ranging from being a SCSI replacement to
interconnecting the components of your home theater.  It allows up to
64K devices to be connected in any topology using busses and bridges
that does not create a cycle, and automatically detects the
configuration when components are added or removed.  Short (four-byte
"quadlet") low-latency messages are supported as well as ATM-like
isochronous transmission (used to keep multimedia messages
synchronized).  Adaptec has FireWire products that allow up to 63
devices to be connected to a single PCI interface card, and also has
good general FireWire information at <url
url="http://www.adaptec.com/serialio/">.
-->
<!--
FireWire(<url url="http://www.firewire.org/">)は、IEEE 1394-1995 で
-->
FireWire(<url url="http://www.apple.com/firewire/">)は、IEEE 1394-1995 で
標準化されていて、安価で高速なデジタルネットワークを家庭用電化製品に
もたらすことを目指しています。現在の代表的な用途はデジタルビデオカムと
コンピュータの接続ですが、そもそもは SCSI の代替からホームシアターに
ある機材間の接続までをカバーすることを目指しています。65,536 個の
デバイスが接続可能で、ループしていないバス型やブリッジ型であればどんな
接続のしかたでもかまいません。また機器を抜き差しすると、自動的に構成を
検知することができます。小さく(4 バイト。「quadlet」と呼ばれている)、
遅延の少ないメッセージがサポートされていて、これは ATM の 等時性伝送
(isochronous transmission)(マルチメディア用メッセージの同期をとるため
に使用)と同じようなものです。Adaptec は、FireWire 製品を扱っていて、
63 個のデバイスを 1 枚の PCI インタフェースカードに接続できます。また
<!--
FireWire 全般の情報も <url url="http://www.adaptec.com/serialio/"> で
-->
FireWire 全般の情報も 
<url 
url="http://www.adaptec.com/worldwide/product/prodtechindex.html?cat=%2fTechnology%2"> で公開しています。

<!--
Although FireWire will not be the highest bandwidth network available,
the consumer-level market (which should drive prices very low) and low
latency support might make this one of the best Linux PC cluster
message-passing network technologies within the next year or so.
-->
FireWire では最高の帯域幅を持つネットワークを利用できるようにはならない
と思います。しかし一般消費者相手の市場(低価格路線をとる必要がある)を狙って
いること、遅延が少ないことから、ここ数年内に Linux PC でのクラスタの
メッセージ通信用ネットワーク技術の最適解の 1 つとなると思われます。

<!-- <sect2>HiPPI And Serial HiPPI -->
<sect2>HiPPI と Serial HiPPI
<p>
<itemize>
<!--
<item>Linux support: <em>no</em>
<item>Maximum bandwidth: <em>1,600 Mb/s</em> (serial is <em>1,200 Mb/s</em>)
<item>Minimum latency: <em>?</em>
<item>Available as: <em>multiple-vendor hardware</em>
<item>Interface port/bus used: <em>EISA, PCI</em>
<item>Network structure: <em>switched hubs</em>
<item>Cost per machine connected: <em>&dollar;3,500</em> (serial is <em>&dollar;4,500</em>)
-->
<item>Linux のサポート: <em>なし</em>
<item>最大帯域幅: <em>1,600 M ビット/秒</em> (serial は <em>1,200 M ビット/
秒</em>)
<item>最低遅延: <em>?</em>
<item>利用できるものは: <em>複数ベンダーのハードウェア</em>
<item>ポートもしくはバスのインタフェース: <em>EISA、PCI</em>
<item>ネットワークの構成: <em>スイッチング・ハブ</em>
<item>接続マシン当たりのコスト: <em>3,500 ドル</em> (serial is <em>4,500 
ドル</em>)
</itemize>
<p>

<!--
HiPPI (High Performance Parallel Interface) was originally intended to
provide very high bandwidth for transfer of huge data sets between a
supercomputer and another machine (a supercomputer, frame buffer, disk
array, etc.), and has become the dominant standard for
supercomputers.  Although it is an oxymoron, <bf>Serial HiPPI</bf> is
also becoming popular, typically using a fiber optic cable instead of
the 32-bit wide standard (parallel) HiPPI cables.  Over the past few
years, HiPPI crossbar switches have become common and prices have
dropped sharply; unfortunately, serial HiPPI is still pricey, and that
is what PCI bus interface cards generally support.  Worse still, Linux
doesn't yet support HiPPI.  A good overview of HiPPI is maintained by
CERN at <url url="http://www.cern.ch/HSI/hippi/">; they also maintain
a rather long list of HiPPI vendors at <url
url="http://www.cern.ch/HSI/hippi/procintf/manufact.htm">.
-->
HiPPI(High Performance Parallel Interface)はもともと非常に大きなデータ
の伝送をスーパーコンピュータやその他のマシン(スーパーコンピュータや
フレームバッファ、ディスクアレイ等)間で帯域幅を大きくとって行うことを
目的として作られました。そしてスーパーコンピュータの分野では、事実上の
標準となっています。<bf>Serial HiPPI</bf> も一般的になってきており、
32 ビット幅の標準(パラレル)の HiPPI ケーブルを使わずに、光ファイバの
ケーブルを普通は利用します。serial と言いながら光ケーブルを使うのは
へんですが。数年前から HiPPI を使ったクロスバースイッチが広がっており、
価格が急激に下がっています。PCI インタフェースカードをサポートしている 
serial HiPPI は依然として割高なのが残念です。さらに残念なことに、Linux 
は HiPPI をまだサポートしていません。CERN が作っている HiPPI の優れた
概略は <url 
url="http://www.cern.ch/HSI/hippi/"> にあります。CERN はこの他にも HiPPI 
を扱っている数多くのベンダー一覧を <url
url="http://www.cern.ch/HSI/hippi/procintf/manufact.htm"> で公開してい
ます。
<p>
【訳註：HiPPI は EXPERIMENTAL でサポートされています】

<sect2>IrDA (Infrared Data Association)
<p>
<itemize>
<!--
<item>Linux support: <em>no?</em>
<item>Maximum bandwidth: <em>1.15 Mb/s</em> and <em>4 Mb/s</em>
<item>Minimum latency: <em>?</em>
<item>Available as: <em>multiple-vendor hardware</em>
<item>Interface port/bus used: <em>IrDA</em>
<item>Network structure: <em>thin air</em> ;-)
<item>Cost per machine connected: <em>&dollar;0</em>
-->
<item>Linux のサポート: <em>なし ?</em>
<item>最大帯域幅: <em>1.15 M ビット/秒</em> と <em>4 M ビット/秒</em>
<item>最低遅延: <em>?</em>
<item>利用できるものは: <em>複数ベンダーのハードウェア</em>
<item>ポートもしくはバスのインタフェース: <em>IrDA</em>
<item>ネットワークの構成: <em>見えません</em> ;-)
<item>接続マシン当りのコスト: <em>0 ドル</em>
</itemize>
<p>

<!--
IrDA (Infrared Data Association, <url url="http://www.irda.org/">) is
that little infrared device on the side of a lot of laptop PCs.  It is
inherently difficult to connect more than two machines using this
interface, so it is unlikely to be used for clustering.  Don Becker
did some preliminary work with IrDA.
-->
IrDA(Infrared Data Association <url url="http://www.irda.org/">)は
小さな赤外線を使ったデバイスで、多くのラップトップタイプの PC の側面
についています。このインタフェースを使って、2 台以上のマシンを接続する
のはそもそも困難なので、クラスタで利用するのは適切ではありません。
Don Becker 氏が 何とか IrDA を使えるようにしました。
<p>
【訳註：正式にサポートしています】

<sect2>Myrinet
<p>
<itemize>
<!--
<item>Linux support: <em>library</em>
<item>Maximum bandwidth: <em>1,280 Mb/s</em>
<item>Minimum latency: <em>9 microseconds</em>
<item>Available as: <em>single-vendor hardware</em>
<item>Interface port/bus used: <em>PCI</em>
<item>Network structure: <em>switched hubs</em>
<item>Cost per machine connected: <em>&dollar;1,800</em>
-->
<item>Linux のサポート: <em>ライブラリ</em>
<item>最大帯域幅: <em>1,280 M ビット/秒</em>
<item>最小遅延: <em>9 マイクロ秒</em>
<item>利用できるものは: <em>単独ベンダーのハードウェア</em>
<item>ポートもしくはバスのインタフェース: <em>PCI</em>
<item>ネットワークの構成: <em>スイッチング・ハブ</em>
<item>接続マシン当りのコスト: <em>1,800 ドル</em>
</itemize>
<p>

<!--
Myrinet <url url="http://www.myri.com/"> is a local area network (LAN)
designed to also serve as a "system area network" (SAN), i.e., the
network within a cabinet full of machines connected as a parallel
system.  The LAN and SAN versions use different physical media and
have somewhat different characteristics; generally, the SAN version
would be used within a cluster.
-->
Myrinet(<url url="http://www.myri.com/">)はローカル・エリア・ネット
ワーク(LAN)の 1 つで、「システム・エリア・ネットワーク」(SAN)も実現する
ように設計してあります。つまり、そのネットワークは 1 つのキャビネット
内にマシンを収納し接続することで、並列システムを構成できます。LAN と 
SAN では物理的な媒体が異なっていて、その特性も若干違います。通常 
SAN では、1 つのクラスタ内で使用するのが一般的です。

<!--
Myrinet is fairly conventional in structure, but has a reputation for
being particularly well-implemented.  The drivers for Linux are said
to perform very well, although shockingly large performance variations
have been reported with different PCI bus implementations for the host
computers.
-->
Myrinet は構成上新しいところはほとんどありませんが、パフォーマンスが
とても良いと評判です。Linux 用のドライバは性能がとても良いと言われて
いますが、ホストコンピュータに付ける PCI バスの実装毎にパフォーマンス
の差がひどく大きいとも言われています。

<!--
Currently, Myrinet is clearly the favorite network of cluster groups
that are not too severely "budgetarily challenged."  If your idea of a
Linux PC is a high-end Pentium Pro or Pentium II with at least 256 MB
RAM and a SCSI RAID, the cost of Myrinet is quite reasonable.  However,
using more ordinary PC configurations, you may find that your choice
is between <em>N</em> machines linked by Myrinet or <em>2N</em> linked
by multiple Fast Ethernets and TTL&lowbar;PAPERS.  It really depends
on what your budget is and what types of computations you care about
most.
-->
現状では、Myrinet はクラスタを構築する際に「予算獲得」にそれほどシビア
になる必要がないグループにとっては、とても魅力的なネットワークです。
Linux PC にハイエンドな Pentium Pro や Pentium II、少なくとも 256 MB の 
RAM を搭載して、SCSI RAID も入れるぐらいなら、Myrinet は手頃といっても
いいでしょう。しかしもっと普通の PC で構成するなら、選択肢として <em>N
</em> 台のマシンを Myrinet で接続するか、<em>2N</em> 台を複数のファースト・
イーサネットで TTL&lowbar;PAPERS を使って接続するかのどちらかにするので
はないでしょうか。これは予算がいくらで、計算する事に対して何に一番注意を
向けるかによるところが大きいです。

<sect2>Parastation
<p>
<itemize>
<!--
<item>Linux support: <em>HAL or socket library</em>
<item>Maximum bandwidth: <em>125 Mb/s</em>
<item>Minimum latency: <em>2 microseconds</em>
<item>Available as: <em>single-vendor hardware</em>
<item>Interface port/bus used: <em>PCI</em>
<item>Network structure: <em>hubless mesh</em>
<item>Cost per machine connected: <em>&gt; &dollar;1,000</em>
-->
<item>Linux のサポート: <em>HAL もしくはソケット・ライブラリ</em>
<item>最大帯域幅: <em>125 M ビット/秒</em>
<item>最低遅延: <em>2 マイクロ秒</em>
<item>利用できるものは: <em>単独ベンダーのハードウェア</em>
<item>ポートもしくはバスのインタフェース: <em>PCI</em>
<item>ネットワークの構成: <em>メッシュ状でハブを置かない</em>
<item>接続マシン当りのコスト: <em>1,000 ドル以上</em>
</itemize>
<p>

<!--
The ParaStation project <url
url="http://wwwipd.ira.uka.de/parastation"> at University of Karlsruhe
Department of Informatics is building a PVM-compatible custom
low-latency network.  They first constructed a two-processor ParaPC
prototype using a custom EISA card interface and PCs running BSD UNIX,
and then built larger clusters using DEC Alphas.  Since January 1997,
ParaStation has been available for Linux.  The PCI cards are being
made in cooperation with a company called Hitex (see <url
url="http://www.hitex.com:80/parastation/">).  Parastation hardware
implements both fast, reliable, message transmission and simple barrier
synchronization.
-->
ParaStation プロジェクト(<url url="http://wwwipd.ira.uka.de/parastation">)
は、University of Karlsruhe Department of Informatics で行われていて、
PVM 互換の遅延が少ない特注のネットワークです。まずこのプロジェクトでは 
2 個のプロセッサを搭載した ParaPC のプロトタイプを作り上げ、それに独自
の EISA カードのインタフェースを搭載し、BSD系の UNIX を走らせました。
それから DEC の Alpha マシンを使って大規模なクラスタを構築しました。1997 
年 1 月から、Linux でも ParaStation が利用できるようになりました。PCI 
カードは Hitex(<url url="http://www.hitex.com:80/parastation/"> を参照して
ください)という企業と共同で開発しました。ParaStation のハードウェアには、
高速で、信頼性があり、メッセージ通信や簡潔なバリア同期も備わっています。
<p>
【訳註：Hitex のハードウェアは現在使用していません。Myrinet
(http://www.myri.com/)を採用しています】

<sect2>PLIP
<p>
<itemize>
<!--
<item>Linux support: <em>kernel driver</em>
<item>Maximum bandwidth: <em>1.2 Mb/s</em>
<item>Minimum latency: <em>1,000 microseconds?</em>
<item>Available as: <em>commodity hardware</em>
<item>Interface port/bus used: <em>SPP</em>
<item>Network structure: <em>cable between 2 machines</em>
<item>Cost per machine connected: <em>&dollar;2</em>
-->
<item>Linux のサポート: <em>カーネル組込みのドライバ</em>
<item>最大帯域幅: <em>1.2 M ビット/秒</em>
<item>最低遅延: <em>1,000 マイクロ秒 ?</em>
<item>利用できるものは: <em>市販のハードウェア</em>
<item>ポートもしくはバスのインタフェース: <em>SPP</em>
<item>ネットワークの構成: <em>2 台のマシン間をケーブルで結ぶ</em>
<item>接続マシン当りのコスト: <em>2 ドル</em>
</itemize>
<p>

<!--
For just the cost of a "LapLink" cable, PLIP (Parallel Line Interface
Protocol) allows two Linux machines to communicate through standard
parallel ports using standard socket-based software.  In terms of
bandwidth, latency, and scalability, this is not a very serious
network technology; however, the near-zero cost and the software
compatibility are useful.  The driver is part of the standard Linux
kernel distributions.
-->
「ラップリンク」ケーブルのコストだけがかかります。PLIP(Parallel Line 
Interface Protocol)は、2 台の Linux マシンを標準パラレルポートで結んで、
普通のソケットベースのソフトウェアで通信を行います。帯域幅や遅延、拡張性
の面からすると本格的なネットワーク技術とはいえません。しかし、コストが
ほとんどただ同然なこと、ソフトウェアの互換性がある点では便利です。ドライバ
は普通の Linux カーネルのディストリビューションに含まれています。

<sect2>SCI
<p>
<itemize>
<!--
<item>Linux support: <em>no</em>
<item>Maximum bandwidth: <em>4,000 Mb/s</em>
<item>Minimum latency: <em>2.7 microseconds</em>
<item>Available as: <em>multiple-vendor hardware</em>
<item>Interface port/bus used: <em>PCI, proprietary</em>
<item>Network structure: <em>?</em>
<item>Cost per machine connected: <em>&gt; &dollar;1,000</em>
-->
<item>Linux のサポート: <em>no</em>
<item>最大帯域幅: <em>4,000 M ビット/秒</em>
<item>最小遅延: <em>2.7 マイクロ秒</em>
<item>利用できるものは: <em>複数ベンダーのハードウェア</em>
<item>ポートもしくはバスのインタフェース: <em>PCI と ベンダー独自のもの</em>
<item>ネットワークの構成: <em>?</em>
<item>接続マシン当りのコスト: <em>1,000 ドル</em>
</itemize>
<p>

<!--
The goal of SCI (Scalable Coherent Interconnect, ANSI/IEEE 1596-1992)
is essentially to provide a high performance mechanism that can
support coherent shared memory access across large numbers of
machines, as well various types of block message transfers.  It is
fairly safe to say that the designed bandwidth and latency of SCI are
both "awesome" in comparison to most other network technologies.  The
catch is that SCI is not widely available as cheap production units,
and there isn't any Linux support.
-->
SCI(Scalable Coherent Interconnect ANSI/IEEE 1596-1992)は、大規模なマシン
群で同期をとりながら共有メモリにアクセスする機能(様々なタイプのメッセージ
のブロック転送など)を高性能に提供するしくみを目指しています。SCI の設計は、
帯域幅と遅延において他のほとんどのネットワーク技術と比較して「素晴らしい」
と言って過言ではないでしょう。問題点は、SCI が安価な製品として広く利用
できないことと Linux をサポートしていないことです。

<!--
SCI primarily is used in various proprietary designs for
logically-shared physically-distributed memory machines, such as the
HP/Convex Exemplar SPP and the Sequent NUMA-Q 2000 (see <url
url="http://www.sequent.com/">).  However, SCI is available as a PCI
interface card and 4-way switches (up to 16 machines can be connected
by cascading four 4-way switches) from Dolphin, <url
url="http://www.dolphinics.com/">, as their CluStar product line.  A
good set of links overviewing SCI is maintained by CERN at <url
url="http://www.cern.ch/HSI/sci/sci.html">.
-->
主に SCI は、論理的には共有しているが物理的には分散しているメモリを搭載
しているメーカー独自のマシンに採用されています。例えば、HP/Convex の 
Exemplar SPP や Sequent の NUMA-Q 2000 (<url 
url="http://www.sequent.com/">)などです。しかし SCI は PCI インタフェース・
カードや 4 ポートのスイッチ(4 ポートのスイッチ 4 台をカスケードして、16 
台までのマシンを接続可能)が Dolphin(<url 
url="http://www.dolphinics.com/"> からクラスタ製品のラインナップとして
販売されています。CERN(<url url="http://www.cern.ch/HSI/sci/sci.html"> に
は優れた SCI の概説のリンク集があります。
<p>
【訳註：Sequent は 1998 年に IBM に吸収されました。NUMA シリーズは 
IBM @server x シリーズ及び IBM NUMA-Q として発売されています】

<sect2>SCSI
<p>
<itemize>
<!--
<item>Linux support: <em>kernel drivers</em>
<item>Maximum bandwidth: <em>5 Mb/s</em> to over <em>20 Mb/s</em>
<item>Minimum latency: <em>?</em>
<item>Available as: <em>multiple-vendor hardware</em>
<item>Interface port/bus used: <em>PCI, EISA, ISA card</em>
<item>Network structure: <em>inter-machine bus sharing SCSI devices</em>
<item>Cost per machine connected: <em>?</em>
-->
<item>Linux のサポート: <em>カーネル組込みのドライバ</em>
<item>最大帯域幅: <em>5 M ビット/秒</em> から <em>20 M ビット/秒以上</em>
<item>最小遅延: <em>?</em>
<item>利用できるものは: <em>複数ベンダーのハードウェア</em>
<item>ポートもしくはバスのインタフェース: <em>PCI、EISA、ISA カード</em>
<item>ネットワークの構成: <em>マシン間でバスを使って SCSI デバイスを共有</em>
<item>接続マシン当りのコスト: <em>?</em>
</itemize>
<p>

<!--
SCSI (Small Computer Systems Interconnect) is essentially an I/O bus
that is used for disk drives, CD ROMS, image scanners, etc.  There are
three separate standards SCSI-1, SCSI-2, and SCSI-3; Fast and Ultra
speeds; and data path widths of 8, 16, or 32 bits (with FireWire
compatibility also mentioned in SCSI-3).  It is all pretty confusing,
but we all know a good SCSI is somewhat faster than EIDE and can handle
more devices more efficiently.
-->
SCSI(Small Computer Systems Interconnect)は、元来ディスク・ドライブや 
CD-ROM、画像スキャナー等の入出力のためのバスです。SCSI-1 や SCSI-2、
SCSI-3 という独立した規格があります。また速度の面で Fast や Ultra、
データの転送幅として 8、16、32 ビット(FireWire との互換性は SCSI-3 に
定義してあります)があります。かなり複雑なのですが、性能の良い SCSI 
は EIDE より若干速く、より多くのデバイスをさらに効率的に扱えるのは
周知の事実です。

<!--
What many people do not realize is that it is fairly simple for two
computers to share a single SCSI bus.  This type of configuration is
very useful for sharing disk drives between machines and implementing
<bf>fail-over</bf> - having one machine take over database requests
when the other machine fails.  Currently, this is the only mechanism
supported by Microsoft's PC cluster product, WolfPack.  However, the
inability to scale to larger systems renders shared SCSI uninteresting
for parallel processing in general.
-->
2 台のコンピュータで 1 本の SCSI バスを共有できることに気づいていない
方が予想外にたくさんいます。このタイプの構成は、ディスク・ドライブを
マシン間で共有するのにとても便利で、<bf>フェイル・オーバー</bf>
を実現します。つまり、一方のマシンがおかしくなった時にそのマシンに対する
データベースへの要求を肩代わりするというように。現在のところ、Microsoft 
の PC クラスタ製品である WolfPack は、このしくみしか提供していません。
しかし SCSI を共有するこのしくみが、より大規模なシステムへと拡張できない
ことで、並列処理一般にとっては色あせたしくみになってしまっています。

<sect2>ServerNet
<p>
<itemize>
<!--
<item>Linux support: <em>no</em>
<item>Maximum bandwidth: <em>400 Mb/s</em>
<item>Minimum latency: <em>3 microseconds</em>
<item>Available as: <em>single-vendor hardware</em>
<item>Interface port/bus used: <em>PCI</em>
<item>Network structure: <em>hexagonal tree/tetrahedral lattice of hubs</em>
<item>Cost per machine connected: <em>?</em>
-->
<item>Linux のサポート: <em>no</em>
<item>最大帯域幅: <em>400 M ビット/秒</em>
<item>最低遅延: <em>3 マイクロ秒</em>
<item>利用できるものは: <em>単独ベンダーのハードウェア</em>
<item>ポートもしくはバスのインタフェース: <em>PCI</em>
<item>ネットワークの構成: <em>六面＋ツリー構造と四面＋格子構造を持つハブ</em>
<item>接続マシン当たりのコスト: <em>?</em>
</itemize>
<p>

<!--
ServerNet is the high-performance network hardware from Tandem, <url
url="http://www.tandem.com">.  Especially in the online transation
processing (OLTP) world, Tandem is well known as a leading producer of
high-reliability systems, so it is not surprising that their network
claims not just high performance, but also "high data integrity and
reliability."  Another interesting aspect of ServerNet is that it
claims to be able to transfer data from any device directly to any
device; not just between processors, but also disk drives, etc., in a
one-sided style similar to that suggested by the MPI remote memory
access mechanisms described in section 3.5.  One last comment about
ServerNet:  although there is just a single vendor, that vendor is
powerful enough to potentially establish ServerNet as a major
standard...  Tandem is owned by Compaq.
-->
ServerNet は Tandem(<url url="http://www.tandem.com">)から提供されて
いる高性能なネットワーク機器です。特にオンライン・トランザクション処理
(OLTP)の分野では、Tandem は高い信頼性も持ったシステムを作ることでは
トップクラスにあるのは有名です。ですから Tandem のネットワークがただ
パフォーマンスだけではなく、データの保全性と信頼性をも追求しているのは
当然のことです。もう 1 つ ServerNet が興味深い点は、あらゆるデバイス同士
が直接データをやりとりできる点にあります。プロセッサ間だけではなく、
ディスク・ドライブ間等でも可能です。セクション 3.5 で説明する MPI が推奨
しているローカルでないメモリに対しての片方向へのアクセスのしかたと似て
います。最後に 1 つだけ ServerNet についてコメントすることがあります。
単独ベンダーしかサポートしていませんが、そのベンダーは ServerNet を事実上
の標準にするだけの力があります… Tandem の親会社は Compaq ですから。
<p>
【訳註：「六面＋ツリー構造と四面＋格子構造を持つハブ」の具体的な図は、
<url url="http://www.compaq.co.jp/tandem/technology/servernet/whitepaper/BRKTECWP.html" name="ServerNet：大容量データの高速移動を可能にする新サーバー・
アーキテクチャー 超並列 I/O へのアプローチ">にある図(図 7 と 8)を参照
してください。ここにはより詳細な ServerNet の解説もあります】

<sect2>SHRIMP
<p>
<itemize>
<!--
<item>Linux support: <em>user-level memory mapped interface</em>
<item>Maximum bandwidth: <em>180 Mb/s</em>
<item>Minimum latency: <em>5 microseconds</em>
<item>Available as: <em>research prototype</em>
<item>Interface port/bus used: <em>EISA</em>
<item>Network structure: <em>mesh backplane (as in Intel Paragon)</em>
<item>Cost per machine connected: <em>?</em>
-->
<item>Linux のサポート: <em>ユーザレベルのメモリマッピングインタフェース</em>
<item>最大帯域幅: <em>180 M ビット/秒</em>
<item>最少遅延: <em>5 マイクロ秒</em>
<item>利用できるものは: <em>研究段階の試作品</em>
<item>ポートもしくはバスのインタフェース: <em>EISA</em>
<item>ネットワークの構成: <em>メッシュ状のバックプレイン(Intel の Paragon 
のように)</em>
<item>接続マシン当たりのコスト: <em>?</em>
</itemize>
<p>

<!--
The SHRIMP project, <url url="http://www.CS.Princeton.EDU/shrimp/">,
at the Princeton University Computer Science Department is building a
parallel computer using PCs running Linux as the processing elements.
The first SHRIMP (Scalable, High-Performance, Really Inexpensive
Multi-Processor) was a simple two-processor prototype using a
dual-ported RAM on a custom EISA card interface.  There is now a
prototype that will scale to larger configurations using a custom
interface card to connect to a "hub" that is essentially the same mesh
routing network used in the Intel Paragon (see <url
url="http://www.ssd.intel.com/paragon.html">).  Considerable effort
has gone into developing low-overhead "virtual memory mapped
communication" hardware and support software.
-->
SHRIMP プロジェクト(<url url="http://www.CS.Princeton.EDU/shrimp/">)
は、プリンストン大学の Computer Science Department で行われています。
Linux が動いている PC を演算ノードと見なし、1 台の並列コンピュータとして
構築しています。
最初の  SHRIMP(Scalable, High-Performance, Really Inexpensive 
Multi-Processor)は、独自の EISA カードのインタフェース上にデュアルポート
の RAM を積んで、プロセッサを 2 つ搭載した試作機でした。現状の試作機は、
より構成の規模が大きくなり、独自のインタフェース・カードを Intel の 
Paragon(<url url="http://www.ssd.intel.com/paragon.html"> を参照)
【訳註：リンク切れ】と同様なメッシュ状の経路を持つ「ハブ」に接続
しています。
オーバーヘッドを押さえた「仮想メモリにマップした通信」機器とそれをサポート
するソフトウェアの開発に精力を注ぎ込んでいます。
<p>
【訳註：Intel はスーパコンピュータの製造を中止しています。Paragon 
の姿は、<url url="http://www.cs.sandia.gov/HPCCIT/gif/paragon.gif"> で
見ることができます】

<sect2>SLIP
<p>
<itemize>
<!--
<item>Linux support: <em>kernel drivers</em>
<item>Maximum bandwidth: <em>0.1 Mb/s</em>
<item>Minimum latency: <em>1,000 microseconds?</em>
<item>Available as: <em>commodity hardware</em>
<item>Interface port/bus used: <em>RS232C</em>
<item>Network structure: <em>cable between 2 machines</em>
<item>Cost per machine connected: <em>&dollar;2</em>
-->
<item>Linux のサポート: <em>カーネル組み込みのドライバ</em>
<item>最大帯域幅: <em>0.1 M ビット/秒</em>
<item>最低遅延: <em>1,000 マイクロ秒 ?</em>
<item>利用できるものは: <em>市販のハードウェア</em>
<item>ポートもしくはバスのインタフェース: <em>RS232C</em>
<item>ネットワークの構成: <em>2 台のマシン間のケーブル</em>
<item>接続マシン当たりのコスト: <em>2 ドル</em>
</itemize>
<p>

<!--
Although SLIP (Serial Line Interface Protocol) is firmly planted at
the low end of the performance spectrum, SLIP (or CSLIP or PPP) allows
two machines to perform socket communication via ordinary RS232 serial
ports.  The RS232 ports can be connected using a null-modem RS232
serial cable, or they can even be connected via dial-up through a
modem.  In any case, latency is high and bandwidth is low, so SLIP
should be used only when no other alternatives are available.  It is
worth noting, however, that most PCs have two RS232 ports, so it would
be possible to network a group of machines simply by connecting the
machines as a linear array or as a ring.  There is even load sharing
software called EQL.
-->
SLIP(Serial Line Interface Protocol)は、パフォーマンスの点ではローエンド
に位置づけられます。しかし SLIP(もしくは CSLIP や PPP)は 2 台のマシンを
普通の RS232 シリアルポート経由でソケットベースの通信が可能です。RS232 
ポートはヌル・モデム RS232 シリアルケーブルを使って接続でき、またモデム
経由でダイヤルアップすることで接続することもできます。どの場合でも遅延が多く、
帯域幅は狭いため、SLIP は他に選択肢がない場合にだけ使うべきです。どこにも
いいところがありませんが、PC の大部分は RS232 を 2 ポート持っているので、
マシン間を直列もしくはリング状に接続することでネットワークが組めます。
負荷分散のために EQL というソフトウェアさえ用意されています。

<sect2>TTL&lowbar;PAPERS
<p>
<itemize>
<!--
<item>Linux support: <em>AFAPI library</em>
<item>Maximum bandwidth: <em>1.6 Mb/s</em>
<item>Minimum latency: <em>3 microseconds</em>
<item>Available as: <em>public-domain design, single-vendor hardware</em>
<item>Interface port/bus used: <em>SPP</em>
<item>Network structure: <em>tree of hubs</em>
<item>Cost per machine connected: <em>&dollar;100</em>
-->
<item>Linux のサポート: <em>AFAPI ライブラリ</em>
<item>最大帯域幅: <em>1.6 M ビット/秒</em>
<item>最低遅延: <em>3 マイクロ秒</em>
<item>利用できるものは: <em>パブリック・ドメインで設計した単独ベンダーの
ハードウェア</em>
<item>ポートもしくはバスのインタフェース: <em>SPP</em>
<item>ネットワークの構成: <em>ツリー状のハブ</em>
<item>接続マシン当たりのコスト: <em>100 ドル</em>
</itemize>
<p>

<!--
The PAPERS (Purdue's Adapter for Parallel Execution and Rapid
Synchronization) project, <url
url="http://garage.ecn.purdue.edu/~papers/">, at the Purdue University
School of Electrical and Computer Engineering is building scalable,
low-latency, aggregate function communication hardware and software
that allows a parallel supercomputer to be built using unmodified
PCs/workstations as nodes.
-->
PAPERS(Purdue's Adapter for Parallel Execution and Rapid Synchronization) 
<!--
プロジェクト(<url url="http://garage.ecn.purdue.edu/~papers/">)は、
-->
プロジェクト(<url url="http://aggregate.org/AFAPI/">)は、
パーデュ大学の School of Electrical and Computer Engineering で行われて
います。拡張性があり、遅延の少ない集合演算を実現する通信ハードウェアと
普通の PC やワークステーションを並列スーパーコンピュータのノードとして
構成できるソフトウェアを構築しています。

<!--
There have been over a dozen different types of PAPERS hardware built
that connect to PCs/workstations via the SPP (Standard Parallel Port),
roughly following two development lines.  The versions called "PAPERS"
target higher performance, using whatever technologies are appropriate;
current work uses FPGAs, and high bandwidth PCI bus interface designs
are also under development.  In contrast, the versions called
"TTL&lowbar;PAPERS" are designed to be easily reproduced outside
Purdue, and are remarkably simple public domain designs that can be
built using ordinary TTL logic.  One such design is produced
commercially, <url url="http://chelsea.ios.com:80/~hgdietz/sbm4.html">.
-->
数 10 タイプもの PAPERS のハードウェアがあり、SPP(Standard Parallel Port) 
経由で PC やワークステーションに接続しています。おおまかに言って 2 つの
開発計画が進められています。「PAPERS」と言われるものは、パフォーマンス
の向上を目的として、ふさわしいと思われるあらゆる技術を駆使しています。
現状は FPGA(Field Programmable Gate Array)を使い、広い帯域幅を持つ PCI 
バスインタフェースの設計を行っていて、両者とも開発中です。
「TTL&lowbar;PAPERS」はこれとは対照的で、パーデュ大学以外でも簡単に
構築できるように設計してあります。とてもシンプルかつパブリック・ドメイン
な設計で、一般的な TTL のロジックを使って構築しています。この設計は商用でも
利用されています(<url url="http://chelsea.ios.com:80/~hgdietz/sbm4.html">)
【訳註：リンク切れ】

<!--
Unlike the custom hardware designs from other universities,
TTL&lowbar;PAPERS clusters have been assembled at many universities
from the USA to South Korea.  Bandwidth is severely limited by the SPP
connections, but PAPERS implements very low latency aggregate function
communications; even the fastest message-oriented systems cannot
provide comparable performance on those aggregate functions.  Thus,
PAPERS is particularly good for synchronizing the displays of a video
wall (to be discussed further in the upcoming Video Wall HOWTO),
scheduling accesses to a high-bandwidth network, evaluating global
fitness in genetic searches, etc.  Although PAPERS clusters have been
built using IBM PowerPC AIX, DEC Alpha OSF/1, and HP PA-RISC HP-UX
machines, Linux-based PCs are the platforms best supported.
-->
他の大学が独自のハードウェアを設計しているのに対して、TTL&lowbar;PAPERS 
クラスタは米国から韓国に至るまで、幅広い大学で構築されています。帯域幅は
SPP による接続なので制限がいくつかありますが、PAPERS はほんのわずかの
遅延で集合演算通信を実現しています。メッセージ指向タイプのシステムの中で
最速のものでも、集合演算のパフォーマンスでは PAPAERS にはおよびません。
つまり PAPERS は、ビデオ・ウォールのモニター間の同期(近々に出る Video 
Wall HOWTO でさらに論じます)や広い帯域幅を持つネットワークへのアクセス
管理、遺伝研究における全体適応性の評価等に特に優れています。PAPERS 
クラスタは IBM の PowerPC AIX や旧 DEC(現 Compaq)の Alpha OSF/1、HP の 
PA-RISC HP-UX のマシンでも構築されていますが、Linux ベースの PC の
サポートが一番です。

<!--
User programs using TTL&lowbar;PAPERS AFAPI directly access the SPP
hardware port registers under Linux, without an OS call for each
access.  To do this, AFAPI first gets port permission using either
<tt>iopl()</tt> or <tt>ioperm()</tt>.  The problem with these calls is
that both require the user program to be privileged, yielding a
potential security hole.  The solution is an optional kernel patch,
<url url="http://garage.ecn.purdue.edu/~papers/giveioperm.html">, that
allows a privileged process to control port permission for any process.
-->
ユーザレベルのプログラム で TTL&lowbar;PAPERS AFAPI(Aggregate Function 
API)を使うと、Linux 配下で SPP に接続しているハードウェアポートのレジスタ
に直接アクセスしますので、アクセス毎にシステムコールは発生しません。
こうするには、まず AFAPI が <tt>iopl()</tt> や <tt>ioperm()</tt> を
使ってポートにアクセスできるようにします。ただこれらのシステムコール双方
とも、ユーザのプログラムに特権を持たせる必要があり、これが潜在的に
セキュリティ・ホールになる恐れがある点が問題となります。この問題を解決
するには、カーネルにパッチ
<!--
(<url url="http://garage.ecn.purdue.edu/~papers/giveioperm.html">)を追加して
-->
<url url="http://aggregate.org/AFAPI/">)を追加して
当てて、特権を持つプロセスがあらゆるプロセスのポートに対するアクセス権
を制御できるようにします。

<sect2>USB (Universal Serial Bus)
<p>
<itemize>
<!--
<item>Linux support: <em>kernel driver</em>
<item>Maximum bandwidth: <em>12 Mb/s</em>
<item>Minimum latency: <em>?</em>
<item>Available as: <em>commodity hardware</em>
<item>Interface port/bus used: <em>USB</em>
<item>Network structure: <em>bus</em>
<item>Cost per machine connected: <em>&dollar;5?</em>
-->
<item>Linux のサポート: <em>カーネル組み込みのドライバ</em>
<item>最大帯域幅: <em>12 M ビット/秒</em>
<item>最低遅延: <em>?</em>
<item>利用できるものは: <em>市販のハードウェア</em>
<item>ポートもしくはバスのインタフェース: <em>USB</em>
<item>Network の構成: <em>バス</em>
<item>接続マシン当たりのコスト: <em>5 ドル ?</em>
</itemize>
<p>

<!--
USB (Universal Serial Bus, <url url="http://www.usb.org/">) is a
hot-pluggable conventional-Ethernet-speed, bus for up to 127
peripherals ranging from keyboards to video conferencing cameras.  It
isn't really clear how multiple computers get connected to each other
using USB.  In any case, USB ports are quickly becoming as standard on
PC motherboards as RS232 and SPP, so don't be surprised if one or two
USB ports are lurking on the back of the next PC you buy.  Development
of a Linux driver is discussed at <url
url="http://peloncho.fis.ucm.es/~inaky/USB.html">.
-->
USB(Universal Serial Bus <url url="http://www.usb.org/">)は、電源を
入れたままで抜き差しでき、従来のイーサネット並みの速度が出すことが
できます。キーボードからビデオ会議用のカメラまで、周辺機器類を 127 
個までバスに接続できます。複数のコンピュータそれぞれを USB を使って
接続する方法はよくわかりません。いずれにしても USB ポートは RS232 や 
SPP と同様に PC のマザーボードにまもなく標準で付くことになりますので、
次に PC を購入する時に USB ポートが 1、2 つ付いていても不思議では
ありません。Linux のドライバの開発については、
<!--
<url url="http://peloncho.fis.ucm.es/~inaky/USB.html"> で議論しています。
-->
<url url="http://www.linux-usb.org/"> で議論しています。

<!--
In some ways, USB is almost the low-performance, zero-cost, version of
FireWire that you can purchase today.
-->
ある意味で USB は、パフォーマンスが低く、コストがかからない、現在購入可能
な FireWire の一種と言えないこともありません。

<sect2>WAPERS
<p>
<itemize>
<!--
<item>Linux support: <em>AFAPI library</em>
<item>Maximum bandwidth: <em>0.4 Mb/s</em>
<item>Minimum latency: <em>3 microseconds</em>
<item>Available as: <em>public-domain design</em>
<item>Interface port/bus used: <em>SPP</em>
<item>Network structure: <em>wiring pattern between 2-64 machines</em>
<item>Cost per machine connected: <em>&dollar;5</em>
-->
<item>Linux のサポート: <em>AFAPI ライブラリ</em>
<item>最大帯域幅: <em>0.4 M ビット/秒</em>
<item>最低遅延: <em>3 マイクロ秒</em>
<item>利用できるものは: <em>パブリック・ドメインな設計</em>
<item>ポートもしくはバスのインタフェース: <em>SPP</em>
<item>Network の構成: <em>2 から 64 台のマシン間の回路化</em>
<item>接続マシン当たりのコスト: <em>5 ドル</em>
</itemize>
<p>

<!--
WAPERS (Wired-AND Adapter for Parallel Execution and Rapid
Synchronization) is a spin-off of the PAPERS project, <url
url="http://garage.ecn.purdue.edu/~papers/">, at the Purdue University
School of Electrical and Computer Engineering.  If implemented
properly, the SPP has four bits of open-collector output that can be
wired together across machines to implement a 4-bit wide wired AND.
This wired-AND is electrically touchy, and the maximum number of
machines that can be connected in this way critically depends on the
analog properties of the ports (maximum sink current and pull-up
resistor value); typically, up to 7 or 8 machines can be networked by
WAPERS.  Although cost and latency are very low, so is bandwidth;
WAPERS is much better as a second network for aggregate operations
than as the only network in a cluster.  As with TTL&lowbar;PAPERS, to
improve system security, there is a minor kernel patch recommended,
but not required: <url
url="http://garage.ecn.purdue.edu/~papers/giveioperm.html">.
-->
WAPERS(Wired-AND Adapter for Parallel Execution and Rapid 
Synchronization)は、パーデュ大学の School of Electrical and Computer 
Engineering で行われている PAPERS プロジェクト<url 
url="http://garage.ecn.purdue.edu/~papers/">【訳註：リンク切れ】から
派生しました。きちんと実装してあれば、SPP は 4 ビットのオープン・コレクタ
出力ができ、マシン間をすべて回路化して、4 ビット幅の論理回路を実現します。
この論理回路は電気的に扱いにくく、この方法で接続できるマシンの最大数
もポートのアナログ特性に極めて依存しています(最大のシンク電流やプル
アップレジスタ値。通常 WAPERS では、ネットワークには 7、8 台の
マシンが接続できます。コストや遅延は低いものの、帯域幅も狭くなります。
WAPERS はクラスタ構成の中で唯一のネットワークとして使うというよりも、
集合演算の操作のための二次的なネットワークに適しています。
TTL&lowbar;PAPERS と同様に、システムのセキュリティを上げるのにはカーネル
への小さなパッチを当てることが推奨されていますが、必ずしも必要では
ありません(<url 
url="http://garage.ecn.purdue.edu/~papers/giveioperm.html">)。

<!-- <sect1>Network Software Interface -->
<sect1>ネットワークに対するソフトウェアのインタフェース
<p>

<!--
Before moving on to discuss the software support for parallel
applications, it is useful to first briefly cover the basics of
low-level software interface to the network hardware.  There are
really only three basic choices:  sockets, device drivers, and
user-level libraries.
-->
並列アプリケーションのソフトウェアのサポートを論じる前に、まず
ネットワーク機器に対する低レベルなソフトウェアのインタフェースの
基礎について、その概略を見ていくことにしましょう。基本的に選択肢
はたった 3 つしかありません。それはソケットとデバイス・ドライバと
ユーザレベルのライブラリです。

<!-- <sect2>Sockets -->
<sect2>ソケット
<p>

<!--
By far the most common low-level network interface is a socket
interface.  Sockets have been a part of unix for over a decade, and
most standard network hardware is designed to support at least two
types of socket protocols:  UDP and TCP.  Both types of socket allow
you to send arbitrary size blocks of data from one machine to another,
but there are several important differences.  Typically, both yield a
minimum latency of around 1,000 microseconds, although performance can
be far worse depending on network traffic.
-->
低レベルのネットワークに対するインタフェースで圧倒的に広く使われるは、
ソケット・インタフェースです。ソケットはずっと以前から UNIX の一機能
であり、標準的なネットワーク機器の大部分は少なくとも ソケットの 2 つの
タイプのプロトコルをサポートするように設計されています。それは UDP と TCP 
です。両タイプのソケットとも、あるマシンから他のマシンへ任意の大きさの
データブロックを送ることが可能です。しかし、根本的に異なる点もいくつか
あります。両者とも最低遅延はおおよそ 1,000 マイクロ秒程度ですが、その
性能はネットワーク上の流量によってはさらに低下します。

<!--
These socket types are the basic network software interface for most
of the portable, higher-level, parallel processing software; for
example, PVM uses a combination of UDP and TCP, so knowing the
difference will help you tune performance.  For even better
performance, you can also use these mechanisms directly in your
program.  The following is just a simple overview of UDP and TCP; see
the manual pages and a good network programming book for details.
-->
これらのタイプのソケットは、移植性やより高度なレベルを求める並列処理
ソフトとっては基本となるネットワークインタフェースです。例えば PVM 
は UDP と TCP を組み合わせて使用していますので、両者の相違を知ることで
パフォーマンスを向上できるようになるでしょう。さらにパフォーマンスを
上げるのに、プログラムの中から直接これらの機能を利用することもできます。
下記に UDP と TCP についての簡単な概略を述べます。詳しいことは man や
ネットワーク・プログラミングについての良書を読んでください。

<!-- <sect3>UDP Protocol (SOCK&lowbar;DGRAM) -->
<sect3>UDP プロトコル(SOCK&lowbar;DGRAM)
<p>

<!--
<bf>UDP</bf> is the User Datagram Protocol, but you more easily can
remember the properties of UDP as Unreliable Datagram Processing.  In
other words, UDP allows each block to be sent as an individual message,
but a message might be lost in transmission.  In fact, depending on
network traffic, UDP messages can be lost, can arrive multiple times
or can arrive in an order different from that in which they were
sent.  The sender of a UDP message does not automatically get an
acknowledgment, so it is up to user-written code to detect and
compensate for these problems.  Fortunately, UDP does ensure that if a
message arrives, the message contents are intact (i.e., you never get
just part of a UDP message).
-->
<bf>UDP</bf> は User Datagram Protocol の略称ですが、その特性をもっと
覚えやすくするために、Unreliable Datagram Processing(信頼性のないデータ
処理)としてもいいのではないでしょうか。つまり UDP は送信するブロックを
独立したメッセージとしていて、そのメッセージは伝送中に無くなるかも
しれないのです。事実、ネットワークの流量しだいでは UDP メッセージが無く
なったり、何回もやってきたり、送った順番とは違う順番できたりする可能性
があります。UDP メッセージの送り手は自動的にこの状況を知るすべはなく、
ユーザ自身が書いたコードで検知して、その問題に対処する必要があります。
幸いなことに、UDP はメッセージが到着していれば、その中身は壊れていない
ことを保証しています(言い替えれば、1 つの UDP メッセージの断片だけを
受け取るということはあり得ません)。

<!--
The nice thing about UDP is that it tends to be the fastest socket
protocol.  Further, UDP is "connectionless," which means that each
message is essentially independent of all others.  A good analogy is
that each message is like a letter to be mailed; you might send
multiple letters to the same address, but each one is independent of
the others and there is no limit on how many people you can send
letters to.
-->
UDP の良いところは、ソケットプロトコルの中では最速である場合が多いこと
です。その上 UDP は「コネクションレス」で、これは個々のメッセージが
他すべてのメッセージと独立していることを意味しています。例えると、
個々のメッセージは郵便に出した手紙と同じです。同じ住所にいくつも手紙を
出せますが、個々の手紙は他のものとは何の関係もありませんし、どのくらい
の人に出そうとも制限というものはありません。

<!-- <sect3>TCP Protocol (SOCK&lowbar;STREAM) -->
<sect3>TCP プロトコル(SOCK&lowbar;STREAM)
<p>

<!--
Unlike UDP, <bf>TCP</bf> is a reliable, connection-based, protocol.
Each block sent is not seen as a message, but as a block of data
within an apparently continuous stream of bytes being transmitted
through a connection between sender and receiver.  This is very
different from UDP messaging because each block is simply part of the
byte stream and it is up to the user code to figure-out how to extract
each block from the byte stream; there are no markings separating
messages.  Further, the connections are more fragile with respect to
network problems, and only a limited number of connections can exist
simultaneously for each process.  Because it is reliable, TCP
generally implies significantly more overhead than UDP.
-->
UDP とは違い、<bf>TCP</bf>は信頼性があるコネクションベースのプロトコル
です。
個々のブロック送信は、1 つのメッセージとは見なされず、送受信間の
コネクションを通して伝送される、一連のバイトストリームの中のデータブ
ロックとして扱われます。これが UDP メッセージと大きく違う点で、個々の
ブロックは単にバイトストリームの一部に過ぎず、ユーザ自身が書いたコード
によってそのバイトストリームからブロックを取り出す必要があります。
しかし、メッセージを分解するための印がない上に、コネクションはネットワーク
の障害に弱く、それぞれのプロセス当たりで同時にコネクションを張る数にも制限
があります。信頼性があるゆえに、TCP は UDP と比べてかなりオーバーヘッドが
大きくなる傾向があります。

<!--
There are, however, a few pleasant surprises about TCP.  One is that,
if multiple messages are sent through a connection, TCP is able to
pack them together in a buffer to better match network hardware packet
sizes, potentially yielding better-than-UDP performance for groups of
short or oddly-sized messages.  The other bonus is that networks
constructed using reliable direct physical links between machines can
easily and efficiently simulate TCP connections.  For example, this was
done for the ParaStation's "Socket Library" interface software, which
provides TCP semantics using user-level calls that differ from the
standard TCP OS calls only by the addition of the prefix
<tt>PSS</tt> to each function name.
-->
しかし、TCP には思わずうれしくなる機能がいくつかあります。1 つは、
複数のメッセージを 1 つのコネクションで送ったとすると、TCP はそれら
をひとまとめにしてバッファにおいた上で、ネットワーク機器のパケット
の大きさに調整できることです。メッセージが小さかったり、中途半端な
大きさの場合は、UDP よりもパフォーマンスが出るかもしれません。いい
ところは他にもあり、マシン間を物理的に直接接続することで信頼性のある
ネットワークを構築して、TCP コネクションをシミュレートしてしまう方法
です。例えば、ParaStation の「ソケット・ライブラリ」というインタフェース
のソフトウェアを使えば、実現できてしまいます。このソフトウェアは、
ユーザレベルで呼び出すことで TCP を使いこなせます。OS 標準の呼び出し
と違っている点は、<tt>PSS</tt> を呼び出すシステムコールそれぞれの前
につける点だけです。

<!-- <sect2>Device Drivers -->
<sect2>デバイス・ドライバ
<p>

<!--
When it comes to actually pushing data onto the network or pulling data
off the network, the standard unix software interface is a part of the
unix kernel called a device driver.  UDP and TCP don't just transport
data, they also imply a fair amount of overhead for socket management.
For example, something has to manage the fact that multiple TCP
connections can share a single physical network interface. In
contrast, a device driver for a dedicated network interface only needs
to implement a few simple data transport functions.  These device
driver functions can then be invoked by user programs by using
<tt>open()</tt> to identify the proper device and then using system
calls like <tt>read()</tt> and <tt>write()</tt> on the open "file."
Thus, each such operation could transport a block of data with little
more than the overhead of a system call, which might be as fast as
tens of microseconds.
-->
実際にデータをネットワークとやりとりする時に、標準的な UNIX のソフトウェア
のインタフェースとなるのは、UNIX のカーネルの一部であるデバイス・ドライバ
です。UDP や TCP はデータをただ伝送するのではなく、かなりのオーバーヘッドを
ともなうソケットの制御もしています。
例えば、複数の TCP コネクションは物理的に 1 つのネットワーク・インタフェース
を共有できるということは、何かがそれを処理しているからできるのです。それに
ひきかえ、あるネットワーク・インタフェース専用のデバイス・ドライバは、いくつ
かの単純なデータ伝送機能だけを必要とします。これらのデバイス・ドライバの機能
は、ユーザのプログラムから実行することが可能で、<tt>open()</tt> を使って
固有のデバイスを特定してから、オープンした「ファイル」に対して 
<tt>read()</tt> や <tt>write()</tt> のようなシステムコールを使います。
つまりそのような操作では、データブロックを伝送するのにほとんどシステム
コールによるオーバーヘッドが生じません。恐らく数十マイクロ秒程度で済み
ます。

<!--
Writing a device driver to be used with Linux is not hard...  if you
know <em>precisely</em> how the device hardware works.  If you are not
sure how it works, don't guess.  Debugging device drivers isn't fun
and mistakes can fry hardware.  However, if that hasn't scared you
off, it may be possible to write a device driver to, for example, use
dedicated Ethernet cards as dumb but fast direct machine-to-machine
connections without the usual Ethernet protocol overhead.  In fact,
that's pretty much what some early Intel supercomputers did....  Look
at the Device Driver HOWTO for more information.
-->
Linux で使えるデバイス・ドライバを書くのは大変なことではありません…。
そのデバイスのハードウェアがどのように動作するかを<em>正確に</em>知って
いるならですが…。どのように動作するのか確かでないなら、推測するのは
止めた方がいいでしょう。デバイス・ドライバのデバッグはつまらないだけでなく、
失敗するとハードウェアを壊してしまいます。しかしそれも気にならないなら、
デバイス・ドライバを書くことは可能です。例えば、機能は劣っているものの
通常のイーサネット・プロトコルのオーバヘッド無しにマシン間に直接コネクション
を張って高速に通信する専用のイーサネットカードを使うために。実際、初期の 
Intel の スーパーコンピュータのいくつかがそうでした…。詳しいことは、
Device Driver HOWTO を見てください。

<!-- <sect2>User-Level Libraries -->
<sect2>ユーザレベルのライブラリ
<p>

<!--
If you've taken an OS course, user-level access to hardware device
registers is exactly what you have been taught never to do, because
one of the primary purposes of an OS is to control device access.
However, an OS call is at least tens of microseconds of overhead.  For
custom network hardware like TTL&lowbar;PAPERS, which can perform a
basic network operation in just 3 microseconds, such OS call overhead
is intolerable.  The only way to avoid that overhead is to have
user-level code - a user-level library - directly access hardware
device registers.  Thus, the question becomes one of how a user-level
library can access hardware directly, yet not compromise the OS
control of device access rights.
-->
OS についての教育課程を受けたことがあるなら、ユーザレベルでハードウェア・
デバイスのレジスタに間違ってもアクセスしてはいけない、と教わったと思い
ます。デバイスへのアクセスを制御するのが OS の重要な役目の 1 つだからです。
しかし OS のシステムコールは少なくとも数 10 マイクロ秒のオーバーヘッドが
生じます。TTL&lowbar;PAPERS のような特殊なネットワーク機器のように、
基本的なネットワーク処理がわずか 3 マイクロ秒しかかからない場合には、
そのような OS のシステムコールのオーバーヘッドは許容の範囲を越えています。
オーバーヘッドを避ける唯一の手段は、ユーザレベルのコードとライブラリを
使って、ハードウェア・デバイスのレジスタに直接アクセスすることです。
つまり課題となるのは、どうしたらユーザレベルのライブラリがハードウェア
に直接アクセスできるかということであって、OS がデバイスのアクセス権を
制御することとどう調整しあうか、ということではありません。

<!--
On a typical system, the only way for a user-level library to directly
access hardware device registers is to:
-->
一般的なシステムで、ユーザレベルのライブラリで直接ハードウェアのレジスタ
をアクセスする唯一の方法は、

<enum>
<!--
<item>At user program start-up, use an OS call to map the page of
memory address space containing the device registers into the user
process virtual memory map.  For some systems, the <tt>mmap()</tt>
call (first mentioned in section 2.6) can be used to map a special
file which represents the physical memory page addresses of the I/O
devices.  Alternatively, it is relatively simple to write a device
driver to perform this function.  Further, this device driver can
control access by only mapping the page(s) containing the specific
device registers needed, thereby maintaining OS access control.

<item>Access device registers without an OS call by simply loading or
storing to the mapped addresses.  For example, <tt>*((char *) 0x1234) =
5;</tt> would store the byte value 5 into memory location 1234
(hexadecimal).
-->
<item>ユーザ・プログラムを動かす時に、OS のシステムコールを使って
メモリのアドレス空間のページに存在しているデバイスのレジスタを
ユーザプロセスの仮想メモリにマップすること。システムの中には、
<tt>mmap()</tt> システムコール(セクション 2.6 で説明済み)が、入出力
デバイスの物理メモリ上のページアドレスに相当するスペシャル・ファイル
にマップする手段として良く利用されている。別の手段として、デバイス・
ドライバを書いて、この機能を実現するのはそれ程難しくはない。さらに
このデバイス・ドライバは必要としている特定のデバイスのレジスタのページ
だけをマップしてアクセスを制御できるので、OS のアクセス制御はそのまま
にしておける

<item>マップしたアドレスに対して単純に読み書きすることで、OS のシステム
コールを使わずにデバイスのレジスタにアクセスすること。例えば、
<tt>*((char *) 0x1234) = 5;</tt> は 5 という値をメモリの 1234(16 進数)
に書き込むことになる
</enum>

<!--
Fortunately, it happens that Linux for the Intel 386 (and compatible
processors) offers an even better solution:
-->
幸いなことに、Intel の 386(とその互換プロセッサ)では、さらにうまい
解決方法があります。

<enum>
<!--
<item>Using the <tt>ioperm()</tt> OS call from a privileged process,
get permission to access the precise I/O port addresses that
correspond to the device registers.  Alternatively, permission can be
managed by an independent privileged user process (i.e., a "meta OS")
using the <url
url="http://garage.ecn.purdue.edu/~papers/giveioperm.html"
name="giveioperm() OS call"> patch for Linux.
-->
<item><tt>ioperm()</tt> という OS の システムコールを特権を持つプロセス
から呼び出すことで、デバイスのレジスタに対応している入出力アドレスへの
アクセス権を得られる。もう 1 つの方法として、独自の特権を持つユーザ
プロセス(すなわち「メタ OS」)で権限を管理する方法がある。Linux に <url 
url="http://garage.ecn.purdue.edu/~papers/giveioperm.html" 
name="giveioperm() システムコール"> パッチを当てて実現できる

<!--
<item>Access device registers without an OS call by using 386 port I/O
instructions.
-->
<item>OS のシステムコールを使わずに、386 の入出力ポート命令を使ってデバイス
のレジスタにアクセスすること
</enum>
<p>

<!--
This second solution is preferable because it is common that multiple
I/O devices have their registers within a single page, in which case
the first technique would not provide protection against accessing
other device registers that happened to reside in the same page as the
ones intended.  Of course, the down side is that 386 port I/O
instructions cannot be coded in C - instead, you will need to use a
bit of assembly code.  The GCC-wrapped (usable in C programs) inline
assembly code function for a port input of a byte value is:
-->
2 番目が優れた解決方法です。複数の入出力デバイスは複数のレジスタを 
1 つのページ内に置いているのが普通で、そうなると最初のテクニックでは、
他のデバイスのレジスタがたまたま目的のレジスタの同じページ内にあった
時に、そのアクセスから目的のレジスタを保護する手段を提供できないため
です。もちろん 386 のポート入出力命令にもマイナス面があります。それは 
C でコーディングできないために、かわりにわずかですがアセンブラを使う
必要があるかもしれないことです。下記に、あるポートに 1 バイトの値を
入力するために、GCC でラッパした(C プログラム内で利用可能)インラインの
アセンブラコードの関数をあげます。

<code>
extern inline unsigned char
inb(unsigned short port)
{
    unsigned char _v;
__asm__ __volatile__ ("inb %w1,%b0"
                      :"=a" (_v)
                      :"d" (port), "0" (0));
    return _v;
}
</code>

<!-- Similarly, the GCC-wrapped code for a byte port output is: -->
同様に、あるポートに 1 バイトの値を出力する GCC にくるんだコードを
下記にあげます。

<code>
extern inline void
outb(unsigned char value,
unsigned short port)
{
__asm__ __volatile__ ("outb %b0,%w1"
                      :/* no outputs */
                      :"a" (value), "d" (port));
}
</code>

<sect1>PVM (Parallel Virtual Machine)
<p>

<!--
PVM (Parallel Virtual Machine) is a freely-available, portable,
message-passing library generally implemented on top of sockets.  It
is clearly established as the de-facto standard for message-passing
cluster parallel computing.
-->
PVM(Parallel Virtual Machine)はフリーで利用ができ、移植性がある
メッセージ通信ライブラリで、大部分はソケットベースで実装してあります。
メッセージ通信タイプのクラスタ並列計算では、事実上の標準と言っても
過言ではありません。

<!--
PVM supports single-processor and SMP Linux machines, as well as
clusters of Linux machines linked by socket-capable networks (e.g.,
SLIP, PLIP, Ethernet, ATM).  In fact, PVM will even work across groups
of machines in which a variety of different types of processors,
configurations, and physical networks are used - <bf>Heterogeneous
Clusters</bf> - even to the scale of treating machines linked by the
Internet as a parallel cluster.  PVM also provides facilities for
parallel job control across a cluster.  Best of all, PVM has long been
freely available (currently from <url
url="http://www.epm.ornl.gov/pvm/pvm&lowbar;home.html">), which has
led to many programming language compilers, application libraries,
programming and debugging tools, etc., using it as their "portable
message-passing target library."  There is also a network newsgroup,
<htmlurl url="news:comp.parallel.pvm" name="comp.parallel.pvm">.
-->
PVM がサポートしているのは、プロセッサ が 1 つのマシンや SMP Linux マシン、
ソケットが利用可能なネットワーク(例えば SLIP、PLIP、イーサネット、ATM)に
接続している Linux マシンによるクラスタです。PVM は、プロセッサやシステム
構成、使用している物理的なネットワークが異なっている様々なマシン構成
(<bf>異機種クラスタ</bf>と言います)であっても実際に動作すると思われます。
またインターネット経由で接続し合ったマシンを 1 つのクラスタとして扱うほど
の規模でも動作すると思われます。また、PVM はクラスタ全体に渡って並列に実行
しているジョブを制御する機能も持っています。そして何よりも PVM は長い年月
に渡り何の制限も受けずに利用されており(現状は <url 
url="http://www.epm.ornl.gov/pvm/pvm&lowbar;home.html"> から)、結果として
数多くのプログラミング言語やコンパイラ、アプリケーション・ライブラリ、
そしてプログラミングやデバックのためのツール等ができました。そしてこれらの
成果物を「移植性のあるメッセージ通信を開発するためのライブラリ」として使用
しています。また news グループ(<htmlurl url="news:comp.parallel.pvm" 
name="comp.parallel.pvm">)も存在しています。

<!--
It is important to note, however, that PVM message-passing calls
generally add significant overhead to standard socket operations,
which already had high latency.  Further, the message handling calls
themselves do not constitute a particularly "friendly" programming
model.
-->
しかし注意が必要なのは、PVM のメッセージ通信を呼び出すと標準的なソケット
処理の遅延の大きさに加えて、さらにかなりのオーバーヘッドが加わってしまう
ことです。その上、メッセージを扱う呼び出しそのものがとりわけ「親しみやすい」
プログラミング・モデルではないことにも注意が必要です。

<!--
Using the same Pi computation example first described in section 1.3,
the version using C with PVM library calls is:
-->
最初にセクション 1.3 で登場した円周率の計算を例にして、PVM ライブラリを
呼び出す C を使ったバージョンは下記のようになります。

<code>
#include <stdlib.h>
#include <stdio.h>
#include <pvm3.h>

#define NPROC	4

main(int argc, char **argv)
{
  register double lsum, width;
  double sum;
  register int intervals, i; 
  int mytid, iproc, msgtag = 4;
  int tids[NPROC];  /* array of task ids */

  /* enroll in pvm */
  mytid = pvm_mytid();

  /* Join a group and, if I am the first instance,
     iproc=0, spawn more copies of myself
  */
  iproc = pvm_joingroup("pi");

  if (iproc == 0) {
    tids[0] = pvm_mytid();
    pvm_spawn("pvm_pi", &amp;argv[1], 0, NULL, NPROC-1, &ero;tids[1]);
  }
  /* make sure all processes are here */
  pvm_barrier("pi", NPROC);

  /* get the number of intervals */
  intervals = atoi(argv[1]);
  width = 1.0 / intervals;

  lsum = 0.0;
  for (i = iproc; i<intervals; i+=NPROC) {
    register double x = (i + 0.5) * width;
    lsum += 4.0 / (1.0 + x * x);
  }
  
  /* sum across the local results & scale by width */
  sum = lsum * width;
  pvm_reduce(PvmSum, &amp;sum, 1, PVM_DOUBLE, msgtag, "pi", 0);

  /* have only the console PE print the result */
  if (iproc == 0) {
    printf("Estimation of pi is %f\n", sum);
  }

  /* Check program finished, leave group, exit pvm */
  pvm_barrier("pi", NPROC);
  pvm_lvgroup("pi");
  pvm_exit();
  return(0);
}
</code>

<sect1>MPI (Message Passing Interface)
<p>

<!--
Although PVM is the de-facto standard message-passing library, MPI
(Message Passing Interface) is the relatively new official standard.
The home page for the MPI standard is <url
url="http://www.mcs.anl.gov:80/mpi/"> and the newsgroup is <htmlurl
url="news:comp.parallel.mpi" name="comp.parallel.mpi">.
-->
PVM はメッセージ通信ライブラリの事実上の標準となっていますが、MPI
(Message Passing Interface)は PVM と比べると新しい公式の規格です。
MPI 規格のホーム・ページは <url url="http://www.mcs.anl.gov:80/mpi/"> 
で、news グループは <htmlurl url="news:comp.parallel.mpi" 
name="comp.parallel.mpi"> です。

<!--
However, before discussing MPI, I feel compelled to say a little bit
about the PVM vs. MPI religious war that has been going on for the
past few years.  I'm not really on either side.  Here's my attempt at
a relatively unbiased summary of the differences:
-->
ここで MPI について議論する前に、過去数年に渡って続いた PVM 対 MPI の
宗教戦争について触れざるを得ないと思います。私はどちらにも組みして
いません。ここではその相違点を偏見にとらわれることなくまとめてみます。

<descrip>
<!--
<tag>Execution control environment.</tag> Put simply, PVM has one and
MPI doesn't specify how/if one is implemented.  Thus, things like
starting a PVM program executing are done identically everywhere, while
for MPI it depends on which implementation is being used.
-->
<tag/プロセス実行を制御する環境。/ 一言でいうと PVM は持っているが、MPI は
実装とそのやり方をきちんと仕様化していない。つまり、PVM のプログラムはどこ
でも同じ様に実行できるが、MPI は実装によってその動作が変わってしまう

<!--
<tag>Support for heterogeneous clusters.</tag> PVM grew-up in the
workstation cycle-scavenging world, and thus directly manages
heterogeneous mixes of machines and operating systems.  In contrast,
MPI largely assumes that the target is an MPP (Massively Parallel
Processor) or a dedicated cluster of nearly identical workstations.
-->
<tag/異機種クラスタのサポート。/ PVM はワークステーションが空いている
時間を集めて処理するという観点で進化してきたので、いろいろな種類のマシン
やオペレーティング・システムが混じった環境をじかに管理できる。これとは
対照的に、MPI は主としてターゲットを MPP(Massively Parallel Processor)
もしくは、クラスタ専用に使われる同じ種類のワークステーションに当てている

<!--
<tag>Kitchen sink syndrome.</tag> PVM evidences a unity of purpose that
MPI 2.0 doesn't.  The new MPI 2.0 standard includes a lot of features
that go way beyond the basic message passing model - things like RMA
(Remote Memory Access) and parallel file I/O.  Are these things
useful?  Of course they are...  but learning MPI 2.0 is a lot like
learning a complete new programming language.
-->
<tag/何でもかんでも症候群。/ PVM は目的に対して一貫している。これが 
MPI 2.0 には欠けている。MPI 2.0 の新しい規格は、多くの機能を盛り込んで
おり、基本的なメッセージ通信モデルをはるかに越えてしまっている。
例えば RMA(Remote Memory Access)や並列ファイル入出力などがそれに当たる。
本当に役に立つのだろうか？ もちろんそれらは…しかし MPI 2.0 は、新しい
プログラミング言語を完璧に習得するぐらい学習が必要になる

<!--
<tag>User interface design.</tag> MPI was designed after PVM, and
clearly learned from it.  MPI offers simpler, more efficient, buffer
handling and higher-level abstractions allowing user-defined data
structures to be transmitted in messages.
-->
<tag/ユーザ・インタフェースの設計。/ MPI の設計は PVM より新しく、
PVM の設計を確かに参考にしている。MPI はシンプルかつ効率的なバッファ
機能があり、その高度の抽象化によってユーザが定義したデータ構造を
メッセージに入れて伝送できる

<!--
<tag>The force of law.</tag> By my count, there are still
significantly more things designed to use PVM than there are to use
MPI; however, porting them to MPI is easy, and the fact that MPI is
backed by a widely-supported formal standard means that using MPI is,
for many institutions, a matter of policy.
-->
<tag/おきての影響力。/私が見るところでは、MPI と比べるとまだ PVM の方が
いろいろと考え抜いている点が多い。しかし PVM から MPI に移植することが
簡単であること、MPI が公式な標準として広く支持されていることから、公共
機関にとっては MPI を使用すること自体がポリシそのものになっている
</descrip>

<!--
Conclusion?  Well, there are at least three independently developed,
freely available, versions of MPI that can run on clusters of Linux
systems (and I wrote one of them):
-->
結論は？ という問いに対しては、フリーで使える MPI が 3 つ独立して開発
されていて、Linux のクラスタが動きます、と答えておきます。
(その中の 1 つは私が作りました)

<itemize>
<!--
<item>LAM (Local Area Multicomputer) is a full implementation of the
MPI 1.1 standard.  It allows MPI programs to be executed within an
individual Linux system or across a cluster of Linux systems using
UDP/TCP socket communication.  The system includes simple execution
control facilities, as well as a variety of program development and
debugging aids.  It is freely available from <url
url="http://www.osc.edu/lam.html">.
-->
<item>LAM(Local Area Multicomputer)は MPI 1.1 規格に完全に準拠して
	いる。MPI プログラムが、スタンドアローンの Linux システム や UDP 
	や TCP ベースのソケット通信を使った Linux システムで構築した
	クラスタ上で動作する。システムには様々なプログラム開発やデバック
	を支援するツールとともに、
	<!--
	簡単な実行制御機能がある。<url url="http://www.osc.edu/lam.html"> から
	-->
	簡単な実行制御機能がある。<url url="http://www.mpi.nd.edu/lam/"> 
	からフリーで利用可能

<!--
<item>MPICH (MPI CHameleon) is designed as a highly portable full
implementation of the MPI 1.1 standard.  Like LAM, it allows MPI
programs to be executed within an individual Linux system or across a
cluster of Linux systems using UDP/TCP socket communication.  However,
the emphasis is definitely on promoting MPI by providing an efficient,
easily retargetable, implementation.  To port this MPI implementation,
one implements either the five functions of the "channel interface"
or, for better performance, the full MPICH ADI (Abstract Device
Interface).  MPICH, and lots of information about it and porting, are
available from <url url="http://www.mcs.anl.gov/mpi/mpich/">.
-->
<item>MPICH(MPI CHameleon)は MPI 1.1 規格に完全に準拠していて、移植性
	を考慮して設計してある。LAM と同様に、MPI プログラムがスタンド
	アローンの Linux システム や UDP や TCP ベースのソケット通信を使った 
	Linux システムで構築したクラスタ上で動作する。しかし MPI が効率的
	かつ目的に対して柔軟に対応することに重点をおいているのは間違いない。
	この MPI の実装を移植するには、「チャネル・インタフェース」の 5 つ
	の関数とパフォーマンス向上のために MPICH ADI(Abstract Device 
	Interface)を実装することになる。
	MPICH についてのさらに詳しい情報とその移植方法については、
	<url url="http://www.mcs.anl.gov/mpi/mpich/"> で知ることができる

<!--
<item>AFMPI (Aggregate Function MPI) is a subset implementation of the
MPI 2.0 standard.  This is the one that I wrote.  Built on top of the
AFAPI, it is designed to showcase low-latency collective communication
functions and RMAs, and thus provides only minimal support for MPI
data types, communicators, etc.  It allows C programs using MPI to run
on an individual Linux system or across a cluster connected by
AFAPI-capable network hardware.  It is freely available from <url
url="http://garage.ecn.purdue.edu/~papers/">.
-->
<item>AFMPI(Aggregate Function MPI)は MPI 2.0 規格のサブセットで、私が
	作成した。AFAPI をベースに構築してあり、遅延の少ない集合通信と RMA 
	の見本となるように設計した。したがって MPI のデータタイプや通信手段
	等は最低限のものしか提供していない。スタンドアロンの Linux システムと 
	AFPI が利用できるネットワーク機器で接続しているクラスタにおいて、MPI 
	を使った C プログラムが動作する。
	<url url="http://garage.ecn.purdue.edu/~papers/"> からフリーで利用可能
</itemize>

<!--
No matter which of these (or other) MPI implementations one uses, it
is fairly simple to perform the most common types of communications.
-->
これら MPI の実装(その他も)のどれを利用しても、通常使うタイプの通信
はかなり簡単に実行できます。

<!--
However, MPI 2.0 incorporates several communication paradigms that are
fundamentally different enough so that a programmer using one of them
might not even recognize the other coding styles as MPI.  Thus, rather
than giving a single example program, it is useful to have an example
of each of the fundamentally different communication paradigms that
MPI supports.  All three programs implement the same basic algorithm
(from section 1.3) that is used throughout this HOWTO to compute the
value of Pi.
-->
しかし MPI 2.0 には通信パラダイムが複数あり、それが根本的に違ったものに
なっているため、プログラマーがあるパラダイムを使用しても MPI の他の
コーディングでは利用でいない場合があります。したがって 1 つのプログラム
例をあげるよりも、MPI がサポートしている根本的に異なっている通信パラダイム
それぞれについて例をあげる方が役立つでしょう。3 つのプログラムすべては、
この HOWTO を通じて使用してきた円周率の計算をする基本的なアルゴリズム
(セクション 1.3 より)で実装してあります。

<!--
The first MPI program uses basic MPI message-passing calls for each
processor to send its partial sum to processor 0, which sums and
prints the result:
-->
最初の MPI のプログラムは、基本的な MPI のメッセージ通信呼び出しを
使用して、それぞれのプロセッサが小計を 0 番のプロセッサに送って、
そのプロセッサが合計して結果を出力します。

<code>
#include <stdlib.h>
#include <stdio.h>
#include <mpi.h>

main(int argc, char **argv)
{
  register double width;
  double sum, lsum;
  register int intervals, i; 
  int nproc, iproc;
  MPI_Status status;

  if (MPI_Init(&ero;argc, &ero;argv) != MPI_SUCCESS) exit(1);
  MPI_Comm_size(MPI_COMM_WORLD, &ero;nproc);
  MPI_Comm_rank(MPI_COMM_WORLD, &ero;iproc);
  intervals = atoi(argv[1]);
  width = 1.0 / intervals;
  lsum = 0;
  for (i=iproc; i&lt;intervals; i+=nproc) {
    register double x = (i + 0.5) * width;
    lsum += 4.0 / (1.0 + x * x);
  }
  lsum *= width;
  if (iproc != 0) {
    MPI_Send(&ero;lbuf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);
  } else {
    sum = lsum;
    for (i=1; i<nproc; ++i) {
      MPI_Recv(&ero;lbuf, 1, MPI_DOUBLE, MPI_ANY_SOURCE,
               MPI_ANY_TAG, MPI_COMM_WORLD, &ero;status);
      sum += lsum;
    }
    printf("Estimation of pi is %f\n", sum);
  }
  MPI_Finalize();
  return(0);
}
</code>

<!--
The second MPI version uses collective communication (which, for this
particular application, is clearly the most appropriate):
-->
二番目の MPI のバージョンは、集合通信(この特定用途に対して最適解)を
使っています。

<code>
#include <stdlib.h>
#include <stdio.h>
#include <mpi.h>

main(int argc, char **argv)
{
  register double width;
  double sum, lsum;
  register int intervals, i; 
  int nproc, iproc;

  if (MPI_Init(&ero;argc, &ero;argv) != MPI_SUCCESS) exit(1);
  MPI_Comm_size(MPI_COMM_WORLD, &ero;nproc);
  MPI_Comm_rank(MPI_COMM_WORLD, &ero;iproc);
  intervals = atoi(argv[1]);
  width = 1.0 / intervals;
  lsum = 0;
  for (i=iproc; i<intervals; i+=nproc) {
    register double x = (i + 0.5) * width;
    lsum += 4.0 / (1.0 + x * x);
  }
  lsum *= width;
  MPI_Reduce(&ero;lsum, &ero;sum, 1, MPI_DOUBLE,
             MPI_SUM, 0, MPI_COMM_WORLD);
  if (iproc == 0) {
    printf("Estimation of pi is %f\n", sum);
  }
  MPI_Finalize();
  return(0);
}
</code>

<!--
The third MPI version uses the MPI 2.0 RMA mechanism for each processor
to add its local <tt>lsum</tt> into <tt>sum</tt> on processor 0:
-->
三番目の MPI のバージョンは、MPI 2.0 の RMA の機能を使って、それぞれの
プロセッサがローカルの <tt>lsum</tt> を 0 番のプロセッサの <tt>sum</tt> 
に加算します。

<code>
#include <stdlib.h>
#include <stdio.h>
#include <mpi.h>

main(int argc, char **argv)
{
  register double width;
  double sum = 0, lsum;
  register int intervals, i; 
  int nproc, iproc;
  MPI_Win sum_win;

  if (MPI_Init(&ero;argc, &ero;argv) != MPI_SUCCESS) exit(1);
  MPI_Comm_size(MPI_COMM_WORLD, &ero;nproc);
  MPI_Comm_rank(MPI_COMM_WORLD, &ero;iproc);
  MPI_Win_create(&ero;sum, sizeof(sum), sizeof(sum),
                 0, MPI_COMM_WORLD, &ero;sum_win);
  MPI_Win_fence(0, sum_win);
  intervals = atoi(argv[1]);
  width = 1.0 / intervals;
  lsum = 0;
  for (i=iproc; i<intervals; i+=nproc) {
    register double x = (i + 0.5) * width;
    lsum += 4.0 / (1.0 + x * x);
  }
  lsum *= width;
  MPI_Accumulate(&ero;lsum, 1, MPI_DOUBLE, 0, 0,
                 1, MPI_DOUBLE, MPI_SUM, sum_win);
  MPI_Win_fence(0, sum_win);
  if (iproc == 0) {
    printf("Estimation of pi is %f\n", sum);
  }
  MPI_Finalize();
  return(0);
}
</code>

<!--
It is useful to note that the MPI 2.0 RMA mechanism very neatly
overcomes any potential problems with the corresponding data structure
on various processors residing at different memory locations.  This is
done by referencing a "window" that implies the base address,
protection against out-of-bound accesses, and even address scaling.
Efficient implementation is aided by the fact that RMA processing may
be delayed until the next <tt>MPI&lowbar;Win&lowbar;fence</tt>.  In
summary, the RMA mechanism may be a strange cross between distributed
shared memory and message passing, but it is a very clean interface
that potentially generates very efficient communication.
-->
MPI 2.0 に含まれる RMA のしくみが、様々なプロセッサ上の異なるメモリに
存在する同期を必要とするデータ構造を扱う上で、問題となりそうなところを
巧妙に屈伏している点は覚えておいても損はありません。これは、「window」
を基準とすることで解決しています。window には、ベースアドレスや領域外
へのアクセス防止に加えて、利用アドレス領域の変更を行う機能まで含んで
います。RMA が効率的なのは、次の <tt>MPI&lowbar;Win&lowbar;fence</tt> 
を呼び出すまで実際には命令が実行されない点にあります。要約すると、RMA 
のしくみは、分散共有メモリとメッセージ通信を巧妙に組み合わせたものです
が、インタフェースがとても明快で非常に効率的に通信ができる可能性を
秘めています。

<sect1>AFAPI (Aggregate Function API)
<p>

<!--
Unlike PVM, MPI, etc., the AFAPI (Aggregate Function Application
Program Interface) did not start life as an attempt to build a
portable abstract interface layered on top of existing network
hardware and software.  Rather, AFAPI began as the very
hardware-specific low-level support library for PAPERS (Purdue's
Adapter for Parallel Execution and Rapid Synchronization; see <url
url="http://garage.ecn.purdue.edu/~papers/">).
-->
AFAPI(Aggregate Function Application Program Interface)は PVM や MPI 
他とは違い、そもそも移植性のある抽象的なインタフェースを既存のネット
ワーク機器やソフトウェア上に構築しようとして世に出したわけではありま
せん。AFAPI はむしろハードウェアにとても依存した低レベルなライブラリ
で、PAPERS(Purdue's Adapter for Parallel Execution and Rapid 
Synchronization <url 
url="http://garage.ecn.purdue.edu/~papers/"> 参照)用です。

<!--
PAPERS was discussed briefly in section 3.2; it is a public domain
design custom aggregate function network that delivers latencies as
low as a few microseconds.  However, the important thing about PAPERS
is that it was developed as an attempt to build a supercomputer that
would be a better target for compiler technology than existing
supercomputers.  This is qualitatively different from most Linux
cluster efforts and PVM/MPI, which generally focus on trying to use
standard networks for the relatively few sufficiently coarse-grain
parallel applications.  The fact that Linux PCs are used as components
of PAPERS systems is simply an artifact of implementing prototypes in
the most cost-effective way possible.
-->
PAPERS についてはセクション 3.2 で簡単に述べましたが、パブリック・
ドメインで設計したネットワークで、独自の集合演算を実現し、遅延はわずか
数ミリ秒程度で済んでしまいます。しかし PAPERS で重要なのはこの点では
なく、1 つのスーパーコンピュータを作り上げる目的で開発が行われた点に
あります。これは既存のスーパーコンピュータを対象にするというよりも、
コンパイラ技術を生かす相手としてスーパーコンピュータを対象としました。
これは Linux クラスタの大部分がとった試みや、PVM、MPI のように標準的な
ネットワークを使って比較的粒度が粗い並列アプリケーションを利用すること
に焦点を当てたものとは質的に異なっています。Linux PC を PAPERS システム
の構成要素として採用したのは、最も費用対効果が高くとれる方法でプロト
タイプを実装した結果に過ぎません。

<!--
The need for a common low-level software interface across more than a
dozen different prototype implementations was what made the PAPERS
library become standardized as AFAPI.  However, the model used by
AFAPI is inherently simpler and better suited for the finer-grain
interactions typical of code compiled by parallelizing compilers or
written for SIMD architectures.  The simplicity of the model not only
makes PAPERS hardware easy to build, but also yields surprisingly
efficient AFAPI ports for a variety of other hardware systems, such as
SMPs.
-->
様々に異なるプロトタイプの実装に対して、共通に使える低レベルなソフト
ウェアが必要とされたことから、PAPERS ライブラリで作成したものが AFAPI 
の標準とされました。しかし AFAPI で使用しているモデルはそもそもシンプル
で、並列化コンパイラでコンパイルしたものや SIMD アーキテクチャ用に作成
した、粒度が細かい処理一般に適しています。モデルがシンプルなことで、
PAPERS のハードウェアを容易に構築できるだけでなく、SMP 等の他の様々な
ハードウェアへの AFAPI の移植も、思いのほか効率的に行えます。

<!--
AFAPI currently runs on Linux clusters connected using TTL_PAPERS,
CAPERS, or WAPERS.  It also runs (without OS calls or even bus-lock
instructions, see section 2.2) on SMP systems using a System V Shared
Memory library called SHMAPERS.  A version that runs across Linux
clusters using UDP broadcasts on conventional networks (e.g.,
Ethernet) is under development.  All released versions are available
from <url url="http://garage.ecn.purdue.edu/~papers/">.  All versions
of the AFAPI are designed to be called from C or C++.
-->
現状、AFAPI は TTL_PAPERS や CAPERS、WAPERS で接続している Linux クラスタ
上で動作しています。また SHMAPERS という System V の共有メモリライブラリ
を使って、SMP システムでも同様に動作しています(OS のシステムコールを使用
しないばかりか、バスをロックする命令すら使わずに。セクション 2.2 を参照)。
Linux クラスタ上で UDP のブロードキャストを使って普通のネットワーク
(例えばイーサネット)上で動くバージョンは開発中です。リリースしたすべての
バージョンは、<url url="http://garage.ecn.purdue.edu/~papers/"> から
取ってこられます。AFAPI のすべてのバージョンは、C や C++ から呼び出すよう
に設計してあります。

<!--
The following example program is the AFAPI version of the Pi
computation described in section 1.3.
-->
次のプログラム例は、セクション 1.3 であげた、円周率計算の AFAPI 
バージョンです。

<code>
#include <stdlib.h>
#include <stdio.h>
#include "afapi.h"

main(int argc, char **argv)
{
  register double width, sum;
  register int intervals, i;

  if (p_init()) exit(1);

  intervals = atoi(argv[1]);
  width = 1.0 / intervals;

  sum = 0;
  for (i=IPROC; i<intervals; i+=NPROC) {
    register double x = (i + 0.5) * width;
    sum += 4.0 / (1.0 + x * x);
  }

  sum = p_reduceAdd64f(sum) * width;

  if (IPROC == CPROC) {
    printf("Estimation of pi is %f\n", sum);
  }

  p_exit();
  return(0);
}
</code>

<!-- <sect1>Other Cluster Support Libraries -->
<sect1>クラスタをサポートしているその他のライブラリ
<p>

<!--
In addition to PVM, MPI, and AFAPI, the following libraries offer
features that may be useful in parallel computing using a cluster of
Linux systems.  These systems are given a lighter treatment in this
document simply because, unlike PVM, MPI, and AFAPI, I have little or
no direct experience with the use of these systems on Linux clusters.
If you find any of these or other libraries to be especially useful,
please send email to me at <htmlurl url="mailto:pplinux@ecn.purdue.edu"
name="pplinux@ecn.purdue.edu"> describing what you've found, and I will
consider adding an expanded section on that library.
-->
PVM や MPI、AFAPI に加えて、下記のライブラリが提供する機能が Linux 
システムで構築したクラスタで並列処理を行うのに役立つかもしれません。
このドキュメントではこれらのシステムについては簡単に触れるだけに留めます。
理由は簡単で、PVM や MPI、AFAPI と違い、私がほとんどまったくと言っていい
ほどこれらのシステムを Linux クラスタ上でじかに扱ったことがないからです。
これらのライブラリやその他ライブラリの中で、これは有効だ、と思われるもの
があったなら、どうか私に電子メールを送ってください。何を発見したかを書いて
いただき、pplinux@ecn.purdue.edu 宛までお願いします。検討した上、その
ライブラリをこのセクションの補遺として追加するつもりです。

<!-- <sect2>Condor (process migration support) -->
<sect2>Condor(プロセス・マイグレーションをサポート)
<p>

<!--
Condor is a distributed resource management system that can manage
large heterogeneous clusters of workstations.  Its design has been
motivated by the needs of users who would like to use the unutilized
capacity of such clusters for their long-running,
computation-intensive jobs.  Condor preserves a large measure of the
originating machine's environment on the execution machine, even if
the originating and execution machines do not share a common file
system and/or password mechanisms.  Condor jobs that consist of a
single process are automatically checkpointed and migrated between
workstations as needed to ensure eventual completion.
-->
Condor は分散しているリソースの管理を行うシステムで、ワークステーション
で構成してある大規模な異機種クラスタを管理できます。計算を中心に長い時間
を必要とするの処理を行いたいユーザが、クラスタの余っている能力を利用したい、
という要求に答えるべく設計を行ってきました。Condor はプロセスを実際に
実行するマシン上に元々実行していたマシンの環境を広範囲に保持しています。
たとえ元のマシンと実際に実行するマシンが共通のファイル・システムやパス
ワードのしくみを共通に持っていなくてもです。最終的にジョブの終了を保証
する必要があるので、1 つのプロセスからなる Condor のジョブは自動的に
チェックポイントされ、ワークステーション間でマイグレーションします。
<p>
【訳註：「プロセス・マイグレーション」とは、あるマシンで実行して
いるプロセスを他のマシンに引き継いで、引き続き実行することです。
「チェックポイント」とは、現在のプロセスやデータの状態を後で利用するために
記録しておくことをです】

<!--
Condor is available at <url url="http://www.cs.wisc.edu/condor/">.  A
Linux port exists; more information is available at <url
url="http://www.cs.wisc.edu/condor/linux/linux.html">.  Contact
<htmlurl url="mailto:condor-admin@cs.wisc.edu"
name="condor-admin@cs.wisc.edu"> for details.
-->
Condor は <url url="http://www.cs.wisc.edu/condor/"> から利用できます。
Linux への移植もあります。さらに詳しい情報は <url 
url="http://www.cs.wisc.edu/condor/linux/linux.html">
【訳註：リンク切れ】にあります。詳細は、condor-admin@cs.wisc.edu 
に連絡を取ってください。

<sect2>DFN-RPC (German Research Network - Remote Procedure Call)
<p>

<!--
The DFN-RPC, a (German Research Network Remote Procedure Call) tool,
was developed to distribute and parallelize scientific-technical
application programs between a workstation and a compute server or a
cluster. The interface is optimized for applications written in
fortran, but the DFN-RPC can also be used in a C environment.  It has
been ported to Linux.  More information is at <url
url="ftp://ftp.uni-stuttgart.de/pub/rus/dfn&lowbar;rpc/README&lowbar;dfnrpc.html">.
-->
DFN-RPC(German Research Network Remote Procedure Call)は、科学技術
アプリケーション・プログラムで、ワークステーションと計算サーバ
もしくはクラスタ間で分散、並列処理を行う目的で開発されました。
インタフェースは、Fortran で書いたアプリケーションに最適化していますが、
DFN-RPC は C の開発環境でも利用できます。Linux にも移植されています。
さらに詳細な情報は、<url 
url="ftp://ftp.uni-stuttgart.de/pub/rus/dfn&lowbar;rpc/README&lowbar;dfnrpc.html"> にあります。

<sect2>DQS (Distributed Queueing System)
<p>

<!--
Not exactly a library, DQS 3.0 (Distributed Queueing System) is a job
queueing system that has been developed and tested under Linux.  It is
designed to allow both use and administration of a heterogeneous
cluster as a single entity.  It is available from <url
url="http://www.scri.fsu.edu/~pasko/dqs.html">.
-->
正確にはライブラリではないのですが、DQS 3.0(Distributed Queueing System)
はジョブをキューイングするシステムです。Linux 上で開発、テストされて
います。異機種クラスタを単一のシステムとして利用、管理できるように
設計されています。<url url="http://www.scri.fsu.edu/~pasko/dqs.html"> 
から利用できます。

<!--
There is also a commercial version called CODINE 4.1.1 (COmputing in
DIstributed Network Environments).  Information on it is available
from <url url="http://www.genias.de/genias&lowbar;welcome.html">.
-->
商用版もあり、CODINE 4.1.1(COmputing in DIstributed Network Environments)
といいます。<url url="http://www.genias.de/genias&lowbar;welcome.html"> 
に情報があります。

<!-- <sect1>General Cluster References -->
<sect1>利用可能なクラスタの一覧
<p>

<!--
Because clusters can be constructed and used in so many different ways,
there are quite a few groups that have made interesting contributions.
The following are references to various cluster-related projects that
may be of general interest.  This includes a mix of Linux-specific and
generic cluster references.  The list is given in alphabetical order.
-->
クラスタはいろいろと異なる方法で構築、運用できるので、クラスタの開発に
貢献する興味深い活動を行っているグループがかなりあります。
下記の一覧で、クラスタ関連のプロジェクトの中で皆さんが興味を持たれるで
あろうと思われるものをあげておきます。これには、Linux 固有のもの、
クラスタ一般のものが両方含まれています。リストはアルファベット順です。

<sect2>Beowulf
<p>

<!--
The Beowulf project, <url
url="http://cesdis1.gsfc.nasa.gov/beowulf/">, centers on production of
software for using off-the-shelf clustered workstations based on
commodity PC-class hardware, a high-bandwidth cluster-internal
network, and the Linux operating system.
-->
Beowulf プロジェクト(<url url="http://www.beowulf.org/">)
は、市販されている PC レベルのハードウェアと広い帯域幅を持つクラスタ
組み込みのネットワーク、そして Linux オペーレーティング・システムを
ベースにしています。そのような市販のワークステーションを使ってクラスタ
を組むためのソフトウェアを作成することにターゲットを当てています。

<!--
Thomas Sterling has been the driving force behind Beowulf, and
continues to be an eloquent and outspoken proponent of Linux
clustering for scientific computing in general. In fact, many groups
now refer to their clusters as "Beowulf class" systems - even if the
cluster isn't really all that similar to the official Beowulf design.
-->
Thomas Sterling 氏が Beowulf を推進していて、科学計算一般についての 
Linux クラスタリングについての、雄弁かつ率直な擁護者でもあります。実際
に多くのグループが自分たちのクラスタを「Beowulf クラスの」システムと
呼んでいます。本当はそのクラスタが公式の Beowulf の設計にそれほど似て
いないにもかかわらず。

<!--
Don Becker, working in support of the Beowulf project, has produced
many of the network drivers used by Linux in general.  Many of these
drivers have even been adapted for use in BSD.  Don also is
responsible for many of these Linux network drivers allowing
load-sharing across multiple parallel connections to achieve higher
bandwidth without expensive switched hubs.  This type of load sharing
was the original distinguishing feature of the Beowulf cluster.
-->
Don Becker 氏は Beowulf プロジェクトのサポートをしていて、一般的な Linux 
で利用可能なネットワーク・ドライバも数多く作成しています。そのドライバ
の多くは BSD でも利用されています。彼はこれらのネットワーク・ドライバ
の多くが複数の並列接続を負荷分散し、広い帯域幅を高価なスイッチング・
ハブ無しに実現することに対しても責任を負っています。このタイプの負荷
分散は、元々 Beowulf クラスタに独自のしくみでした。

<sect2>Linux/AP+
<p>

<!--
The Linux/AP+ project, <url
url="http://cap.anu.edu.au/cap/projects/linux/">, is not exactly about
Linux clustering, but centers on porting Linux to the Fujitsu AP1000+
and adding appropriate parallel processing enhancements.  The AP1000+
is a commercially available SPARC-based parallel machine that uses a
custom network with a torus topology, 25 MB/s bandwidth, and 10
microsecond latency...  in short, it looks a lot like a SPARC Linux
cluster.
-->
Linux/AP+ プロジェクト(<url 
url="http://cap.anu.edu.au/cap/projects/linux/">)は、正しくは Linux 
のクラスタリングではありませんが、Linux を富士通の AP1000+ に移植して、
マシンに見合った並列処理機能の拡張を目指しています。AP1000+ は市販の 
SPARC ベースの並列マシンで、トーラス構造の特殊なネットワークを持ち、
帯域幅が 25 MB/秒、遅延が 10 ミリ秒…つまり SPARC ベースの Linux 
クラスタにそっくりです。
<p>
【訳註：トーラス構造をしたスーパーコンピュータのイメージは 
<url 
url="http://www.research.ibm.com/bluegene/original_pictures.html"
 name="IBM Bluegene"> を見てください】
<!--
-->
<sect2>Locust
<p>

<!--
The Locust project, <url
url="http://www.ecsl.cs.sunysb.edu/~manish/locust/">, is building a
distributed virtual shared memory system that uses compile-time
information to hide message-latency and to reduce network traffic at
run time.  Pupa is the underlying communication subsystem of Locust,
and is implemented using Ethernet to connect 486 PCs under FreeBSD.
Linux?
-->
Locust プロジェクト(<url 
url="http://www.ecsl.cs.sunysb.edu/~manish/locust/">)【訳註：リンク切れ】
は、分散仮想共有メモリシステムを構築しています。コンパイル時に決定する
情報を使用して、メッセージの遅延を顕在化させずに実行時のネットワークの
流量を減らしています。Pupa が Locust の基本通信サブシステムで、イーサネット
を使って FreeBSD が動作している 486 PC を接続しています。Linux はわかりません。

<!-- <sect2>Midway DSM (Distributed Shared Memory) -->
<sect2>Midway DSM(分散共有メモリ)
<p>

<!--
Midway, <url
url="http://www.cs.cmu.edu/afs/cs.cmu.edu/project/midway/WWW/HomePage.html">,
is a software-based DSM (Distributed Shared Memory) system, not unlike
TreadMarks.  The good news is that it uses compile-time aids rather
than relatively slow page-fault mechanisms, and it is free.  The bad
news is that it doesn't run on Linux clusters.
-->
Midway(<url 
url="http://www.cs.cmu.edu/afs/cs.cmu.edu/project/midway/WWW/HomePage.html">)
は、TreadMarks(後述)とは違い、ソフトウェアベースの DSM(分散共有メモリ)
システムです。ページ・フォルトのように遅いしくみではなく、コンパイル時の
情報を利用していたり、フリーに利用できる点が良いのですが、残念ながら Linux 
クラスタでは動きません。

<sect2>Mosix
<p>

<!--
MOSIX modifies the BSDI BSD/OS to provide dynamic load balancing and
preemptive process migration across a networked group of PCs.  This is
nice stuff not just for parallel processing, but for generally using a
cluster much like a scalable SMP.  Will there be a Linux version?  Look
at <url url="http://www.cs.huji.ac.il/mosix/"> for more information.
-->
MOSIX は BSDI の BSD/OS に手を入れて、動的なロード・バランシングと
ネットワーク上でグループを組んでいる PC 間でプリエンプティブにプロセス・
マイグレーションができるようにしています。これは並列処理にうってつけと
いうわけではありませんが、拡張性がある SMP のようなクラスタで利用する
のに適しています。Linux バージョンは出るのか？ という問にたいする答は、
<url url="http://www.cs.huji.ac.il/mosix/"> にあります。

<sect2>NOW (Network Of Workstations)
<p>

<!--
The Berkeley NOW (Network Of Workstations) project, <url
url="http://now.cs.berkeley.edu/">, has led much of the push toward
parallel computing using networks of workstations.  There is a lot
work going on here, all aimed toward "demonstrating a practical 100
processor system in the next few years."  Alas, they don't use Linux.
-->
Berkeley の NOW(Network Of Workstations)プロジェクト(<url 
url="http://now.cs.berkeley.edu/">)は、ネットワークに接続している
ワークステーションを使って、並列計算を行う流れを生み出しました。
数多くの研究が継続しており、「100 個のプロセッサを載せた実用的なシステムを
ここ数年で実証する」ことに目標を定めています。悲しいことに Linux は
使っていません。

<!-- <sect2>Parallel Processing Using Linux -->
<sect2>Linux を使った並列処理
<p>

<!--
The parallel processing using Linux WWW site, <url
url="http://yara.ecn.purdue.edu/~pplinux/">, is the home of this HOWTO
and many related documents including online slides for a full-day
Tutorial.  Aside from the work on the PAPERS project, the Purdue
University School of Electrical and Computer Engineering generally has
been a leader in parallel processing; this site was established to
help others apply Linux PCs for parallel processing.
-->
Linux を使った並列処理の WWW サイトは、<url 
url="http://yara.ecn.purdue.edu/~pplinux/"> にあります。ここは、この 
HOWTO のホームで、見るのに丸一日かかるようなチュートリアルのスライド
を含むたくさんの関連ドキュメントがあります。PAPERS プロジェクトの
活動だけではなく、パーデュ大学の School of Electrical and Computer 
Engineering は、並列処理のリーダー的な存在です。このサイトを開設した
のは、皆さんが Linux PC で並列処理をする手助けをするためです。

<!--
Since Purdue's first cluster of Linux PCs was assembled in February
1994, there have been many Linux PC clusters assembled at Purdue,
including several with video walls.  Although these clusters used 386,
486, and Pentium systems (no Pentium Pro systems), Intel recently
awarded Purdue a donation which will allow it to construct multiple
large clusters of Pentium II systems (with as many as 165 machines
planned for a single cluster).  Although these clusters all have/will
have PAPERS networks, most also have conventional networks.
-->
パーデュ大学の最初の Linux PC のクラスタが 1994 年 2 月に組み立てられ
て以来、Linux PC クラスタがパーデュ大学でたくさん組み立てられました。
その中にはビデオ・ウォールがついたシステムもいくつかありました。それら
のクラスタは、386 や 486、Pentium システム(Pentium Pro システムはあり
ません)を使いましたが、最近になって Intel がパーデュ大学に寄付をして
くれました。その寄付で Pentium II システムを使った大規模なクラスタを
複数構築できるようになりました(165 台ものマシンで 1 つのクラスタを
構築する計画あり)。これらにクラスタはすべて PAPERS のネットワークに
接続する予定で、その内の大部分はこれまでのネットワークにも接続して
います。

<!-- <sect2>Pentium Pro Cluster Workshop -->
<sect2>Pentium Pro クラスタのセミナー
<p>

<!--
In Des Moines, Iowa, April 10-11, 1997, AMES Laboratory held the
Pentium Pro Cluster Workshop.  The WWW site from this workshop, <url
url="http://www.scl.ameslab.gov/workshops/PPCworkshop.html">, contains
a wealth of PC cluster information gathered from all the attendees.
-->
1997 年 4 月 10、11 日にアイオワ州のデモインで AMES 研究所主催で、
Pentium Pro クラスタのセミナーが開かれました。このセミナーからの報告
は、<url url="http://www.scl.ameslab.gov/workshops/PPCworkshop.html"> 
にあります。ここは PC クラスタについて出席者すべてから集めた情報の
宝庫になっています。

<!-- <sect2>TreadMarks DSM (Distributed Shared Memory) -->
<sect2>TreadMarks DSM (分散共有メモリ)
<p>

<!--
DSM (Distributed Shared Memory) is a technique whereby a
message-passing system can appear to behave as an SMP.  There are
quite a few such systems, most of which use the OS page-fault mechanism
to trigger message transmissions.  TreadMarks, <url
url="http://www.cs.rice.edu/~willy/TreadMarks/overview.html">, is one
of the more efficient of such systems and does run on Linux clusters.
The bad news is "TreadMarks is being distributed at a small cost to
universities and nonprofit institutions." For more information about
the software, contact <htmlurl url="mailto:treadmarks@ece.rice.edu"
name="treadmarks@ece.rice.edu">.
-->
DSM(分散共有メモリ)は、メッセージ通信システムが、SMP のごとくふるまえ
る技術です。そのようなシステムはかなり多く、それらのほとんどは OS の
ページ・フォールトのしくみを利用してメッセージ通信をはじめます。
TreadMarks(<url 
url="http://www.cs.rice.edu/~willy/TreadMarks/overview.html">)は、その
ようなシステムの中でも効率的で、Linux クラスタ上でも動作します。
「TreadMarks は大学や非営利組織に対してわずかな費用で配布される」と
いう点が残念なところです。さらにこのソフトウェアについての知りたいなら、
treadmarks@ece.rice.edu に連絡をとってください。

<sect2>U-Net (User-level NETwork interface architecture)
<p>

<!--
The U-Net (User-level NETwork interface architecture) project at
Cornell, <url url="http://www2.cs.cornell.edu/U-Net/Default.html">,
attempts to provide low-latency and high-bandwidth using commodity
network hardware by by virtualizing the network interface so that
applications can send and receive messages without operating system
intervention.  U-Net runs on Linux PCs using a DECchip DC21140 based
Fast Ethernet card or a Fore Systems PCA-200 (not PCA-200E) ATM card.
-->
U-Net(User-level NETwork interface architecture)プロジェクトは
コーネル大学の <url url="http://www2.cs.cornell.edu/U-Net/Default.html">
で行われています。市販のネットワーク機器を使ってネットワーク・インタ
フェースを仮想化し、少ない遅延と広い帯域幅を提供しています。この仮想
インタフェースによって、アプリケーションはオペレーティング・システムを
通すことなく、メッセージを送受信できます。U-Net は、DEC の DC21140 
チップを載せているファースト・イーサネットカードと Fore Systems の 
PCA-200(PCA-200E ではない) ATM カードを使った Linux クラスタ上で
動いています。
<p>
【訳註：開発者がカルフォルニア大学のバークレイ校に異動したため
Web サイトも<url url="http://www.cs.berkeley.edu/~mdw/projects/unet/">
に移っています】

<sect2>WWT (Wisconsin Wind Tunnel)
<p>

<!--
There is really quite a lot of cluster-related work at Wisconsin.  The
WWT (Wisconsin Wind Tunnel) project, <url
url="http://www.cs.wisc.edu/~wwt/">, is doing all sorts of work toward
developing a "standard" interface between compilers and the underlying
parallel hardware.  There is the Wisconsin COW (Cluster Of
Workstations), Cooperative Shared Memory and Tempest, the Paradyn
Parallel Performance Tools, etc.  Unfortunately, there is not much
about Linux.
-->
ウィスコンシン大学では、クラスタ関連の研究がとても盛んに行われています。
WWT(Wisconsin Wind Tunnel)プロジェクト(<url 
url="http://www.cs.wisc.edu/~wwt/">)は、コンパイラと並列処理の基盤となる
機器間の「標準的」なインタフェース開発に関連するすべて分野で研究を行って
います。Wisconsin COW(Cluster Of Workstations)は、Cooperative Shared 
Memory や Tempest、Paradyn Parallel Performance Tools 等を開発しています。
残念ながら、Linux についてはあまり触れられていません。
<p>
【訳註：Paradyn と Wisconsin Wind Tunnel は、独立したプロジェクト
のニックネームです。Cooperative Shared Memory は、ソフトウェアでデータの
変化を管理し、共有メモリのハードウェアを単純化します。Tempest は、プロ
グラム、コンパイラ、ライブラリにメッセージ通信や透過的な共有メモリ、
もしくはその組み合わせを提供するインタフェースです。Paradyn Parallel 
Performance Tools は、プログラマに対してプログラムの遅い部分を自動的に
抽出し、その問題点についての情報をプログラマに与え、チューニングの手助け
を行うツールです】


<!-- <sect>SIMD Within A Register (e.g., using MMX) -->
<sect>SIMD Within A Register(例えば MMX を利用)
<p>

<!--
SIMD (Single Instruction stream, Multiple Data stream) Within A
Register (SWAR) isn't a new idea.  Given a machine with <em>k</em>-bit
registers, data paths, and function units, it has long been known that
ordinary register operations can function as SIMD parallel operations
on <em>n</em>, <em>k</em>/<em>n</em>-bit, integer field values.
However, it is only with the recent push for multimedia that the 2x to
8x speedup offered by SWAR techniques has become a concern for
mainstream computing.  The 1997 versions of most microprocessors
incorporate hardware support for SWAR:
-->
SIMD(Single Instruction stream, Multiple Data stream) Within A
Register(SWAR)は、新しいアイディアではありません。<em>k</em> ビットの
レジスタとデータパス、演算装置を持つマシンでは、一般的なレジスタ処理は、
SIMD の並列処理で動くことが知られています。
つまり <em>k</em>/<em>n</em> ビットの整数領域の値として <em>n</em> 個
実行できます。
しかし最近になって SWAR 技術によってマルチメディア処理が 2 倍から 8 倍
早くなったことで、この技術がコンピューティングのメインストリームで関心
が持たれるようになったのに過ぎません。1997 年時点でのマイクロプロセッサ
のほとんどは、組み込みのハードウェアで SWAR をサポートしています。

<itemize>
<item>
<!--
<htmlurl url="http://www.amd.com/html/products/pcd/techdocs/appnotes/20726a.pdf" 
-->
<htmlurl url="http://www.amd.com/support/techdocdir.html" 
name="AMD K6 MMX (MultiMedia eXtensions)">

<item><htmlurl url="http://www.cyrix.com:80/process/SUPPORT/isv.htm" 
name="Cyrix M2 MMX (MultiMedia eXtensions)">
<p>
【訳註：VIA の Web サイトはオンラインドキュメントの提供を停止しています】

<item>
<!--
<htmlurl url="http://ftp.digital.com/pub/Digital/info/semiconductor/literature/alphahb2.pdf" 
-->
<htmlurl url="http://opensource.compaq.com/the_source/technical_papers/pauls-tips.htm" 
name="Digital Alpha MAX (MultimediA eXtensions)">
<p>
【訳註：MAX は MVIという名称に変更されています】

<item><htmlurl 
url="http://hpcc997.external.hp.com:80/wsg/strategies/pa2go3/pa2go3.html" 
name="Hewlett-Packard PA-RISC MAX (Multimedia Acceleration
eXtensions)">【訳註：リンク切れ】

<!--
<item><htmlurl url="http://developer.intel.com/drg/mmx/" name="Intel
Pentium II &amp; Pentium with MMX (MultiMedia eXtensions)">
-->
<item><htmlurl 
url="http://www.intel.co.jp/jp/developer/vtune/v4/cbts/strmsimd/appnotes.htm" name="Intel
Pentium II &amp; Pentium with MMX (MultiMedia eXtensions)">

<!--
<item><htmlurl url="http://www.microunity.com/www/mediaprc.htm" 
name="Microunity Mediaprocessor SIGD (Single Instruction on Groups of
Data)">
-->
<item><htmlurl url="http://www.microunity.com/www/broadband/faqs/faqs.html" 
name="Microunity Mediaprocessor SIGD (Single Instruction on Groups of
Data)">

<item><htmlurl url="http://www.mips.com/arch/ISA5/" name="MIPS Digital
Media eXtension (MDMX, pronounced Mad Max)">【訳註：リンク切れ】

<item><htmlurl url="http://www.sun.com/sparc/vis/index.html" name="Sun
SPARC V9 VIS (Visual Instruction Set)">
</itemize>

<!--
There are a few holes in the hardware support provided by the new
microprocessors, quirks like only supporting some operations for some
field sizes.  It is important to remember, however, that you don't
need any hardware support for many SWAR operations to be efficient.
For example, bitwise operations are not affected by the logical
partitioning of a register.
-->
新しいマイクロプロセッサが提供しているハードウェア機能には、極秘に
なっていたり、あるフィールドの大きさのためだけに必要な操作のような
おかしなものはほとんどありません。重要な点は、SWAR の操作を効率的行う
のにいかなるハードウェアのサポートも必要がないということです。
例えば、論理的に 1 つのレジスタを分割しても、ビットごとの演算には影響が
でません。

<!-- <sect1>SWAR: What Is It Good For?  -->
<sect1>SWAR の何が優れているのか？
<p>

<!--
Although <em>every</em> modern processor is capable of executing with
at least some SWAR parallelism, the sad fact is that even the best
SWAR-enhanced instruction sets do not support very general-purpose
parallelism.  In fact, many people have noticed that the performance
difference between Pentium and "Pentium with MMX technology" is often
due to things like the larger L1 cache that coincided with appearance
of MMX.  So, realistically, what is SWAR (or MMX) good for?
-->
最近のプロセッサであれば<em>どれでも</em>多かれ少なかれ SWAR の並列処理
機能を生かせます。ただ残念なことに、SWAR で大幅に機能強化された命令セット
が、汎用的に並列処理に適用できるわけではありません。実際には、皆さんも 
Pentium と「MMX Pentium」の性能の違いは、MMX が発売されたと同時に搭載
されたより大きな L1 キャッシュ等のおかげであることに気づかれていると
思います。本当のところ、SWAR(もしくは MMX)は何が良いのでしょうか？

<itemize>
<!--
<item>Integers only, the smaller the better.  Two 32-bit values fit in
a 64-bit MMX register, but so do eight one-byte characters or even an
entire chess board worth of one-bit values.
-->
<item>データは整数のみ。小さければ小さい程良い。32 ビットの値 2 つが、
	64 ビットの MMX レジスタにはちょうどいいが、8 個の 1 バイトの
	キャラクタもしくは 1 ビットの値をチェス盤に値を散らすようにセット
	する

<!--
Note: there <em>will be a floating-point version of MMX</em>, although
very little has been said about it at this writing.  Cyrix has posted
a set of slides, <url url="ftp://ftp.cyrix.com/developr/mpf97rm.pdf">,
that includes a few comments about <bf>MMFP</bf>.  Apparently, MMFP
will support two 32-bit floating-point numbers to be packed into a
64-bit MMX register; combining this with two MMFP pipelines will yield
four single-precision FLOPs per clock.
-->
	注意：<em>浮動小数点版の MMX</em>もあるようだが、これを記述している
	時点では、ほんの少ししか出まわっていないと言われている。Cyrix は以前
	発表したスライド(<url url="ftp://ftp.cyrix.com/developr/mpf97rm.pdf">)
	【訳註：リンク切れ】の中で、<bf>MMFP</bf> についてコメントしている。
	MMFP は 2 つの 32 ビット浮動小数値をパックして 64 ビットの MMX レジスタ
	に納め、これをまとめて 2 つの MMFP パイプラインに流し、クロック当たり 
	4 つの単精度浮動小数点演算をサポートするとしている。
<p>
【訳註：2001.3 現在、Cyrix(現 VIA 傘下)のプロセッサでこの機能を
実装しているものはありませんし、予定も発表されていません】

<!--
<item>SIMD or vector-style parallelism.  The same operation is applied
to all fields simultaneously.  There are ways to nullify the effects on
selected fields (i.e., equivalent to SIMD enable masking), but they
complicate coding and hurt performance.
-->
<item>SIMD もしくはベクトル型の並列性。同じ操作がすべてのフィールド
	に対して同時に発生する。特定フィールドの結果を無効にする(つまり、SIMD が
	マスキングをすることと同じ)手段があるが、コーディングが複雑になったり
	パフォーマンスが低下したりする

<!--
<item>Localized, regular (preferably packed), memory reference
patterns.  SWAR in general, and MMX in particular, are terrible at
randomly-ordered accesses; gathering a vector <tt>x[y]</tt> (where
<tt>y</tt> is an index array) is prohibitively expensive.
-->
<item>ローカルで規則的な(パックしてあればなお良い)メモリ参照パターン。
	SWAR 全般、特に MMX はランダムな順序でアクセスするととんでもないこと
	になる。<tt>x[y]</tt>(<tt>y</tt> インデックスの配列)のようなベクトル
	を集めてくる処理はとても重くなる
</itemize>

<!--
These are serious restrictions, but this type of parallelism occurs in
many parallel algorithms - not just multimedia applications.  For the
right type of algorithm, SWAR is more effective than SMP or cluster
parallelism...  and it doesn't cost anything to use it.
-->
これらの制約は深刻ですが、このタイプの並列性はマルチメディアの
アプリケーションだけでなく、並列アルゴリズムではよく生じることです。
アルゴリズムのタイプが適切であれば、SWAR は、SMP や クラスタの並列性
より有効ですし、使用するに当ってまったく費用がかかりません。

<!-- <sect1>Introduction To SWAR Programming -->
<sect1>SWAR プログラミング入門
<p>

<!--
The basic concept of SWAR, SIMD Within A Register, is that operations
on word-length registers can be used to speed-up computations by
performing SIMD parallel operations on <em>n</em>
<em>k</em>/<em>n</em>-bit field values.  However, making use of
SWAR technology can be awkward, and some SWAR operations are actually
more expensive than the corresponding sequences of serial operations
because they require additional instructions to enforce the field
partitioning.
-->
SWAR(SIMD Within A Register)の基本的なコンセプトは、ワード長レジスタ
の操作を <em>n</em><em>k</em>/<em>n</em> ビットのフィールド値を SIMD 
の並列演算をすることで、計算速度を向上させる点にあります。しかし、
SWAR 技術は扱いづらく、実際 SWAR の演算は同様な演算を行う順次演算を連続
して行ったのと比べて重くなります。それは SWAR の演算には、フィールドを
分割する命令がさらに加わるためです。

<!--
To illustrate this point, let's consider a greatly simplified SWAR
mechanism that manages four 8-bit fields within each 32-bit register.
The values in two registers might be represented as:
-->
この点を説明するのに、SWAR のしくみをかなり単純化して考えてみること
にしましょう。4 つの 8 ビットフィールド長を持つ 32 ビットのレジスタ 
があるとします。
2 つのレジスタの値は、下記のようになります。

<code>
         PE3     PE2     PE1     PE0
      +-------+-------+-------+-------+
Reg0  | D 7:0 | C 7:0 | B 7:0 | A 7:0 |
      +-------+-------+-------+-------+
Reg1  | H 7:0 | G 7:0 | F 7:0 | E 7:0 |
      +-------+-------+-------+-------+
</code>

<!--
This simply indicates that each register is viewed as essentially a
vector of four independent 8-bit integer values.  Alternatively, think
of <tt>A</tt> and <tt>E</tt> as values in Reg0 and Reg1 of processing
element 0 (PE0), <tt>B</tt> and <tt>F</tt> as values in PE1's
registers, and so forth.
-->
この簡単な図はそれぞれのレジスタに 4 つの独立した 8 ビットの値のベクトル
があることを表しています。<tt>A</tt> と <tt>E</tt> が Reg0 と Reg1 の
プロセッシングエレメント 0(PE0)、<tt>B</tt> と <tt>F</tt> を PE1 の
レジスタ値とも見なせます。その他の項目も同様です。

<!--
The remainder of this document briefly reviews the basic classes of
SIMD parallel operations on these integer vectors and how these
functions can be implemented.
-->
この後ドキュメントでは SIMD 並列処理を分類し、ベクトルを扱う関数が
どのように実装されているかをこの整数ベクトルを元にして概観していき
ます。

<!-- <sect2>Polymorphic Operations -->
<sect2>ポリモフィックな操作
<p>

<!--
Some SWAR operations can be performed trivially using ordinary 32-bit
integer operations, without concern for the fact that the operation is
really intended to operate independently in parallel on these 8-bit
fields.  We call any such SWAR operation <em>polymorphic</em>, since
the function is unaffected by the field types (sizes).
-->
SWAR の操作のいくつかは、通常の 32 ビット整数の操作そのままに処理
します。しかし実際には、この操作が並列して独立に 8 ビットのフィールド
を操作することとは無関係です。このような SWAR の操作のことを<em>
ポリモフィック</em>と呼んでいます。その操作がフィールドのタイプ(サイズ)
に影響されないためです。

<!--
Testing if any field is non-zero is polymorphic, as are all bitwise
logic operations.  For example, an ordinary bitwise-and operation (C's
<tt>&amp;</tt> operator) performs a bitwise and no matter what the
field sizes are.  A simple bitwise and of the above registers yields:
-->
どのフィールドがゼロでないかをテストするのは、すべてに対してビット論理
演算をする点でポリモフィックな操作と言えます。例えば、通常のビット論理
積演算(C の <tt>&amp;</tt> 演算子)はフィールドの大きさがいくつであっても、
ビット演算となります。単純なビット論理積演算を上記のレジスタで行うと下記
のようになります。

<code>
          PE3       PE2       PE1       PE0
      +---------+---------+---------+---------+
Reg2  | D&ero;H 7:0 | C&ero;G 7:0 | B&ero;F 7:0 | A&ero;E 7:0 |
      +---------+---------+---------+---------+
</code>

<!--
Because the bitwise and operation always has the value of result bit
<em>k</em> affected only by the values of the operand bit <em>k</em>
values, all field sizes are supported using the same single
instruction.
-->
ビット論理積演算は常にオペランド・ビットの <em>k</em> という値に
だけ左右されて <em>k</em> というビット値になるので、フィールドの大
きさはすべて同じ 1 つの命令を使ってカバーできます。

<!-- <sect2>Partitioned Operations -->
<sect2>分割操作
<p>

<!--
Unfortunately, lots of important SWAR operations are not polymorphic.
Arithmetic operations such as add, subtract, multiply, and divide are
all subject To carry/borrow interactions between fields.  We call such
SWAR operations <em>partitioned</em>, because each such operation must
effectively partition the operands and result to prevent interactions
between fields.  However, there are actually three different methods
that can be used to achieve this effect.
-->
あいにく SWAR 操作で重要なものの中にも、ポリモフィックでない操作が
たくさんあります。
四則演算のような算術演算では、フィールド間で桁の上げ下げをする必要が
あります。
そのような操作を SWAR で行うことを「分割する」と呼んでいます。
理由は、そのような操作が事実上オペランドや結果を分割して、フィールド
間のやりくりを防がなければならないからです。実際この効果を生むのには
3 つの異なる手法が取られます。

<!-- <sect3>Partitioned Instructions -->
<sect3>分割命令
<p>

<!--
Perhaps the most obvious approach to implementing partitioned
operations is to provide hardware support for "partitioned parallel
instructions" that cut the carry/borrow logic between fields.  This
approach can yield the highest performance, but it requires a change
to the processor's instruction set and generally places many
restrictions on field size (e.g., 8-bit fields might be supported, but
not 12-bit fields).
-->
おそらく、分割操作の中で最も理解しやすい実装方法は、「分割並列命令
(partitioned parallel instruction)」をハードウェアでサポートすることで
しょう。これでフィールド間の桁の上げ下げを排除します。この方法を使えば
パフォーマンスは文句なく上がりますが、プロセッサの命令セットが変更
されたり、フィールドの大きさに対しての制限が増えてしまいます
(例えば、8 ビットのフィールドはサポートしても、12 ビットは駄目であるとか)。

<!--
The AMD/Cyrix/Intel MMX, Digital MAX, HP MAX, and Sun VIS all
implement restricted versions of partitioned instructions.
Unfortunately, these different instruction set extensions have
significantly different restrictions, making algorithms somewhat
non-portable between them.  For example, consider the following
sampling of partitioned operations:
-->
AMD や Cyrix、Intel の MMX や Digital の MAX、HP の MAX、 Sun の VIS 
すべては、分割命令の実装に制限があります。残念なことに、それぞれの
命令セット拡張は制限事項についても著しく異なっているので、それらの間
では若干ですがアルゴリズムに移植性がなくなっています。例えば、下記で
分割命令の一部を見てみましょう。

<code>
  Instruction           AMD/Cyrix/Intel MMX   DEC MAX   HP MAX   Sun VIS
+---------------------+---------------------+---------+--------+---------+
| Absolute Difference |                     |       8 |        |       8 |
+---------------------+---------------------+---------+--------+---------+
| Merge Maximum       |                     |   8, 16 |        |         |
+---------------------+---------------------+---------+--------+---------+
| Compare             |           8, 16, 32 |         |        |  16, 32 |
+---------------------+---------------------+---------+--------+---------+
| Multiply            |                  16 |         |        |    8x16 |
+---------------------+---------------------+---------+--------+---------+
| Add                 |           8, 16, 32 |         |     16 |  16, 32 |
+---------------------+---------------------+---------+--------+---------+
</code>

<!--
In the table, the numbers indicate the field sizes, in bits, for which
each operation is supported.  Even though the table omits many
instructions including all the more exotic ones, it is clear that
there are many differences.  The direct result is that high-level
languages (HLLs) really are not very effective as programming models,
and portability is generally poor.
-->
この表では数字がフィールドの大きさをビットで表していて、この値でそれぞれ
の操作が可能になっています。もっと興味深い命令など多くの命令が表には
載っていませんが、この表だけでも違いの大きさは明らかです。結論としては、
明らかに高級言語(HLL)はプログラミング・モデルとしてまったく役に立たず、
移植性もほとんどないことです。

<!-- <sect3>Unpartitioned Operations With Correction Code -->
<sect3>コードを修正して、分割命令を使わない
<p>

<!--
Implementing partitioned operations using partitioned instructions can
certainly be efficient, but what do you do if the partitioned
operation you need is not supported by the hardware?  The answer is
that you use a series of ordinary instructions to perform the operation
with carry/borrow across fields, and then correct for the undesired
field interactions.
-->
分割命令を使った分割操作を実装すれば確かに効果が上がりますが、もし必要
としている分割操作をハードウェアがサポートしていなかったらどうなる
でしょう？ 答は、通常の命令群を使ってフィールド間で桁の上げ下げを行う
操作を行い、フィールド間での余計なやりとりを正します。

<!--
This is a purely software approach, and the corrections do introduce
overhead, but it works with fully general field partitioning.  This
approach is also fully general in that it can be used either to fill
gaps in the hardware support for partitioned instructions, or it can
be used to provide full functionality for target machines that have no
hardware support at all.  In fact, by expressing the code sequences in
a language like C, this approach allows SWAR programs to be fully
portable.
-->
この手段はまさにソフトウェアによるもので、修正によるオーバーヘッド
が加わります。しかし、これで汎用的にフィールドの分割が可能になります。
この方法は非常に汎用的で、ハードウェア毎の分割命令の違いを埋めるだけ
でなく、まったくハードウェアのサポートのないマシンに対しても機能をフル
に提供できます。実際には、C のようなプログラミング言語でコードを書く
ことで、SWAR プログラムはとても移植しやすくなります。

<!--
The question immediately arises:  precisely how inefficient is it to
simulate SWAR partitioned operations using unpartitioned operations
with correction code?  Well, that is certainly the &dollar;64k question...
but many operations are not as difficult as one might expect.
-->
ここで疑問が沸いてきます。SWAR の分割操作を使わずにコードを修正して
シミュレートした場合、正確にどのくらい効率が落ちるのでしょうか？ 
いいところを突いた質問です…しかし、皆さんが思っているほど難しい操作が
多いわけではありません。

<!--
Consider implementing a four-element 8-bit integer vector add of two
source vectors, <tt>x</tt>+<tt>y</tt>, using ordinary 32-bit
operations.
-->
4 つの要素を持つ 8 ビットの整数ベクトル 2 つを 32 ビット操作を使って
加算(<tt>x</tt>+<tt>y</tt>)を実現することを考えてみましょう。

<!--
An ordinary 32-bit add might actually yield the correct result, but
not if any 8-bit field carries into the next field.  Thus, our goal is
simply to ensure that such a carry does not occur.  Because adding two
<em>k</em>-bit fields generates an at most <em>k</em>+1 bit
result, we can ensure that no carry occurs by simply "masking out" the
most significant bit of each field.  This is done by bitwise anding
each operand with <tt>0x7f7f7f7f</tt> and then performing an
ordinary 32-bit add.
-->
通常の 32 ビット加算は正確な値になると思いますが、それはどの 8 ビット
フィールドも次のフィールドに影響を与えない場合です。したがって、最終的
にはそのような桁上がりがまったく起こらないことを保証しなければいけません。
<em>k</em> ビットのフィールドを加算すると、多くても <em>k</em>+1 ビット
値になるので、桁上がりは単にそれぞれのフィールドの最上位のビットを「マスク
をかけること」で防げます。これはそれぞれのオペランドに対して <tt>0x7f7f7f7f
</tt> をビット単位で論理積を取った後、通常の 32 ビット加算をすれば OK です。

<code>
t = ((x &ero; 0x7f7f7f7f) + (y &ero; 0x7f7f7f7f));
</code>

<!--
That result is correct...  except for the most significant bit within
each field.  Computing the correct value for each field is simply a
matter of doing two 1-bit partitioned adds of the most significant
bits from <tt>x</tt> and <tt>y</tt> to the 7-bit carry result
which was computed for <tt>t</tt>.  Fortunately, a 1-bit
partitioned add is implemented by an ordinary exclusive or operation.
Thus, the result is simply:
-->
これで、それぞれのフィールドの最上位ビットを除いて正確な値がでました。
それぞれのフィールドの値を正確に計算するには、<tt>x</tt> と <tt>y</tt> 
2 つに分割された最上位の 1 ビットの値を 7 ビットで計算した <tt>t</tt> 
に加算するだけです。都合のいいことに、分割した 1 ビットの加算は通常の
排他論理和演算として実装されています。
つまり、結果は単純に下記のように求められます。

<code>
(t ^ ((x ^ y) &ero; 0x80808080))
</code>

<!--
Ok, well, maybe that isn't so simple.  After all, it is six operations
to do just four adds.  However, notice that the number of operations
is not a function of how many fields there are...  so, with more
fields, we get speedup.  In fact, we may get speedup anyway simply
because the fields were loaded and stored in a single (integer vector)
operation, register availability may be improved, and there are fewer
dynamic code scheduling dependencies (because partial word references
are avoided).
-->
そんなにやさしくはないですね。結局ちょうど 4 つの加算に 6 回の操作が
必要でした。しかし、操作の回数はフィールドの数がどのくらいあるか…と
いうこととは関係ないことに注意してください。フィールドが増える程速度
が上がります。とにかく実際に速度が向上します。それはフィールドを 1 回
の操作(整数ベクトル)でロードやストアすることで、レジスタを利用する割合
が増え、動的にコードを実行するのに必要なスケジューリングの依存関係が
ほとんどなくなるからです(部分的なワードへの参照を避けられるため)。

<!-- <sect3>Controlling Field Values -->
<sect3>フィールド値の制御
<p>

<!--
While the other two approaches to partitioned operation implementation
both center on getting the maximum space utilization for the registers,
it can be computationally more efficient to instead control the field
values so that inter-field carry/borrow events should never occur.
For example, if we know that all the field values being added are such
that no field overflow will occur, a partitioned add operation can be
implemented using an ordinary add instruction; in fact, given this
constraint, an ordinary add instruction appears polymorphic, and is
usable for any field sizes without correction code.  The question
thus becomes how to ensure that field values will not cause
carry/borrow events.
-->
上記 2 つの方法とも、分割操作でレジスタを最大限利用するように実行する
のに対して、この方法ではフィールドの値を制御することで、より効率的に
計算を行い、フィールド間の桁の上げ下げが決して起こらないようにします。
例えば、加算したフィールドすべてにおいてオーバーフローが生じないことが
わかっている場合、分割操作の加算は通常の加算命令を使って実行できます。
実際この制約下で通常の加算命令はポリモフィックとなり、コードを修正する
ことなしにどんなフィールドの大きさでも利用できることになります。ここで
問題なのは、どうしたらフィールドの値間で桁の上下げを起こさないかを確認
する方法です。

<!--
One way to ensure this property is to implement partitioned
instructions that can restrict the range of field values.  The Digital
MAX vector minimum and maximum instructions can be viewed as hardware
support for clipping field values to avoid inter-field carry/borrow.
-->
この特性を確認する方法の 1 つは、フィールドの値の範囲を制約する分割命令
を実装することです。Digital の MAX にあるベクトル最小最大命令は、
ハードウェアでこれをサポートしているようで、フィールドの値をある範囲で
カットして、フィールド間で桁の上げ下げを起こさないようにしています。

<!--
However, suppose that we do not have partitioned instructions that can
efficiently restrict the range of field values...  is there a
sufficient condition that can be cheaply imposed to ensure
carry/borrow events will not interfere with adjacent fields?  The
answer lies in analysis of the arithmetic properties.  Adding two
<em>k</em>-bit numbers generates a result with at most
<em>k</em>+1 bits; thus, a field of <em>k</em>+1 bits can safely
contain such an operation despite using ordinary instructions.
-->
しかし、フィールドの値の範囲を効率的に制限する分割命令がない場合は
どうなるでしょうか…桁の上げ下げで隣のフィールドに影響を与えていない
ことを手軽に保証する十分条件はあるのでしょうか？ その答は演算の特性
を分析することにあります。<em>k</em> ビットの 2 つの数を加算すると、
結果は多くても <em>k</em>+1 ビットです。したがって、<em>k</em>+1 
ビットのフィールドなら、通常の命令を使っていても問題なく収まります。

<!--
Thus, suppose that the 8-bit fields in our earlier example are now
7-bit fields with 1-bit "carry/borrow spacers":
-->
つまり先にあげた例を 8 ビットのフィールドを 7 ビットに 1 ビットの
「桁の上げ下げ用の領域」を加えたものとしてみましょう。

<code>
              PE3          PE2          PE1          PE0
      +----+-------+----+-------+----+-------+----+-------+
Reg0  | D' | D 6:0 | C' | C 6:0 | B' | B 6:0 | A' | A 6:0 |
      +----+-------+----+-------+----+-------+----+-------+
</code>

<!--
A vector of 7-bit adds is performed as follows.  Let us assume that,
prior to the start of any partitioned operation, all the carry spacer
bits (<tt>A'</tt>, <tt>B'</tt>, <tt>C'</tt>, and <tt>D'</tt>) have the
value 0.  By simply executing an ordinary add operation, all the
fields obtain the correct 7-bit values; however, some spacer bit
values might now be 1.  We can correct this by just one more
conventional operation, masking-out the spacer bits.  Our 7-bit
integer vector add, <tt>x</tt>+<tt>y</tt>, is thus:
-->
7 ビットのベクトルの加算は次のようになります。まず分割操作をする前に、
繰り上げ用領域に当るビット(<tt>A'</tt> や <tt>B'</tt>、<tt>C'</tt>、
<tt>D'</tt>)すべてが 0 であると想定します。単純に通常の加算演算を行う
とすべてのフィールドは正しい 7 ビット分の値になります。しかし、繰り上げ
用領域のビットには、1 という値が入っているものが出てくるかもしれません。
これを修正するには、もう 1 回だけ通常の操作を行います。それは繰り上げ
用領域のビットにマスクをかけることです。7 ビット分の整数のベクトル加算 
<tt>x</tt>+<tt>y</tt> はこのようになります。

<code>
((x + y) &ero; 0x7f7f7f7f)
</code>

<!--
This is just two instructions for four adds, clearly yielding good
speedup.
-->
これで、4 つの加算がちょうど 2 つの命令で済み、はっきりと速度が向上
します。

<!--
The sharp reader may have noticed that setting the spacer bits to 0
does not work for subtract operations.  The correction is, however,
remarkably simple.  To compute <tt>x</tt>-<tt>y</tt>, we simply
ensure the initial condition that the spacers in <tt>x</tt> are all
1, while the spacers in <tt>y</tt> are all 0.  In the worst case,
we would thus get:
-->
鋭い読者の方なら、繰り上げ用領域のビットを 0 にすると減算演算がうまく
ないことに気づかれたと思います。しかしこれはとても簡単に修正できます。
<tt>x</tt>-<tt>y</tt> を計算するには、初期状態で <tt>x</tt> の繰り上げ
用領域のビットがすべて 1 で <tt>y</tt> がすべて 0 であることを保証すれば
いいのです。最悪の場合でもこのようにすれば良いはずです。

<code>
(((x | 0x80808080) - y) &ero; 0x7f7f7f7f)
</code>

<!--
However, the additional bitwise or operation can often be optimized
out by ensuring that the operation generating the value for
<tt>x</tt> used <tt>| 0x80808080</tt> rather than <tt>&amp;
0x7f7f7f7f</tt> as the last step.
-->
しかし、追加したビット論理和演算は、最後の操作である 
<tt>&amp; 0x7f7f7f7f</tt> の部分よりも <tt>x</tt> に 
<tt>| 0x80808080</tt> で値を出す操作のところで最適化できます。

<!--
Which method should be used for SWAR partitioned operations?  The
answer is simply "whichever yields the best speedup."  Interestingly,
the ideal method to use may be different for different field sizes
within the same program running on the same machine.
-->
どの方法を SWAR の分割処理として使うべきなのでしょうか？ 答は簡単で、
「一番速度が速いものならどれでも」です。興味深いことに、同じプログラム
を同じマシンで実行しても、フィールドのサイズが異なれば最適な方法も変わる
かもしれません。

<!-- <sect2>Communication &amp; Type Conversion Operations -->
<sect2>値間のやりとりと型変換操作
<p>

<!--
Although some parallel computations, including many operations on image
pixels, have the property that the <em>i</em>th value in a vector is
a function only of values that appear in the <em>i</em>th position
of the operand vectors, this is generally not the case.  For example,
even pixel operations such as smoothing require values from adjacent
pixels as operands, and transformations like FFTs require more complex
(less localized) communication patterns.
-->
並列計算の中には画素に対する演算などのように、あるベクトル中の <em>i</em> 
番目の値がオペランド側のベクトルの <em>i</em> 番目の位置にある値とだけ
相関関係にある場合がありますが、必ずしもこのケースとはかぎりません。
例えば、スムージングのような画素の操作は、隣の画素の値をオペランドとして
必要としますし、FFT(fast Fourier transform 高速フーリエ変換)のような変形
は、さらに複雑な(局所的ではない)やりとりをする傾向にあります。

<!--
It is not difficult to efficiently implement 1-dimensional nearest
neighbor communication for SWAR using unpartitioned shift operations.
For example, to move a value from <tt>PE</tt><em>i</em> to
<tt>PE</tt>(<em>i</em>+1), a simple shift operation suffices.
If the fields are 8-bits in length, we would use:
-->
一次元の隣接する値のやりとりを分割操作ではないシフト操作で実現するのは
難しいことではありません。
例えば、<tt>PE</tt><em>i</em> の値を <tt>PE</tt>(<em>i</em>+1) に移動
するには、単純なシフト操作で十分です。
フィールドが 8 ビットの大きさであれば、下記のようになります。

<code>
(x << 8)
</code>

<!--
Still, it isn't always quite that simple.  For example, to move a
value from <tt>PE</tt><em>i</em> to
<tt>PE</tt>(<em>i</em>-1), a simple shift operation might
suffice...  but the C language does not specify if shifts right
preserve the sign bit, and some machines only provide signed shift
right.  Thus, in the general case, we must explicitly zero the
potentially replicated sign bits:
-->
しかしいつもそれほど単純とは限りません。例えば、<tt>PE</tt><em>i</em> 
を <tt>PE</tt>(<em>i</em>-1) に移動するには単純なシフト操作で十分で
あるかもしれません…が、C ではシフト操作が符号ビットを正しく維持できて
いるかどうかを確認できませんし、マシンの中には符号化シフトしか正しく
行えないものもあります。つまり一般的には、符号ビットのコピーを行って、
それを 0 に設定しておく必要があります。

<code>
((x >> 8) &ero; 0x00ffffff)
</code>

<!--
Adding "wrap-around connections" is also reasonably efficient using
unpartitioned shifts.  For example, to move a value from
<tt>PE</tt><em>i</em> to <tt>PE</tt>(<em>i</em>+1) with
wraparound:
-->
「折り返してつなげる」方法をとると、シフト操作を分割せずにそこそこ
効率的に行えます。例えばこの方法を使って <tt>PE</tt><em>i</em> を 
<tt>PE</tt>(<em>i</em>+1)に移動するには、下記のようにします。

<code>
((x << 8) | ((x >> 24) &ero; 0x000000ff))
</code>

<!--
The real problem comes when more general communication patterns must
be implemented.  Only the HP MAX instruction set supports arbitrary
rearrangement of fields with a single instruction, which is called
<tt>Permute</tt>.  This <tt>Permute</tt> instruction is really
misnamed; not only can it perform an arbitrary permutation of the
fields, but it also allows repetition.  In short, it implements an
arbitrary <tt>x[y]</tt> operation.
-->
さらに一般的なパターンのやり取りを実装しなければならないとなると、問題
が大きくなります。HP の MAX での命令セットに限って言うと、任意に
フィールドを再配置する命令が単独で存在します。この命令を <tt>Permute</tt> 
と呼んでいます。<tt>Permute</tt> 命令という名付け方は不適切で、任意に
並べ替えを行うだけでなく、繰り返しもできてしまいます。つまり、自由に 
<tt>x[y]</tt> 演算が可能になっています。

<!--
Unfortunately, <tt>x[y]</tt> is very difficult to implement without
such an instruction.  The code sequence is generally both long and
inefficient; in fact, it is sequential code.  This is very
disappointing.  The relatively high speed of <tt>x[y]</tt>
operations in the MasPar MP1/MP2 and Thinking Machines CM1/CM2/CM200
SIMD supercomputers was one of the key reasons these machines performed
well.  However, <tt>x[y]</tt> has always been slower than nearest
neighbor communication, even on those supercomputers, so many
algorithms have been designed to minimize the need for
<tt>x[y]</tt> operations.  In short, without hardware support, it
is probably best to develop SWAR algorithms as though
<tt>x[y]</tt> wasn't legal...  or at least isn't cheap.
-->
<tt>x[y]</tt> という操作は、そのような単独命令なしでは実現することが
非常に困難です。処理するコードが長くなるだけでなく、効率も下がります。
実際には順次処理になってしまいます。これではどうしようもありません。
<tt>x[y]</tt> 演算を比較的高速に行えるシステムが、MasPar の MP1/MP2 
や Thinking Machines の CM1/CM2/CM200 という SIMD スーパーコンピュータ
であることがこれを裏付けています。しかし、そのようなスーパーコンピュータ
であっても、<tt>x[y]</tt> は隣り合ったフィールドとのやりとりと比べて常に
遅く、できるだけ <tt>x[y]</tt> 演算を必要としないようにアルゴリズムを設計
する場合がほとんどです。つまりハードウェアのサポートがなければ、
<tt>x[y]</tt> は演算として不適切と言っても…まあ少なくとも安価に実現できる
わけではありません。

<!-- <sect2>Recurrence Operations (Reductions, Scans, etc.) -->
<p>繰り返し操作(還元、走査など)
<!--
A recurrence is a computation in which there is an apparently
sequential relationship between values being computed.  However, if
these recurrences involve associative operations, it may be possible
to recode the computation using a tree-structured parallel algorithm.
-->
繰り返し処理は、計算している値間に逐次的な関係がはっきりと認められる
計算のことを指します。しかし、繰り返し処理に結合操作がある場合は、
木構造の並列アルゴリズムを使って、計算を記録できる場合があります。

<!--
The most common type of parallelizable recurrence is probably the
class known as associative reductions.  For example, to compute the
sum of a vector's values, one commonly writes purely sequential C code
like:
-->
最も一般的なタイプの並列化した繰り返し処理には、結合還元(associative 
reduction)と言われるものがあります。例えばベクトルの合計を計算するのに、
C のコードで単に逐次処理すると下記のようになります。

<code>
t = 0;
for (i=0; i<MAX; ++i) t += x[i];
</code>

<!--
However, the order of the additions is rarely important.  Floating
point and saturation math can yield different answers if the order of
additions is changed, but ordinary wrap-around integer additions will
yield the same results independent of addition order.  Thus, we can
re-write this sequence into a tree-structured parallel summation in
which we first add pairs of values, then pairs of those partial sums,
and so forth, until a single final sum results.  For a vector of four
8-bit values, just two addition steps are needed; the first step does
two 8-bit adds, yielding two 16-bit result fields (each containing a
9-bit result):
-->
しかし、加算の順序が意味を持つことはまれです。浮動小数点や飽和演算では、
加算の順序が違うと結果が変わってしまいますが、通常のラップラウンドな整数
の加算は順序によって結果に影響がでません。したがって、順次に実行する形
から木構造で並列に合計を出すコードに書き換えられます。こうすると、まず
最初に対となる値を加算し、それが合計値の一部となり…ということを繰り返し
て、最終的に 1 つの合計値になるまで計算します。8 ビットの値を 4 つで構成
したベクトルならば、ちょうど 2 回の加算が必要となります。最初に 2 つの
8 ビットの値を加算して、16 ビットのフィールド 2 つに結果が入ります
(フィールドそれぞれに 9 ビットの結果が入っています)。
<p>
【訳註：飽和演算とは、あらかじめ演算結果の範囲を決めておき、
その範囲を越えた演算結果になった場合にあらかじめ用意した結果に置き換える
処理です】

<code>
t = ((x &ero; 0x00ff00ff) + ((x >> 8) &ero; 0x00ff00ff));
</code>

<!--
The second step adds these two 9-bit values in 16-bit fields to
produce a single 10-bit result:
-->
その次に、16 ビットのフィールドに入っている 9 ビットの値を 2 つ加算して、
10 ビットの結果を 1 つ得ることになります。

<code>
((t + (t >> 16)) &ero; 0x000003ff)
</code>

<!--
Actually, the second step performs two 16-bit field adds...  but the
top 16-bit add is meaningless, which is why the result is masked to a
single 10-bit result value.
-->
実際ここでは、16 ビットのフィールドを 2 つ加算したことになります…が、
先頭の 16 ビットの加算は意味がありません。というのは、結果を 1 つの 10 
ビットの値としてマスクしてしまうからです。

<!--
Scans, also known as "parallel prefix" operations, are somewhat harder
to implement efficiently.  This is because, unlike reductions, scans
produce partitioned results.  For this reason, scans can be implemented
using a fairly obvious sequence of partitioned operations.
-->
走査は「並列化した単項演算」とも呼ばれていて、効率的に実装するのはいくぶん
困難です。還元とは異なり、走査の結果が分割されるからです。このような訳で、
走査はきっと連続した分割操作として実装できます。

<!-- <sect1>MMX SWAR Under Linux -->
<sect1>Linux における MMX を使った SWAR
<p>

<!--
For Linux, IA32 processors are our primary concern.  The good news is
that AMD, Cyrix, and Intel all implement the same MMX instructions.
However, MMX performance varies; for example, the K6 has only one MMX
pipeline - the Pentium with MMX has two.  The only really bad news is
that Intel is still running those stupid MMX commercials....  ;-)
-->
Linux にとって IA32 プロセッサは一番の関心事です。AMD や Cyrix、
intel すべてが同じ MMX 命令を実装しているのは素晴らしいことです。
しかし、MMX のパフォーマンスにはばらつきがあります。例えば、K6 は MMX 
のパイプラインを 1 つしか持っていないのに対して、MMX Pentium は 2 つ
持っています。ただ intel がいまだにへんてこりんなコマーシャルをやっている
のにはうんざりしていますが… ;-)
<p>
【訳註：2001.3 現在 Intel および AMD の高性能デスクトップ PC 用
プロセッサである PentiumIII と Athlon は整数演算の高速化である MMX を
拡張し、それぞれ SSE(internet streaming SIMD extensions)、Enhanced 3DNow! 
を実装し、浮動小数点演算の高速化をはかりました。
浮動小数点演算に関しては Pentium III の方が Athlon より高速と言われています
が、浮動小数点の SIMD 命令については Athlon の方が高速と言われています。
大きな理由は、SSE が 64 ビットの演算装置で 128 ビットのオペランドを処理
するので 2 サイクルかかるのに対し、Enhanced 3DNow! は 64 ビットの演算装置
で 64 ビットのオペランドを処理するので 1 サイクルで済むためです】

<!-- There are really three approaches to using MMX for SWAR: -->
SWAR に MMX を活用する方法は 3 つあります。

<enum>
<!--
<item>Use routines from an MMX library.  In particular, Intel has
developed several "performance libraries," <url
url="http://developer.intel.com/drg/tools/ad.htm">, that offer a
variety of hand-optimized routines for common multimedia tasks.  With
a little effort, many non-multimedia algorithms can be reworked to
enable some of the most compute-intensive portions to be implemented
using one or more of these library routines.  These libraries are not
currently available for Linux, but could be ported.
-->
<item>MMX ライブラリのルーチンを使う。特に intel は「パフォーマンス・
<!--
	ライブラリ」<url url="http://developer.intel.com/drg/tools/ad.htm"> 
-->
	ライブラリ」<url 
	url="http://developer.intel.com/software/products/perflib/"> 
	というものをいくつか開発していて、マルチメディア処理全般を対象に
	手作業で最適化した様々なルーチンを提供している。多少の努力をすれば、
	これらのライブラリのルーチンのいくつかを使って、非マルチメディア用
	のアルゴリズムを計算中心の部分を中心に書き直せる。これらのライブラリ
	は現状 Linux では利用できないが、移植可能である

<!--
<item>Use MMX instructions directly.  This is somewhat complicated by
two facts.  The first problem is that MMX might not be available on
the processor, so an alternative implementation must also be
provided.  The second problem is that the IA32 assembler generally
used under Linux does not currently recognize MMX instructions.
-->
<item>MMX 命令を直接使う。これは 2 つの理由から多少複雑になる。
	まず、MMX がプロセッサ上で利用できないかもしれないこと。そうなると
	他の手段を実装しなければならない。次の問題は、Linux で使っている 
	IA32 のアセンブラが現状では MMX 命令を認識しないことである

<!--
<item>Use a high-level language or module compiler that can directly
generate appropriate MMX instructions.  Such tools are currently under
development, but none is yet fully functional under Linux.  For
example, at Purdue University (<url
url="http://dynamo.ecn.purdue.edu/~hankd/SWAR/">) we are currently
developing a compiler that will take functions written in an
explicitly parallel C dialect and will generate SWAR modules that are
callable as C functions, yet make use of whatever SWAR support is
available, including MMX.  The first prototype module compilers were
built in Fall 1996, however, bringing this technology to a usable
state is taking much longer than was originally expected.
-->
<item>高水準言語もしくは適切な MMX 命令を直接生成できるコンパイラの
	モジュールを使用する。現状そのようなツールは開発中であるが、まだ 
	Linux 上ではすべての機能が動いていない。例えば我々はパーデュ大学
	(<url url="http://dynamo.ecn.purdue.edu/~hankd/SWAR/">)において
	現在コンパイラを開発中である。それらは並列化を施してある少々癖の
	ある C で書かれており、C の関数として呼び出せる SWAR モジュール
	を生成できる予定であり、MMX をはじめとして SWAR の機能をサポート
	するものなら何でも利用できる。最初のプロトタイプであるモジュール・
	コンパイラは 1996 年秋に作成されたが、当初目指していた段階に到達
	するにはまだまだ時間がかかる
<p>
【訳註：2001.3 現在、Linux 用の MMX や 3DNow!、SSE のライブラリ
及びコンパイラ関連は、<url url="http://shay.ecn.purdue.edu/~swar/" 
name="The SWAR Homepage at Purdue University"> にあります】
</enum>

<!--
In summary, MMX SWAR is still awkward to use.  However, with a little
extra effort, the second approach given above can be used now.  Here
are the basics:
-->
要約すると、MMX を使った SWAR はまだ使い物になりません。しかし少し努力
すれば上記 2 番目の方法は現在でも利用できます。主要なポイントをあげます。

<enum>
<!--
<item>You cannot use MMX if your processor does not support it.  The
following GCC code can be used to test if MMX is supported on your
processor.  It returns 0 if not, non-zero if it is supported.
-->
<item>プロセッサが MMX をサポートしていなければ MMX は使えない。下記
	の GCC のコードは MMX をプロセッサがサポートしているかを判定する。
	0 を返せば未サポート、0 以外ならサポートしている

<code>
inline extern
int mmx_init(void)
{
	int mmx_available;

	__asm__ __volatile__ (
		/* Get CPU version information */
		"movl $1, %%eax\n\t"
		"cpuid\n\t"
		"andl $0x800000, %%edx\n\t"
		"movl %%edx, %0"
		: "=q" (mmx_available)
		: /* no input */
	);
	return mmx_available;
}
</code>

<!--
<item>An MMX register essentially holds one of what GCC would call an
<tt>unsigned long long</tt>.  Thus, memory-based variables of this type
become the communication mechanism between your MMX modules and the C
programs that call them.  Alternatively, you can declare your MMX data
as any 64-bit aligned data structure (it is convenient to ensure
64-bit alignment by declaring your data type as a <tt>union</tt> with
an <tt>unsigned long long</tt> field).
-->
<item>MMX レジスタは基本的には GCC が <tt>unsigned long long</tt> を
	呼び出した場合にそれを保持する。つまりメモリベースのこの型の変数は、
	MMX モジュールとそれを呼び出した C プログラム間のやりとりの手段となる。
	その一方で、MMX データを 64 ビットにアラインしたデータ構造として宣言
	できる(<tt>unsigned long long</tt> の大きさを持つ <tt>union</tt> 
	として型宣言することで、簡単に 64 ビットにアラインされていることを保証
	できる)

<!--
<item>If MMX is available, you can write your MMX code using
the <tt>.byte</tt> assembler directive to encode each instruction.
This is painful stuff to do by hand, but not difficult for a compiler
to generate.  For example, the MMX instruction <tt>PADDB MM0,MM1</tt>
could be encoded as the GCC in-line assembly code:
-->
<item>MMX が利用可能なら、アセンブラ命令の <tt>.byte</tt> を使って MMX 
	コードが書け、命令をエンコードできる。
	これは手作業では骨が折れるが、コンパイラでコードを生成するのは難しく
	ない。例えば、MMX 命令の <tt>PADDB MM0,MM1</tt> は GCC のインライン・
	アセンブラのコードで下記のようにエンコードできる

<code>
__asm__ __volatile__ (".byte 0x0f, 0xfc, 0xc1\n\t");
</code>

<!--
Remember that MMX uses some of the same hardware that is used for
floating point operations, so code intermixed with MMX code must not
invoke any floating point operations.  The floating point stack also
should be empty before executing any MMX code; the floating point
stack is normally empty at the beginning of a C function that does not
use floating point.
-->
	MMX が浮動小数点演算をするのと同じハードウェアのある部分を使用して
	いることを忘れないように。MMX が混じっているコードは、浮動小数点
	演算を呼び出してはいけない。また、浮動小数点のスタックは、MMX コード
	を実行する前には空にしておく必要がある。通常、浮動小数点のスタックは 
	C の関数の先頭で浮動小数点を使っていないなら空になっている

<!--
<item>Exit your MMX code by executing the <tt>EMMS</tt> instruction,
which can be encoded as:
-->
<item>MMX コードから抜け出すには、<tt>EMMS</tt> 命令を実行する。
	エンコードすると下記のようになる

<code>
__asm__ __volatile__ (".byte 0x0f, 0x77\n\t");
</code>
</enum>

<!--
If the above looks very awkward and crude, it is.  However, MMX is
still quite young....  future versions of this document will offer
better ways to program MMX SWAR.
-->
上記があまりに扱いづらく、洗練されていないと感じるなら、それはその
通りでしょう。しかし MMX はまだできたばかりで…このドキュメントの
将来の版では、もっと優れた MMX による SWAR をプログラムを提示できる
と思います。

<!-- <sect>Linux-Hosted Attached Processors -->
<sect>Linux に搭載されている付加プロセッサ
<p>

<!--
Although this approach has recently fallen out of favor, it is
virtually impossible for other parallel processing methods to achieve
the low cost and high performance possible by using a Linux system to
host an attached parallel computing system.  The problem is that very
little software support is available; you are pretty much on your own.
-->
この方法は最近注目を浴びなくなってきていますが、並列計算機構を付加した 
Linux システムを使うと、他の並列処理方式では到底不可能な低いコストと
高いパフォーマンスを Linux で実現できます。問題は利用できるソフトウェアが
ほとんどないことで、自分でかなりのことを行う必要があります。

<!-- <sect1>A Linux PC Is A Good Host -->
<sect1>優れたホスト、それは Linux PC
<p>

<!--
In general, attached parallel processors tend to be specialized to
perform specific types of functions.
-->
一般的に付加する形で搭載されているプロセッサは、ある種の機能を動作
させることに特化しています。

<!--
Before becoming discouraged by the fact that you are somewhat on your
own, it is useful to understand that, although it may be difficult to
get a Linux PC to appropriately host a particular system, a Linux PC
is one of the few platforms well suited to this type of use.
-->
自分で多少なりとも作業するという事実にがっかりする前に、まず理解して
おいて損しないことがあります。Linux PC に特定のシステムを採用するのは
難しいことかもしれませんが、Linux PC はこの種の利用のしかたに向いて
いる数少ないプラットフォームの 1 つである、ということです。

<!--
PCs make a good host for two primary reasons.  The first is the cheap
and easy expansion capability; resources such as more memory, disks,
networks, etc., are trivially added to a PC.  The second is the ease
of interfacing.  Not only are ISA and PCI bus prototyping cards widely
available, but the parallel port offers reasonable performance in a
completely non-invasive interface.  The IA32 separate I/O space also
facilitates interfacing by providing hardware I/O address protection
at the level of individual I/O port addresses.
-->
PC がホストとして優れている理由は、主に 2 つあります。まず、安価で
簡単に拡張できることです。メモリやディスク、ネットワーク等の資源は
苦労なしに PC へ追加できます。それから、インタフェースが容易に取れる点
もあげられます。ISA や PCI カードを広く利用できるだけでなく、パラレル
ポートのように手頃なパフォーマンスをインタフェースを拡張することなく
利用できます。IA32 は入出力空間を分割しているので、ハードウェアの
入出力アドレスの保護を個々の入出力ポートのアドレスのレベルに合わせる
ことで、インタフェースを簡単に取ることができます。

<!--
Linux also makes a good host OS.  The free availability of full source
code, and extensive "hacking" guides, obviously are a tremendous help.
However, Linux also provides good near-real-time scheduling, and there
is even a true real-time version of Linux at <url
url="http://luz.cs.nmt.edu/~rtlinux/">.  Perhaps even more important
is the fact that while providing a full UNIX environment, Linux can
support development tools that were written to run under Microsoft DOS
and/or Windows.  MSDOS programs can execute within a Linux process
using <tt>dosemu</tt> to provide a protected virtual machine that can
literally run MSDOS.  Linux support for Windows 3.xx programs is even
more direct:  free software such as <tt>wine</tt>, <url
url="http://www.linpro.no/wine/">, simulates Windows 3.11 well enough
for most programs to execute correctly and efficiently within a UNIX/X
environment.
-->
Linux は優れたホスト OS でもあります。フリーに利用できるソースコードや
多数の「ハッキング」ガイドがきっと役に立ちます。Linux は、ほぼリアル
タイムに近いスケジューリングができますが、真にリアルタイムに動くバージョン
として <url url="http://www.rtlinux.org/"> もあります。もちろん
それよりも重要なのは、完璧な UNIX 環境を提供するということです。Linux は 
Microsoft の DOS や Windows で動作するように書かれた開発用のツールも
サポートしています。MSDOS のプログラムは <tt>dosemu</tt> を使って、Linux 
のプロセスとして、保護された仮想マシン上で文字通り MSDOS を実行します。
Windows 3.xx に対する Linuxのサポートは、より精巧で、
<!--
<tt>wine</tt>(<url url="http://www.linpro.no/wine/">)のようなフリーソフト
-->
<tt>wine</tt>(<url url="http://wine.dataparty.no/">)のようなフリーソフト
では、ほとんどのプログラムが UNIX の X 環境でかなり正しくかつ効率的に動き
ます。

<!--
The following two sections give examples of attached parallel systems
that I'd like to see supported under Linux....
-->
下記の 2 つのセクションでは、私が Linux でサポートした付加並列システム
の例を見て行きます。

<!-- <sect1>Did You DSP That?  -->
<sect1>DSP してみましたか？
<p>

<!--
There is a thriving market for high-performance DSP (Digital Signal
Processing) processors.  Although these chips were generally designed
to be embedded in application-specific systems, they also make great
attached parallel computers.  Why?
-->
高性能な DSP(Digital Signal Processing)プロセッサの市場は盛況です。
普通これらのチップは特定のアプリケーションを対象とした組込みシステム
用に設計してありますが、素晴らしい付加並列コンピュータでもあります。
どうしてでしょうか？

<itemize>
<!--
<item>Many of them, such as the Texas Instruments (<url
url="http://www.ti.com/">) TMS320 and the Analog Devices (<url
url="http://www.analog.com/">) SHARC DSP families, are designed to
construct parallel machines with little or no "glue" logic.
-->
<item>Texas Instruments(<url url="http://www.ti.com/">)の TMS320 や
	Analog Devices(<url url="http://www.analog.com/">)の SHARC DSP 
	ファミリーのような多くのチップは、「グルー」ロジックが無いもしくは
	ほんのわずかな数で並列マシンを構築できるように設計されている
<p>
【訳註：グルー・ロジック(glue logic)とは、構成部品間のインタフェース
となって両者間を仲立ちする論理回路やプロトコルを意味します】

<!--
<item>They are cheap, especially per MIP or MFLOP.  Including the cost
of basic support logic, it is not unheard of for a DSP processor to be
one tenth the cost of a PC processor with comparable performance.
-->
<item>安価でありながら、1 つで 100 万命令、もしくは 100 万浮動小数点
	演算の性能がある。基本命令ロジックのコストを入れても、DSP プロセッサは
	1/10 のコストで PC 用のプロセッサに匹敵するパフォーマンスを出すことが
	知られている

<!--
<item>They do not use much power nor generate much heat.  This means
that it is possible to have a bunch of these chips powered by a
conventional PC's power supply - and enclosing them in your PC's case
will not turn it into an oven.
-->
<item>電気をくわないかつ発熱も少ない。つまり、これらのチップをまとめ
	使ってもこれまで使っている PC の電源で十分で、PC ケースの中に格納
	しても PC 内がオーブンの中のようにはならない

<!--
<item>There are strange-looking things in most DSP instruction sets
that high-level (e.g., C) compilers are unlikely to use well - for
example, "Bit Reverse Addressing."  Using an attached parallel system,
it is possible to straightforwardly compile and run most code on the
host, while running the most time-consuming few algorithms on the DSPs
as carefully hand-tuned code.
-->
<item>DSP 命令セットのほとんどは、高水準言語用のコンパイラ(例えば、C 用)
	では解釈しにくく使いやすいとは言い難い。例えば、「ビット反転アドレッシ
	ング」がそれに当る。付加並列システムを使うと、大部分のホスト用コード
	を素直にコンパイルして実行し、数は少ないが最も時間を食うアルゴリズム
	を慎重に人間がコードをチューンして DSP で実行する

<!--
<item>These DSP processors are not really designed to run a UNIX-like
OS, and generally are not very good as stand-alone general-purpose
computer processors.  For example, many do not have memory management
hardware.  In other words, they work best when hosted by a more
general-purpose machine...  such as a Linux PC.
-->
<item>これらの DSP プロセッサは、実際は UNIX のような OS 向けに設計して
	あるわけではないし、プロセッサとして単独に汎用的なコンピュータとは言い
	難い。例えば、メモリ管理のためのハードウェアを持たないものが多い。視点
	を変えると、DSP プロセッサはより汎用的なマシンに搭載されてこそ実力を
	発揮できる。Linux PC もその 1 つである
</itemize>

<!--
Although some audio cards and modems include DSP processors that Linux
drivers can access, the big payoff comes from using an attached
parallel system that has four or more DSP processors.
-->
オーディオカードやモデムの中には、Linux のドライバでアクセスできる DSP 
プロセッサを搭載しているものがいくつかありますが、4 つ以上の DSP 
プロセッサ搭載する付加並列システムで効果が大きく見込まれます。

<!--
Because the Texas Instruments TMS320 series, <url
url="http://www.ti.com/sc/docs/dsps/dsphome.htm">, has been very
popular for a long time, and it is trivial to construct a TMS320-based
parallel processor, there are quite a few such systems available.
There are both integer-only and floating-point capable versions of the
TMS320; older designs used a somewhat unusual single-precision
floating-point format, but the new models support IEEE formats.  The
older TMS320C4x (aka, 'C4x) achieves up to 80 MFLOPS using the
TI-specific single-precision floating-point format; in contrast, a
single 'C67x will provide up to 1 GFLOPS single-precision or 420
MFLOPS double-precision for IEEE floating point calculations, using a
VLIW-based chip architecture called VelociTI.  Not only is it easy to
configure a group of these chips as a multiprocessor, but in a single
chip, the 'C8x multiprocessor will provide a 100 MFLOPS IEEE
floating-point RISC master processor along with either two or four
integer slave DSPs.
-->
Texas Instruments の TMS320 シリーズ
<!--
(<url url="http://www.ti.com/sc/docs/dsps/dsphome.htm">)は長い間に渡って人気
-->
(<url url="http://dspvillage.ti.com/docs/dspproducthome.html">)は長い間に
渡って人気があり、簡単に TMS320 ベースで並列システムを構築でき、かなり
多くのシステムがすでに存在しています。
TMS320 には、整数演算専用のものと浮動小数点演算も可能なバージョンが
あります。古い設計のものは、多少変わった単精度浮動小数点フォーマットを
採用していますが、新しいモデルは IEEE フォーマットをサポートしています。
旧 TMS320C4x(別名 'C4x)は、TI 独自の単精度浮動小数点フォーマットを使って、
80 MFLOPS を達成します。それに引き換え 'C67x は、単精度浮動小数点演算で 
1 GFLOPS を達成し、IEEE の浮動小数点を使った倍精度計算では、420 MFLOPAS 
を達成します。これには VelociTI という VLIW ベースのチップ・
アーキテクチャを使っています。これらのチップをマルチプロセッサとして構成
するのは容易であるだけでなく、単独のチップである 'C8x マルチプロセッサは、
IEEE の浮動小数点で 100 MFLOPS を実現します。このプロセッサは、2 もしくは 
4 つの整数演算用の子 DSP をともなう RISC プロセッサです。
<p>
【訳註：VLIW(Very Long Instruction Word 超長命令)は、コンパイラに
よって依存関係のない複数の命令(整数演算や浮動小数点演算、メモリアクセス等)
を 1 つの長い命令として、それを並列に実行する方法です。プロセッサの構造が
単純になる反面、コンパイラが複雑になります。ただし VLIW な プロセッサである 
Transmeta の Crusoe のように、コンパイラをいじることなく VLIW を効率よく
動かそうとする方法も出てきています。詳しくは<url 
url="http://www.transmeta.com/crusoe/technology.html" 
name="Crusoe Technology"> を参照してください】

<!--
The other DSP processor family that has been used in more than a few
attached parallel systems lately is the SHARC (aka, ADSP-2106x) from
Analog Devices <url url="http://www.analog.com/">.  These chips can be
configured as a 6-processor shared memory multiprocessor without
external glue logic, and larger systems also can be configured using
six 4-bit links/chip.  Most of the larger systems seem targeted to
military applications, and are a bit pricey.  However, Integrated
Computing Engines, Inc., <url url="http://www.iced.com/">, makes an
interesting little two-board PCI card set called GreenICE.  This unit
contains an array of 16 SHARC processors, and is capable of delivering
a peak speed of about 1.9 GFLOPS using a single-precision IEEE format.
GreenICE costs less than &dollar;5,000.
-->
この他の DSP プロセッサファミリーで、最近かなりの割合で付加並列システム
に利用されてきているものに SHARC(別名、ADSP-2106x)という Analog Devices
(<url url="http://www.analog.com/">)から出ているものがあります。これらの
チップは、6 つのプロセッサで共有メモリを利用したマルチプロセッサで、
グルー・ロジックを必要としません。これより大規模なシステムも構築でき、
その場合は、6 つの 4 ビットのリンクとチップを利用します。大規模な
システムの大部分は、軍事用のアプリケーションをターゲットにしているようで、
少々割高になっています。しかし、Integrated Computing Engines, Inc.(<url 
url="http://www.iced.com/">)は、GreenICE という小さな PCI カードを 2 枚
セットにしたおもしろい製品を出しています。このユニットは、16 個の SHARC 
プロセッサをアレイ状に配置しており、IEEE フォーマットの単精度計算をピーク
性能で約 1.9 GFLOPS 出せます。
GreenICE は、5,000 ドル以下のコストです。

<!--
In my opinion, attached parallel DSPs really deserve a lot more
attention from the Linux parallel processing community....
-->
私見ですが、付加並列 DSP は、もっと Linux 並列処理のコミュニティ
から注目を浴びてもいいと思っています…。

<!-- <sect1>FPGAs And Reconfigurable Logic Computing -->
<sect1>FPGA と 再構成可能な論理計算回路
<p>

<!--
If parallel processing is all about getting the highest speedup, then
why not build custom hardware?  Well, we all know the answers; it
costs too much, takes too long to develop, becomes useless when we
change the algorithm even slightly, etc.  However, recent advances in
electrically reprogrammable FPGAs (Field Programmable Gate Arrays)
have nullified most of those objections.  Now, the gate density is
high enough so that an entire simple processor can be built within a
single FPGA, and the time to reconfigure (reprogram) an FPGA has also
been dropping to a level where it is reasonable to reconfigure even
when moving from one phase of an algorithm to the next.
-->
並列処理がひたすら速さを求めるなら、カスタム・ハードウェアではなぜ
いけないのでしょうか？ そうですね、それに対する回答は、あまりにも
コストが高いこと、開発するのに時間がかかり過ぎること、またと少しでも
アルゴリズムが変更になると役に立たなくなってしまうこと等があげられ
ます。しかし近年、電気的に再プログラミング可能な FPGA(Field Programmable 
Gate Array)の進歩によって、これらの欠点の大部分が無意味になってきて
います。現状ではゲート密度も高くなっていて、1 つの FPGA だけで単機能の
プロセッサを十分に作成可能です。FPGA の再設定(再プログラミング)も敷居
が低くなってきており、アルゴリズムがある段階から次の段階へ移行するような
場合でも、無理なく再設定できます。

<!--
This stuff is not for the weak of heart:  you'll have to work with
hardware description languages like VHDL for the FPGA configuration, as
well as writing low-level code to interface to programs on the Linux
host system.  However, the cost of FPGAs is low, and especially for
algorithms operating on low-precision integer data (actually, a small
superset of the stuff SWAR is good at), FPGAs can perform complex
operations just about as fast as you can feed them data.  For example,
simple FPGA-based systems have yielded better-than-supercomputer times
for searching gene databases.
-->
これは根気強い人向けの方法です。FPGA を設定するのには、VHDL のような
ハードウェア記述言語を使わざるを得ません。それと同様に Linux ホスト
システム上で、FPGA とのインタフェースのために低レベルなコードを書く必要
があります。しかし FPGA のコストは低く、特に精度が低くてかまわない整数
データの演算に適しています(実際、SWAR の小規模なサブセットとして具合が良い)。
FPGA は、複雑な演算をデータを入力するのと同じくらいの速度で実行できます。
例えば、シンプルな FPGA ベースのシステムでもスーパーコンピュータより高速
に遺伝子データベースの検索を実現できています。

<!--
There are other companies making appropriate FPGA-based hardware, but
the following two companies represent a good sample.
-->
FPGA ベースの専用ハードウェアを作成している企業はいろいろありますが、
素晴らしいサンプルが、下記の 2 つの企業から出ています。

<!--
Virtual Computer Company offers a variety of products using
dynamically reconfigurable SRAM-based Xilinx FPGAs.  Their 8/16 bit
"Virtual ISA Proto Board" <url
url="http://www.vcc.com/products/isa.html"> is less than &dollar;2,000.
-->
Virtual Computer Company は Xilinx の SRAM ベースの FPGA を使って、
動的に再設定可能な 製品をいろいろ出しています。8 ビットと 16 ビットの
「Virtual ISA Proto Board」
<!--
(<url url="http://www.vcc.com/products/isa.html">)は、2,000 ドル以下で購入
-->
(<url url="http://www.vcc.com/prod1.html">)は、2,000 ドル以下で購入できます。

<!--
The Altera ARC-PCI (Altera Reconfigurable Computer, PCI bus), <url
url="http://www.altera.com/html/new/pressrel/pr&lowbar;arc-pci.html">,
is a similar type of card, but uses Altera FPGAs and a PCI bus
interface rather than ISA.
-->
Altera の ARC-PCI(Altera Reconfigurable Computer, PCI bus)
<!--
(<url url="http://www.altera.com/html/new/pressrel/pr&lowbar;arc-pci.html">)
-->
(<url url="http://www.altera.com/cgi-bin/indexhtml.pl">)
は、Virtual ISA Proto Board と同じタイプのカードですが、Altera の FPGA 
と ISA ではなく PCI バスを使っている点が異なります。

<!--
Many of the design tools, hardware description languages, compilers,
routers, mappers, etc., come as object code only that runs under
Windows and/or DOS.  You could simply keep a disk partition with
DOS/Windows on your host PC and reboot whenever you need to use them,
however, many of these software packages may work under Linux using
<tt>dosemu</tt> or Windows emulators like <tt>wine</tt>.
-->
設計ツールやハードウェア記述言語、コンパイラ、ルーター、マッパ等は、
Windows や DOS 上のみで動作するオブジェクト・コードが付いてくる場合
がほとんどです。ホスト PC 上に DOS や Windows のディスク・パーティション
を残しておいて、必要になったらリブートするという手も使えますが、Linux 
上で <tt>dosemu</tt> や <tt>wine</tt> のような Windows のエミュレータ
を使えば、これらのソフトウェアの多くが動作します。
<p>
【訳註：マッパ(mapper)は、回路を FPGA の論理ブロックに分割し、FPGA 
上でその回路を実装する働きを持ちます】

<!-- <sect>Of General Interest -->
<sect>一般的な興味として
<p>

<!--
The material covered in this section applies to all four parallel
processing models for Linux.
-->
このセクションで扱う題材は、Linux において並列処理を行うための 4 つの
モデルを扱います。

<!-- <sect1>Programming Languages And Compilers -->
<sect1>プログラミング言語とコンパイラ
<p>

<!--
I am primarily known as a compiler researcher, so I'd like to be able
to say that there are lots of really great compilers automatically
generating efficient parallel code for Linux systems.  Unfortunately,
the truth is that it is hard to beat the performance obtained by
expressing your parallel program using various explicit communication
and other parallel operations within C code that is compiled by GCC.
-->
私はコンパイラ研究者として世間には名が通っていますので、Linux システムで
自動的に効率的な並列コードを生成する素晴らしいコンパイラがいかに多いか
ということを話したいと思っていますが、現実はそうではありません。コード
の作成者がわざわざ通信方法を指示したり、GCC でコンパイルした C のコード
で書かれた他の並列処理方法を打ち負かすだけのパフォーマンスはなかなか実現
できません。

<!--
The following language/compiler projects represent some of the best
efforts toward producing reasonably efficient code from high-level
languages.  Generally, each is reasonably effective for the kinds of
programming tasks it targets, but none is the powerful general-purpose
language and compiler system that will make you forever stop writing C
programs to compile with GCC...  which is fine.  Use these languages
and compilers as they were intended, and you'll be rewarded with
shorter development times, easier debugging and maintenance, etc.
-->
下記にあげる言語やコンパイラのプロジェクトは、高級言語から効率的な
コードをそれなりに書けるようにする代表的なもののいくつかです。一般的に、
それぞれがターゲットとするタイプのプログラミングに対しては効率的なの
ですが、何でもこなして GCC で C のプログラムをコンパイルする必要が
まったくなくなるような言語やコンパイラは存在しません…あればいいのですが。
これらの言語やコンパイラを目的に応じてつかえば、開発が短期間で済み、
デバッグやメンテナンス等もより簡単になると思います。

<!--
There are plenty of languages and compilers beyond those listed here
(in alphabetical order).  A list of freely available compilers (most
of which have nothing to do with Linux parallel processing) is at <url
url="http://www.idiom.com/free-compilers/">.
-->
ここで(アルファベット順に)リストアップしたもの以外にも、言語やコンパイラ
はたくさんあります。フリーで使えるコンパイラ(Linux に関連ないものが
ほとんどです)は、<url url="http://www.idiom.com/free-compilers/"> に
一覧があります。

<sect2>Fortran 66/77/PCF/90/HPF/95
<p>

<!--
At least in the scientific computing community, there will always be
Fortran.  Of course, now Fortran doesn't mean the same thing it did in
the 1966 ANSI standard.  Basically, Fortran 66 was pretty simple stuff.
Fortran 77 added tons of features, the most noticeable of which were the
improved support for character data and the change of <tt>DO</tt> loop
semantics.  PCF (Parallel Computing Forum) Fortran attempted to add a
variety of parallel processing support features to 77.  Fortran 90 is
a fully-featured modern language, essentially adding C++-like
object-oriented programming features and parallel array syntax to the
77 language.  HPF (High-Performance Fortran, <url
url="http://www.crpc.rice.edu/HPFF/home.html">), which has itself gone
through two versions (HPF-1 and HPF-2), is essentially the enhanced,
standardized, version of what many of us used to know as CM Fortran,
MasPar Fortran, or Fortran D; it extends Fortran 90 with a variety of
parallel processing enhancements, largely focussed on specifying data
layouts.  Finally, Fortran 95 represents a relatively minor
enhancement and refinement of 90.
-->
少なくとも科学計算分野では Fortran が主流です。もちろん現在の Fortran は、
1996 年の ANSI 規格のものとは違います。Fortran 66 はかなり簡素です。
Fortran 77 は機能をたくさん追加しており、その中で最も注目すべき機能として、
キャラクタ・データのサポート、<tt>DO</tt> ループ構文の変更があります。
PCF(Parallel Computing Forum) Fortran は、77 に対して並列処理をサポート
する機能をいろいろと追加しようとしました。Fortran 90 は今時の言語が備えて
いる機能を完備していて、77 に対して C++ のようなオブジェクト指向
プログラミング機能と配列の要素を並列に計算する機能が追加してあります。
HPF(High-Performance Fortran、<url 
url="http://www.crpc.rice.edu/HPFF/home.html">)は、2 つのバージョン(HPF-1 
と HPF-2)を経る過程で、基本的にこれを拡張したり、標準化を行ったりして
いった結果、CM の Fortran や MasPar の Fortran そして Fortran D という
広く使われているバージョンになりました。HPF はデータ配置関係に広く注目して
様々な並列処理の強化をはかった Fortran 90 を拡張したものです。
最終的には、Fortran 95 が Fortran 90 を多少強化、改良したものとして提供
されています。

<!--
What works with C generally can also work with <tt>f2c</tt>,
<tt>g77</tt> (a nice Linux-specific overview is at <url
url="http://linux.uni-regensburg.de/psi&lowbar;linux/gcc/html&lowbar;g77/g77&lowbar;91.html">),
or the commercial Fortran 90/95 products from <url
url="http://extweb.nag.co.uk/nagware/NCNJNKNM.html">.  This is because
all of these compilers eventually come down to the same code-generation
used in the back-end of GCC.
-->
C と連係していくには、<tt>f2c</tt> や <tt>g77</tt>(Linux に特化した概略
が <url url="http://linux.uni-regensburg.de/psi&lowbar;linux/gcc/
html&lowbar;g77/g77&lowbar;91.html"> にあります)もありますし、Fortran 90 
と 95 の製品が <url url="http://extweb.nag.co.uk/nagware/NCNJNKNM.html">
【訳註：リンク切れ】にあります。これらのコンパイラすべては
結局、GCC をバックエンドに使って同じコード生成をしています。

<!--
Commercial Fortran parallelizers that can generate code for SMPs are
available from <url url="http://www.kai.com/"> and <url
url="http://www.psrv.com/vast/vast&lowbar;parallel.html">.  It is not
clear if these compilers will work for SMP Linux, but it should be
possible given that the standard POSIX threads (i.e., LinuxThreads)
work under SMP Linux.
-->
商用の Fortran で、SMP 用に並列化したコード生成に対応するものには、<url 
url="http://www.kai.com/"> や 
<!--
<url url="http://www.psrv.com/vast/vast&lowbar;parallel.html"> があります。
-->
<url url="http://www.psrv.com/vast_parallel.html"> があります。
これらのコンパイラが SMP Linux で動くかどうかははっきりしませんが、
SMP Linux で動く POSIX 規格のスレッド(すなわち LinuxThreads)を生成でき
てもおかしくないと思います。

<!--
The Portland Group, <url url="http://www.pgroup.com/">, has commercial
parallelizing HPF Fortran (and C, C++) compilers that generate code for
SMP Linux; they also have a version targeting clusters using MPI or
PVM.  FORGE/spf/xHPF products at <url url=" http://www.apri.com/">
might also be useful for SMPs or clusters.
-->
Portland Group(<url url="http://www.pgroup.com/">)は、商用で HPF Fortran
(C や C++ も)を並列化するコンパイラがあり、SMP Linux 用のコードを生成
します。別のバージョンとして、MPI や PVM を利用したクラスタをターゲット
にした製品もあります。<url url=" http://www.apri.com/"> で出している 
FORGE や spf、xHPF は、SMP や クラスタで役に立ちそうです。

<!--
Freely available parallelizing Fortrans that might be made to work
with parallel Linux systems include:
-->
下記にあげるものは、フリーに利用できる並列化 Fortran で、並列 Linux 
システムで動作すると思われます。

<itemize>
<!--
<item>ADAPTOR (Automatic DAta Parallelism TranslaTOR, <url
url="http://www.gmd.de/SCAI/lab/adaptor/adaptor&lowbar;home.html">),
which can translate HPF into Fortran 77/90 code with MPI or PVM calls,
but does not mention Linux.
-->
<item>ADAPTOR(Automatic DAta Parallelism TranslaTOR、<url
	url="http://www.gmd.de/SCAI/lab/adaptor/adaptor&lowbar;home.html">)
	は、HPF を MPI や PVM の命令を使って、Fortran 77 もしくは 90 の
	コードに変換する。しかし Linux については触れられていない

<!--
<item>Fx <url url="http://www.cs.cmu.edu/~fx/Fx"> at Carnegie Mellon
targets some workstation clusters, but Linux?
-->
<!--
<item>カーネギ-・メロン大学の Fx(<url url="http://www.cs.cmu.edu/~fx/Fx">) 
-->
<item>カーネギ-・メロン大学の Fx(<url url="http://www.cs.cmu.edu/~fx/">) 
	は、ワークステーションで組んだクラスタをターゲットにしているが、Linux 
	についてはわからない

<!--
<item>HPFC (prototype HPF Compiler, <url
url="http://www.cri.ensmp.fr/~coelho/hpfc.html">) generates Fortran 77
code with PVM calls.  Is it usable on a Linux cluster?
-->
<item>HPFC(prototype HPF Compiler(<url 
	url="http://www.cri.ensmp.fr/~coelho/hpfc.html">))は、PVM を呼び出す
	形式で Fortran 77 のコードを生成する。これは Linux クラスタに使える
	のではないか？

<!--
<item>Can PARADIGM (PARAllelizing compiler for DIstributed-memory
General-purpose Multicomputers, <url
url="http://www.crhc.uiuc.edu/Paradigm/">) be used with Linux?
-->
<item>Can PARADIGM(PARAllelizing compiler for DIstributed-memory
	General-purpose Multicomputers(<url
	url="http://www.crhc.uiuc.edu/Paradigm/">))は、Linux で利用できるか
	わからない

<!--
<item>The Polaris compiler, <url
url="http://ece.www.ecn.purdue.edu/~eigenman/polaris/">, generates
Fortran code for shared memory multiprocessors, and may soon be
retargeted to PAPERS Linux clusters.
-->
<item>Polaris compiler(<url
	url="http://ece.www.ecn.purdue.edu/~eigenman/polaris/">)は、共有
	メモリを使ったマルチプロセッサシステム用に Fortran のコードを生成
	する。恐らくまもなく PAPERS の Linux クラスタが目をつけることに
	なる

<!--
<item>PREPARE, <url
url="http://www.irisa.fr/EXTERNE/projet/pampa/PREPARE/prepare.html">,
targets MPI clusters...  it is not clear if it can generate code to
run on IA32 processors.
-->
<item>PREPARE
	<!--
	(<url url="http://www.irisa.fr/EXTERNE/projet/pampa/PREPARE/prepare.html">) 
	-->
	(<url 
	url="http://www.irisa.fr/paris/pages-perso/Jean-Louis-Pazat/anglais/anterieures/Prepare.html">)
	は、MPI をターゲットにしているが… IA32 プロセッサ用にコードを生成
	できるのかはっきりしない

<!--
<item>Combining ADAPT and ADLIB, shpf (Subset High Performance Fortran
compilation system, <url
url="http://www.ccg.ecs.soton.ac.uk/Projects/shpf/shpf.html">) is
public domain and generates Fortran 90 with MPI calls...  so, if you
have a Fortran 90 compiler under Linux....
-->
<item> ADAPT と ADLIB、shpf(Subset High Performance Fortran compilation 
	system、<url 
	url="http://www.ccg.ecs.soton.ac.uk/Projects/shpf/shpf.html">)は、
	パブリックドメインで MPI を使った Fortran 90 を生成する。Linux で動く 
	Fortran 90 のコンパイラを持っているなら…

<!--
<item>SUIF (Stanford University Intermediate Form, see <url
url="http://suif.stanford.edu/">) has parallelizing compilers for both
C and Fortran.  This is also the focus of the National Compiler
Infrastructure Project...  so, is anybody targeting parallel Linux
systems?
-->
<item>SUIF(Stanford University Intermediate Form(<url 
	url="http://suif.stanford.edu/">))は C と Fortran を並列化するコンパイラ
	である。これは National Compiler Infrastructure プロジェクトの中心である
	ので…並列 Linux にターゲットを当てている人がだれかいないだろうか？
</itemize>

<!--
I'm sure that I have omitted many potentially useful compilers for
various dialects of Fortran, but there are so many that it is difficult
to keep track.  In the future, I would prefer to list only those
compilers known to work with Linux.  Please email comments and/or
corrections to <htmlurl url="mailto:pplinux@ecn.purdue.edu"
name="pplinux@ecn.purdue.edu">.
-->
きっと様々に存在する Fortran 系において、役に立つ可能性があるコンパイラ
の多くを省いてしまっていると思いますが、あまりに数が多くて追いかけるのが
困難です。その内に Linux で動くことがわかっているコンパイラだけを一覧に
したいと思っています。コメントや訂正がありましたら、pplinux@ecn.purdue.edu 
まで電子メールをください。

<sect2>GLU (Granular Lucid)
<p>

<!--
GLU (Granular Lucid) is a very high-level programming system based on
a hybrid programming model that combines intensional (Lucid) and
imperative models.  It supports both PVM and TCP sockets.  Does it run
under Linux?  More information is available at <url
url="http://www.csl.sri.com/GLU.html">.
-->
GLU(Granular Lucid)は、非常に高水準なプログラミングシステムで、データフロー
型(Lucid)と手続き型を兼ね備えたモデルです。PVM や TCP ソケットをサポート
しています。Linux で動くのでしょうか？ さらに情報が欲しいなら <url 
url="http://www.csl.sri.com/GLU.html">【訳註：リンク切れ】をどうぞ。

<!-- <sect2>Jade And SAM -->
<sect2>Jade と SAM
<p>

<!--
Jade is a parallel programming language that extends C to exploit
coarse-grain concurrency in sequential, imperative programs.  It
assumes a distributed shared memory model, which is implemented by SAM
for workstation clusters using PVM.  More information is available at
<url url="http://suif.stanford.edu/~scales/sam.html">.
-->
Jade は並列プログラミング言語で、C を拡張して、粒度が粗い命令プログラム
を並列に連続して実行します。分散共有メモリモデルを前提にしていて、SAM と
いう PVM を使ったワークステーションで組んだクラスタによって実現して
います。さらに情報が欲しい場合は、<url 
url="http://suif.stanford.edu/~scales/sam.html"> にあります。

<!-- <sect2>Mentat And Legion -->
<sect2>Mentat と Legion
<p>

<!--
Mentat is an object-oriented parallel processing system that works
with workstation clusters and has been ported to Linux.  Mentat
Programming Language (MPL) is an object-oriented programming language
based on C++.  The Mentat run-time system uses something vaguely
resembling non-blocking remote procedure calls.  More information is
available at <url url="http://www.cs.virginia.edu/~mentat/">.
-->
Mentat はオブジェクト指向の並列処理システムで、ワークステーションで
組んだクラスタで動きます。Linux にも移植されています。 Mentat の
プログラミング言語(MPL)は、オブジェクト指向プログラミング言語で、C++ 
をベースにしています。Mentat のランタイム・システムは、ノンブロッキング
なリモート・プロシージャ・コール(RPC)とそれとなく似たものを使っています。
さらに詳しい情報は、<url url="http://www.cs.virginia.edu/~mentat/"> に
あります。

<!--
Legion <url url="http://www.cs.virginia.edu/~legion/"> is built on top
on Mentat, providing the appearance of a single virtual machine across
wide-area networked machines.
-->
Legion(<url url="http://www.cs.virginia.edu/~legion/">)は、Mentat 上に
構築され、WAN に接続しているマシン群が 1 台の仮想マシンとして振る舞います。

<!-- <sect2>MPL (MasPar Programming Language) -->
<sect2>MPL(MasPar Programming Language)
<p>

<!--
Not to be confussed with Mentat's MPL, this language was originally
developed as the native parallel C dialect for the MasPar SIMD
supercomputers.  Well, MasPar isn't really in that business any more
(they are now NeoVista Solutions, <url url="http://www.neovista.com">,
a data mining company), but their MPL compiler was built using GCC, so
it is still freely available.  In a joint effort between the
University of Alabama at Huntsville and Purdue University, MasPar's
MPL has been retargeted to generate C code with AFAPI calls (see
section 3.6), and thus runs on both Linux SMPs and clusters.  The
compiler is, however, somewhat buggy...  see <url
url="http://www.math.luc.edu/~laufer/mspls/papers/cohen.ps">.
-->
Mentat の MPL と混同しないようにしてください。もともとこの言語は、MasPar 
の SIMD スーパーコンピュータ用のネイティブな C 処理系のために開発された
ものです。ご存知の通り、MasPar は現在もうこの分野の業務を行っていません
(現在は、NeoVista Solutions(<url url="http://www.neovista.com">)という
名で、データ・マイニング業務を行っています)。しかし MPL コンパイラは GCC 
を使って作成しているので、今でもフリーで利用できます。ハンツビルにある
アラバマ大学とパーデュ大学が共同で行った作業の中で、AFAPI(セクション 3.6 
を参照してください)を呼び出す C のコードを作成するのに、MasPar の MPL 
見直されました。もちろん Linux の SMP、クラスタ両者とも動作します。しかし
コンパイラには若干バグがあります…<url 
url="http://www.math.luc.edu/~laufer/mspls/papers/cohen.ps"> を見て
ください。

<!-- <sect2>PAMS (Parallel Application Management System) -->
<sect2>PAMS(Parallel Application Management System)
<p>

<!--
Myrias is a company selling a software product called PAMS (Parallel
Application Management System).  PAMS provides very simple directives
for virtual shared memory parallel processing.  Networks of Linux
machines are not yet supported.  See <url
url="http://www.myrias.com/"> for more information.
-->
Myrias は PAMS(Parallel Application Management System)というソフトウェア
製品を販売している企業です。PAMS は仮想共有メモリ並列処理に対して非常に
シンプルな命令群を提供しています。ネットワーク上の Linux マシンはまだ
サポートしていません。詳しくは <url url="http://www.myrias.com/"> を見て
ください。

<sect2>Parallaxis-III
<p>

<!--
Parallaxis-III is a structured programming language that extends
Modula-2 with "virtual processors and connections" for data
parallelism (a SIMD model).  The Parallaxis software comprises
compilers for sequential and parallel computer systems, a debugger
(extensions to the gdb and xgbd debugger), and a large variety of
sample algorithms from different areas, especially image processing.
This runs on sequential Linux systems...  an old version supported
various parallel targets, and the new version also will (e.g.,
targeting a PVM cluster).  More information is available at <url
url="http://www.informatik.uni-stuttgart.de/ipvr/bv/p3/p3.html">.
-->
Parallaxis-III は、構造化プログラミング言語で、Modula-2 にデータの並列
化(SIMD モデルの 1 種)を実現するため、「プロセッサと通信の仮想化」を
加えました。Parallaxis のソフトウェアには、逐次、並列処理向けのコンピュータ
システム用のコンパイラとデバッガ(gdb と xgdb を拡張したもの)、画像処理
をはじめとする、様々な分野から集めた膨大なサンプルアルゴリズムが付いて
います。
Linux システムでは逐次処理は動いています…古いバージョンでは、
いろいろな並列化を対象にしていましたが、新しいバージョンもそうなる予定
です(例えば、PVM クラスタをターゲットにするとか)。詳しい情報は、<url
url="http://www.informatik.uni-stuttgart.de/ipvr/bv/p3/p3.html"> を利用
してください。

<sect2>pC++/Sage++
<p>

<!--
pC++/Sage++ is a language extension to C++ that permits data-parallel
style operations using "collections of objects" from some base
"element" class.  It is a preprocessor generating C++ code that can
run under PVM.  Does it run under Linux?  More information is
available at <url url="http://www.extreme.indiana.edu/sage/">.
-->
pC++/Sage++ は、C++ においてデータを並列化するスタイルの操作を
「オブジェクトの収集」を使って、基本となる「基底」クラスのいくつか
から利用できるようにしたものです。プリプロセッサが PVM 配下で動作する 
C++ コードを生成します。Linux で動くのかどうかはわかりません。
詳細は、<url url="http://www.extreme.indiana.edu/sage/"> を見てください。

<sect2>SR (Synchronizing Resources)
<p>

<!--
SR (Synchronizing Resources) is a concurrent programming language in
which resources encapsulate processes and the variables they share;
operations provide the primary mechanism for process interaction. SR
provides a novel integration of the mechanisms for invoking and
servicing operations. Consequently, all of local and remote procedure
call, rendezvous, message passing, dynamic process creation,
multicast, and semaphores are supported. SR also supports shared
global variables and operations.
-->
SR(Synchronizing Resources)は、コンカレント・プログラミング言語で、
リソースが共有するプロセスや変数をカプセル化しています。操作として、
プロセス間の相互作用を扱う主なしくみを提供しています。SR は操作の実行と
それを提供するメカニズムを新たに統合化した上で提供しています。その結果、
次の機能をサポートします。それはローカルでの呼び出し、RPC、ランデブー、
メッセージ通信、動的プロセス生成、マルチキャスト、セマフォです。
<p>
【訳註：ランデブー(rendezvous)とは、異なるタスクの同期を取るため
の手法の 1 つで、Ada で使われています】

<!--
It has been ported to Linux, but it isn't clear what parallelism it
can execute with.  More information is available at <url
url="http://www.cs.arizona.edu/sr/www/index.html">.
-->
Linux にも移植されましたが、どのような並列処理を行なえるのかはっきり
しません。詳細な情報は、<url
url="http://www.cs.arizona.edu/sr/www/index.html"> を見てください。

<sect2>ZPL And IronMan
<p>

<!--
ZPL is an array-based programming language intended to support
engineering and scientific applications.  It generates calls to a
simple message-passing interface called IronMan, and the few functions
which constitute this interface can be easily implemented using nearly
any message-passing system.  However, it is primarily targeted to PVM
and MPI on workstation clusters, and Linux is supported.  More
information is available at <url
url="http://www.cs.washington.edu/research/projects/orca3/zpl/www/">.
-->
ZPL は配列操作を基本としたプログラミング言語で、工学や科学分野の
アプリケーションのサポート目的としています。IronMan という簡潔な
メッセージ通信のインタフェースを呼び出すことで、このインタフェースを
構成する機能のいくつかをほとんど他のメッセージ通信システムと同じような
使い方で簡単に実現できます。しかしそもそもワークステーションで組んだ
クラスタ上での PVM や MPI をターゲットとしていて、Linux もサポート
しています。詳細な情報は、<url 
url="http://www.cs.washington.edu/research/projects/orca3/zpl/www/"> を
見てください。

<!-- <sect1>Performance Issues -->
<sect1>パフォーマンスの問題
<p>

<!--
There are a lot of people who spend a lot of time benchmarking
particular motherboards, network cards, etc., trying to determine
which is the best.  The problem with that approach is that by the time
you've been able to benchmark something, it is no longer the best
available; it even may have been taken off the market and replaced by
a revised model with entirely different properties.
-->
たくさんの方々がどのマザーボードやネットワークカード等がベストなのかを
判断しようと、ベンチマークに入れ込んでいます。この解決方法では、ベンチ
マークを計測できる状態になった時はすでにそれは利用できるベストなものとは
言えなくなってしまっている、という問題があります。市場で見かけなくなって
いたり、まったく違った特性を持つ改良製品に置き換わったりしているかも
しれないのです。

<!--
Buying PC hardware is like buying orange juice.  Usually, it is made
with pretty good stuff no matter what company name is on the label.
Few people know, or care, where the components (or orange juice
concentrate) came from.  That said, there are some hardware
differences that you should pay attention to.  My advice is simply
that you be aware of what you can expect from the hardware under
Linux, and then focus your attention on getting rapid delivery, a good
price, and a reasonable policy for returns.
-->
PC ハードウェアを購入するのはオレンジジュースを買うのと同じようなもの
です。普通はラベルに企業名があろうがなかろうが、それなりにいいものです。
部品(もしくは濃縮オレンジ果汁)がどこのものかを知っていたり、気にしたり
する人はほとんどいません。つまり、本当に注意を払わなければいけないのは、
一部のハードウェアの違いなのです。アドバイスは簡単です。Linux で動かす
ハードウェアに何をやらせるのかを把握することです。把握できたら、できる
だけ速やかに手に入れる方法や納得できる価格、相応な返品条件に注意を向け
てください。

<!--
An excellent overview of the different PC processors is given in <url
url="http://www.pcguide.com/ref/cpu/fam/">; in fact, the whole WWW
site <url url="http://www.pcguide.com/"> is full of good technical
overviews of PC hardware.  It is also useful to know a bit about
performance of specific hardware configurations, and the Linux
Benchmarking HOWTO <url
url="http://sunsite.unc.edu/LDP/HOWTO/Benchmarking-HOWTO.html"> is a
good place to start.
-->
PC プロセッサ間の違いを大枠で把握するのに格好の場所は、<url 
url="http://www.pcguide.com/ref/cpu/fam/"> です。ここは WWW サイト
全体(<url url="http://www.pcguide.com/">)が PC ハードウェアの技術を
一望できる素晴らしいところでもあります。特定のハードウェアの
パフォーマンスを上げるのについて役に立つところもわずかですがあります。
また、Linux Benchmarking HOWTO <url 
url="http://sunsite.unc.edu/LDP/HOWTO/Benchmarking-HOWTO.html"> も
手始めに読むのにいいと思います。

<!--
The Intel IA32 processors have many special registers that can be used
to measure the performance of a running system in exquisite detail.
Intel VTune, <url
url="http://developer.intel.com/design/perftool/vtune/">, uses the
performance registers extensively in a very complete code-tuning
system...  that unfortunately doesn't run under Linux.  A loadable
module device driver, and library routines, for accessing the Pentium
performance registers is available from <url
url="http://www.cs.umd.edu/users/akinlar/driver.html">.  Keep in mind
that these performance registers are different on different IA32
processors; this code works only with Pentium, not with 486, Pentium
Pro, Pentium II, K6, etc.
-->
Intel IA32 プロセッサには、事細かにシステムの動作性能を計測するのに
使用する特別なレジスタがいくつもあります。Intel の VTune
<!--
(<url url="http://developer.intel.com/software/products/vtune/index.htm/">)は、その
-->
(<url url="http://www.intel.co.jp/jp/developer/vtune/index.htm">)は、その
レジスタを使って、完璧と言える程のコードチューニングをマシンにほどこし
ます…が残念ながら Linux では使えません。Pentium のパフォーマンス用の
レジスタにアクセスするためのローダブル・モジュールのデバイス・ドライバ
やライブラリ・ルーチンは、<url 
url="http://www.cs.umd.edu/users/akinlar/driver.html"> にあります。
注意しなければいけないのは、IA32 プロセッサであっても、パフォーマンス
用のレジスタは、同じではないということです。このコードは Pentium で
だけ動き、486 や Pentium、Pentium Pro、Pentium II、K6 等では動きま
せん。
<p>
【訳註：2001.3 現在、VTune は、Pentium、Pentium Pro、Pentium II、
Pentium III、Pentium IV をサポートしています。MMX や SSE の
チューニングも可能です。日本での販売については、<url 
url="http://www.xlsoft.com/jp/products/vtune/perftool.htm" 
name="エクセルソフト"> を参照してください】

<!--
Another comment on performance is appropriate, especially for those
of you who want to build big clusters and put them in small spaces.
At least some modern processors incorporate thermal sensors and
circuits that are used to slow the internal clock rate if operating
temperature gets too high (an attempt to reduce heat output and
improve reliability).  I'm not suggesting that everyone should go buy
a peltier device (heat pump) to cool each CPU, but you should be aware
that high operating temperature does not just shorten component life -
it also can directly reduce system performance.  Do not arrange your
computers in physical configurations that block airflow, trap heat
within confined areas, etc.
-->
大規模なクラスタをわずかなスペースで構築しようとしている方に対しては、
パフォーマンス上でさらに付け加えておきたいことがあります。
少なくとも最近のプロセッサのいくつかは、温度センサーや回路が組み込まれて
いて、動作温度があまりに高くなると内部動作クロックを遅くします(熱の発生
を押さえて、信頼性を向上させる)。CPU を冷却するのにペルチェ・デバイス
(ヒート・ポンプ)を購入するにはお勧めしませんが、高温での動作は部品の
寿命を短くするだけでなく、システムとしてのパフォーマンスにじかに影響を
与えることに注意してください。コンピュータを設置する場合に、空気の流れを
さえぎるような置き方や熱がこもってしまう場所には置かないようにしてください。

<!--
Finally, performance isn't just speed, but also reliability and
availability.  High reliability means that your system almost never
crashes, even when components fail...  which generally requires
special features like redundant power supplies and hot-swap
motherboards.  That usually isn't cheap.  High availability refers to
the concept that your system is available for use nearly all the
time...  the system may crash when components fail, but the system is
quickly repaired and rebooted.  There is a High-Availability HOWTO
that discusses many of the basic issues.  However, especially for
clusters, high availablity can be achieved simply by having a few
spares.  I recommend at least one spare, and prefer to have at least
one spare for every 16 machines in a large cluster.  Discarding faulty
hardware and replacing it with a spare can yield both higher
availability and lower cost than a maintenance contract.
-->
最後になりますが、パフォーマンスとはスピードだけではなく信頼性と
可用性も含みます。高い信頼性があれば、たとえ部品がいかれても決して
システムはクラッシュしません。普通こうするには、冗長化電源やホット
スワップ可能なマザーボードのように特別なしかけを必要とします。これは
安いとは言えません。高い可用性というのは、ほぼいついかなる時でも利用
できるという考えです。たとえ部品が壊れてシステムがクラッシュしても、
システムはあっという間に修復されてリブートします。この件について基本的
な要件の多くを論じている High-Availability HOWTO という資料があります。
しかし特にクラスタにとっては、高い可用性はわずかな予備だけで実現でき
なければいけません。私としては最低限 1 台の予備で、できればクラスタ
当たり 16 台のマシンで予備 1 台というのがいいのでは、と思います。壊れた
ハードウェアを捨てて予備と交換すれば、保守契約に比べて可用性を高くし
コストも低くできます。

<!-- <sect1>Conclusion - It's Out There -->
<sect1>結論―さあ、やりましょう
<p>

<!--
So, is anybody doing parallel processing using Linux?  Yes!
-->
Linux を使って並列処理は誰でもできますか？ もちろん！

<!--
It wasn't very long ago that a lot of people were wondering if the
death of many parallel-processing supercomputer companies meant that
parallel processing was on its way out.  I didn't think it was dead
then (see <url
url="http://dynamo.ecn.purdue.edu/~hankd/Opinions/pardead.html"> for a
fun overview of what I think really happened), and it seems quite
clear now that parallel processing is again on the rise.  Even Intel,
which just recently stopped making parallel supercomputers, is proud
of the parallel processing support in things like MMX and the upcoming
IA64 EPIC (Explicitly Parallel Instruction Computer).
-->
並列処理用スーパーコンピュータを扱う企業が消えて行ってしまったら並列
処理も消えてしまうのか、ということをみんなで心配していたのは、そんな昔
のことではありません。私は消えてしまわなかったと思っています
(<url url="http://dynamo.ecn.purdue.edu/~hankd/Opinions/pardead.html"> 
を見てください。本当に何が起こったのかをおもしろおかしくまとめてみました)。
今やはっきりと並列処理は盛り返してきました。最近になって並列スーパー
コンピュータの製造を中止した Intel でさえ、MMX や次世代の IA64 EPIC
(Explicitly Parallel Instruction Computer)で、自分たちの持っている並列
処理を自慢しています。

<!--
If you search for "Linux" and "parallel" with your favorite search
engine, you'll find quite a few places are involved in parallel
processing using Linux.  In particular, Linux PC clusters seem to be
popping-up everywhere.  The appropriateness of Linux, combined with
the low cost and high performance of PC hardware, have made parallel
processing using Linux a popular approach to supercomputing for both
small, budget-constrained, groups and large, well-funded, national
research laboratories.
-->
「Linux」と「parallel」をお気に入りのサーチ・エンジンで検索してみれば、
かなりたくさんのところで Linux を使った並列処理を見つけられると思います。
特に Linux PC クラスタはあちこちでやりはじめています。Linux がうってつけ
だったのは、PC のハードウェアが低いコストで高い性能を兼ね備えていて、
それで Linux を使った並列処理が、小規模で予算の制約があるグループから
大規模で資金潤沢な国立の研究機関まで広く使われることになったのです。

<!--
Various projects listed elsewhere in this document maintain lists of
"kindred" research sites that have similar parallel Linux
configurations.  However, at <url
url="http://yara.ecn.purdue.edu/~pplinux/Sites/">, there is a
hypertext document intended to provide photographs, descriptions, and
contact information for all the various sites using Linux systems for
parallel processing.  To have information about your site posted there:
-->
このドキュメントのあちこちに記載してある様々なプロジェクトは、自分たちと
似たような並列処理の構成をとっている「同種の」研究サイトの一覧を管理して
います。しかし <url url="http://yara.ecn.purdue.edu/~pplinux/Sites/"> 
では、ハイパーテキスト形式で写真や解説、連絡先を記載したドキュメントを
提供しています。Linux システムを並列処理に使っているすべてのサイトを対象
としているのです。あなた方のサイトの情報をそこに掲載するには、

<itemize>
<!--
<item>You must have a "permanent" parallel Linux site:  an SMP,
cluster of machines, SWAR system, or PC with attached processor, which
is configured to allow users to <em>execute parallel programs under
Linux</em>.  A Linux-based software environment (e.g., PVM, MPI,
AFAPI) that directly supports parallel processing must be installed on
the system.  However, the hardware need not be dedicated to parallel
processing under Linux, and may be used for completely different
purposes when parallel programs are not being run.
-->
<item>「継続して運用できる」並列 Linux サイトを持っていること。SMP でも
	クラスタを組んだマシンでも SWAR なシステムでも、はたまた付加プロセッサ
	がついているマシンでも、ユーザが <em>Linux 配下で並列プログラムを実行
	できる</em>のならかまわない。Linux ベースのソフトウェア環境(例えば PVM や 
	MPI、AFAPI)のように、直接並列処理をサポートしている環境がシステムに
	インストールしてあること。しかしハードウェアが Linux で並列処理にかかり
	きりになっている必要はないし、並列プログラムが動いていない時には、まったく
	別の目的で使用されていてもかまわない

<!--
<item>Request that your site be listed.  Send your site information to
<htmlurl url="mailto:pplinux@ecn.purdue.edu"
name="pplinux@ecn.purdue.edu">.  Please follow the format used in other
entries for your site information.  <em>No site will be listed without
an explicit request from the contact person for that site.</em>
-->
<item>あなたのサイトの掲載を申請すること。サイトの情報を 
	pplinux@ecn.purdue.edu まで送ること。フォーマットにしたがって他の項目にも
	情報を記入すること。<em>サイトを運営している方からのはっきりした要望がない
	限りは掲載されない</em>
</itemize>

<!--
There are 14 clusters in the current listing, but we are aware of at
least several dozen Linux clusters world-wide.  Of course, listing
does not imply any endorsement, etc.; our hope is simply to increase
awareness, research, and collaboration involving parallel processing
using Linux.
-->
現在 14 のクラスタが掲載してあります。しかし世界規模で見れば、少なくとも
数十の Linux クラスタがあることがわかっています。もちろん掲載したからと
いって、何の保証があるわけではありません。ただ Linux を使った並列処理に
関連したことを共有し合って、研究、協力する機会が増えることを望んでいる
だけです。

<sect>日本語版謝辞
<p>
翻訳に当たり下記の JF メンバーの方々にアドバイスを受けました。
この場を借りてお礼申し上げます。

<itemize>
<item>武井さん
<item>早川さん
<item>山崎さん
</itemize>

</article>
