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 $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_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_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 & 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_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_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&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&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&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 *) &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 *) &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_threads library">. --> GCC のインラインのアセンブリ・コードで、ビット操作を使ってロックを かける例は、<url url="ftp://caliban.physics.utoronto.ca/pub/linux/" name="bb_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>) & ~(<em>c</em> - 1)</tt> is equal to <tt>((int) <em>b</em>) & ~(<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>) & ~(<em>c</em> - 1)</tt> が <tt>((int) <em>b</em>) & ~(<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_ME</tt>, to do this: for a test run, compile with <tt>cc -DIDLE_ME=usleep(1); ...</tt>; for a "production" run, compile with <tt>cc -DIDLE_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_ME</tt> のように呼び出しています。テストで動かす 時には、<tt>cc -DIDLE_ME=usleep(1); ...</tt> とコンパイルし、 「製品」として動かす場合には <tt>cc -DIDLE_ME={} ...</tt> と コンパイルしています。<tt>usleep(1)</tt> を呼び出すと、1 ミリ秒間スリープ するようになり、Linux のスケジューラがそのプロセッサ上で別のプロセスを 選べるようになります。プロセスが使用可能なプロセッサの 2 倍以上の数に なると、コードの中で <tt>usleep(1)</tt> を使うと、使わない場合の 10 倍 速くなることも珍しくありません。 <sect1>bb_threads <p> <!-- The bb_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_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_threads library is a good starting point, but is not really suitable for coding large projects. --> bb_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_threads はまだまだ役に立ち ます。小さく、シンプルで、とりあえず最初に Linux のスレッドを使用する には十分です。このソース・コードを読んでも、LinuxThreads のソースを眺めた 時のように威圧感を感じることはないのは確かです。まとめてみると、 bb_threads ライブラリは最初に試してみるのには良いライブラリですが、 正直なところ大きなプロジェクトのコーディングで使用するのには適していません。 <!-- The basic program structure for using the bb_threads library is: --> bb_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_threads_stacksize(<em>b</em>)</tt>. --> <item>それぞれのスレッドで必要になるスタック空間の最大値を見積ること。 大きく見積っても害はない(仮想記憶がそうであるように ;-)。 しかし忘れないで欲しいことは、スタック<em>すべて</em>は単独の仮想アドレス 空間に由来しているため、大きいことはいいことだ、というわけにはいかないこと である。64 K がお試しの大きさである。 <tt>bb_threads_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_MUTEXES</tt>, and initializes lock <em>i</em> by <tt>bb_threads_mutexcreate(<em>i</em>)</tt>. --> <item>次のステップは、必要となるすべてのロックを初期化することである。 ロックのしくみはこのライブラリに組み込まれていて、0 から <tt>MAX_MUTEXES</tt> までの番号が設定でき、<em>i</em> という ロックを初期化するには、<tt>bb_threads_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_threads_newthread(<em>f</em>, &arg)</tt>, where <em>f</em> should be declared something like <tt>void <em>f</em>(void *arg, size_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_threads_newthread(<em>f</em>, &arg)</tt> という感じで指定することになる。ここで <em>f</em> は <tt>void <em>f</em>(void *arg, size_t dummy)</tt> というように宣言して おくべきである。引数が 1 つ以上になる場合は、引数の値で初期化してある 構造体へのポインタを指定してする <!-- <item>Run parallel code, being careful to use <tt>bb_threads_lock(<em>n</em>)</tt> and <tt>bb_threads_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_threads_lock(<em>n</em>)</tt> と <tt>bb_threads_unlock(<em>n</em>)</tt> を慎重に使用する こと。<em>n</em> は整数で、どのロックを使用するかを指定する。この ライブラリでのロックをかけることとロックを解除する操作は、アトミック にバスをロックする命令を使って、ありふれたスピン・ロックで実現している。 この方法では必要以上にメモリ参照の輻輳が生じ、プロセスを公平に実行する ことが保証できない <!-- The demo program packaged with bb_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_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_threads_cleanup(wait(NULL))</tt>. --> <item>あるスレッドが<tt>返り値</tt>を戻す時点で、そのプロセスが実際に 破棄される…しかし、ローカルなスタック・メモリは自動的に解放されない。 正確に言うと Linux はメモリの解放をサポートしておらず、そのメモリ空間は <tt>malloc()</tt> のメモリの空きリストに自動的に戻されない。つまり、親 プロセスは <tt>bb_threads_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_threads threads. --> 下記の C プログラムはセクション 1.3 で論じたアルゴリズムを元に、2 つの bb_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_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_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_threads locks, which are identified by numbers, POSIX locks are declared as variables of type <tt>pthread_mutex_t lock</tt>. Use <tt>pthread_mutex_init(&lock,val)</tt> to initialize each one you will need to use. --> <item>次のステップは、必要となるあらゆるロックを初期化することである。 bb_threads のロックが番号を指定するのとは異なり、 <tt>pthread_mutex_t lock</tt> という変数を宣言するのが POSIX 流である。<tt>pthread_mutex_init(&lock,val)</tt> を使って、必要なそれぞれのスレッドを初期化する <!-- <item>As with bb_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_t</tt> to identify each thread. To create a thread <tt>pthread_t thread</tt> running <tt>f()</tt>, one calls <tt>pthread_create(&thread,NULL,f,&arg)</tt>. --> <item>bb_threads と同様に、新しいスレッドを起こすにはライブラリの ルーチンを呼び出し、何の関数をスレッドとして実行し、その関数に渡される 引数は何かを指定する。しかし、POSIX ではユーザが <tt>pthread_t</tt> という変数を宣言してスレッドを区別する。 スレッドを起こすには、<tt>pthread_t thread</tt> で <tt>f()</tt> を動かすには、<tt>pthread_create(&thread,NULL,f,&arg)</tt> を呼び出す <!-- <item>Run parallel code, being careful to use <tt>pthread_mutex_lock(&lock)</tt> and <tt>pthread_mutex_unlock(&lock)</tt> as appropriate. --> <item>並列コードを動かすには、 <tt>pthread_mutex_lock(&lock)</tt> と <tt>pthread_mutex_unlock(&lock)</tt> 適切なところで 慎重に使用すること <!-- <item>Use <tt>pthread_join(thread,&retval)</tt> to clean-up after each thread. --> <item><tt>pthread_join(thread,&retval)</tt> を使って、スレッド の後始末をすること <!-- <item>Use <tt>-D_REENTRANT</tt> when compiling your C code. --> <item>C のコードをコンパイルする時には、<tt>-D_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_threads example, two threads execute in parallel. --> 次にあげるのは、円周率の計算を LinuxThreads を使って並列に行う例です。 セクション 1.3 で使ったアルゴリズムが使用されていて、bb_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_PRIVATE, <em>b</em>, (IPC_CREAT | 0666))</tt>. --> <item>普通、それぞれの並列処理のプログラムを自分の共有メモリのセグメント を使って動かしたいかと思われるので、その場合は <tt>shmget()</tt> を呼んで必要な大きさのセグメントを新しく作成する。またこのシステム コールは、既存の共有メモリの ID を得るためにも使われる。どちらの場合も 返り値は共有メモリの ID か、エラーを表す -1 である。例えば、<em>b</em> バイトの大きさの共有メモリを作るなら、<tt>shmid = shmget(IPC_PRIVATE, <em>b</em>, (IPC_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>-></tt><em>x</em>. --> 注意すべき点は、共有メモリセグメントに置く共有する static 変数はすべて <tt>構造体</tt>のメンバーにして宣言することで確保できる、ということだ。 そして <em>shmptr</em> をその構造体のポインタにする。このテクニックを 使うと、<em>x</em> は <em>shmptr</em><tt>-></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_RMID, 0)</tt>. --> <item>この共有メモリのセグメントを解放しなければならない時は、この セグメントにアクセスする最後のプロセスが終了するかデタッチする場合である。 <tt>shmctl()</tt> を呼び出して、初期状態に設定する必要がある。コードは、 <tt>shmctl(shmid, IPC_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 $5 to over $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 $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 $2,400; adding a Myrinet instead brings the cost to about $3,800. If you have about $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., $20,000 could buy 8 machines connected by both Fast Ethernet and TTL_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_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>$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>$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>$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_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_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>$100</em> (hubless, <em>$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 $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 $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>$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>$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>$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>$3,500</em> (serial is <em>$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>$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>$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_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_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>> $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>$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>> $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>$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_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>$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_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_PAPERS」はこれとは対照的で、パーデュ大学以外でも簡単に 構築できるように設計してあります。とてもシンプルかつパブリック・ドメイン な設計で、一般的な TTL のロジックを使って構築しています。この設計は商用でも 利用されています(<url url="http://chelsea.ios.com:80/~hgdietz/sbm4.html">) 【訳註:リンク切れ】 <!-- Unlike the custom hardware designs from other universities, TTL_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_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_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_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>$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>$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_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_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_DGRAM) --> <sect3>UDP プロトコル(SOCK_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_STREAM) --> <sect3>TCP プロトコル(SOCK_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_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_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_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_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", &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, &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<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_Win_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_Win_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_rpc/README_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_rpc/README_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_welcome.html">. --> 商用版もあり、CODINE 4.1.1(COmputing in DIstributed Network Environments) といいます。<url url="http://www.genias.de/genias_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 & 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 & 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>&</tt> operator) performs a bitwise and no matter what the field sizes are. A simple bitwise and of the above registers yields: --> どのフィールドがゼロでないかをテストするのは、すべてに対してビット論理 演算をする点でポリモフィックな操作と言えます。例えば、通常のビット論理 積演算(C の <tt>&</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 $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>& 0x7f7f7f7f</tt> as the last step. --> しかし、追加したビット論理和演算は、最後の操作である <tt>& 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 & 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 $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 $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_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_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_linux/gcc/html_g77/g77_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_linux/gcc/ html_g77/g77_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_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_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_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_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>