スレッド - みる会図書館


検索対象: トランジスタ技術 2016年3月号
25件見つかりました。

1. トランジスタ技術 2016年3月号

スレッドの切り替えはプロセスに分けるよりも手間が少なくて済み , 切り替え時間が短 いことから , より細かく時間を分割できますし , マルチコアの CPU の場合には各スレッ ドを異なるコアで処理することもできるため , システム全体の性能向上にも役立ちます . 例えば , あるアプリケーションの中で , ( 1 ) スイッチを読んで LED に出力する処理 ( 2 ) シリアル・ポート経由で送られてきたコマンドを解釈・実行して結果をシリア ル・ポート経由で返す処理 といった二つの処理関数があった場合 , これらを同時に動かすには main ( ) で両者を交互 に呼び出せば良さそうに思えます . ところが , ( 2 ) の処理に時間がかかると ( 1 ) の処理が滞 ってしまい , 反応が鈍くなってしまいます . このような場合に ( 1 ) と ( 2 ) を別スレッドにして動かしておけば , 反応が鈍くなるという こともなく動作するわけです . また , スレッドでは互いに密に結合している分 , 同時に同じ変数領域にアクセスしたり , 同じ関数を呼び出すときなどに両者が競合しないようにする ( 排他処理と呼びます ) 仕組み が必要になってきます . WiringPi ではこのためにミューテックスという , 同時に一つの スレッドだけがアクセス権を得る仕組みが用意されています . ・スレッド関連 A 曰 スレッド関連の API の一覧を表 5 に示します . スレッド関連 API には , ・スレッド作成用の API ・ミューテックスの操作用 API があります . スレッド作成用 API ・ int piThreadCreate (void* (*function) (void*) ) func ⅱ on ( ) で指定された関数を別スレッドとして動作させます . 書式などを図 12 に示し ます . スレッドとして動作する側の関数は通常の関数定義とは異なり , PI_THREAD マ クロを使います . 例えば myThread ( ) という関数をスレッド用として定義したいときは , P 工 THREAD (myThread) ・・・ ( 処理の実体 ) 表 5 スレッド関連 API 種別 関数名 int piThreadCreate (void* (*function) ( vo 土 d つ ) void piLock(int keyNum) 関係 スレッド 内容 スレッドを作成 ( 関数本体は PI_ スを開放 keyNum(0—3) 番のミューテック ミューテックス番号を指定 : 0 ~ 3 ) ミューテックスを取得 ( keyNum で THREAD (function) で定義 ) 92 void piUn10ck(int keyNum) ンタ技術 2016 年 3 月号別冊付録

2. トランジスタ技術 2016年3月号

ンの」 場合には図 18 のような計画が考えられます . プロセス 1 スレッド 1 CPU コア 1 シングル・プロセスシングル・スレッド CPU への割り当て (1) 1 プロセスを 4 スレッドに分散 = 合計 4 スレッド (a) 通常のプログラム ( シングル・プロセス , シングル・スレッド ) ( 2 ) 4 プロセスを 1 スレッドずつに分散 = 合計 4 ス スレッド 1 ℃ PU コア ( 3 ) 2 プロセスを 2 スレッドずつに分散 = 合計 4 ス スレッド 2 CPU コア 2 スレッド 3 を CPU コア 3 。 プロセスとスレッドの関係を理解していないと , ス スレッド 4 ℃ PU コア 4 レッド分散とプロセス分散を混同して性能劣化を招く シングル・プロセス複数のスレッドを生成 CPU への割り当て ばかりでなく , プログラムが正しく処理されないこと (b) マルチスレッド も発生します . プロセスは人が識別する最小単位と考 プロセス 1 スレッド 1 CPU コア・ えることもでき , スレッドは OS が識別する最小単位 プロセス 2 スレッド 2 C PU コア 2 、 ともいえます . プロセス 3 スレッド 3 OP リコア 3. プロセス 4 U コア 4 スレッド 4 ・並列化最大の壁・・・計算には順序がある 複数のプロセスを生成シングル・スレッド CPU への割り当て 並列化には , データの時間依存性 ( データ従属性と (c) マルチプロセス も呼ぶ ) という最大の障壁があります . 家を建てると き , 土台となる基礎工事が終わらなければ屋根の工事 スレッド 1 CPU コア 1 プロセス 1 はできません . 基礎工事と屋根の工事には順序があり スレッド 2 CPU コア 2 ます . これが時間依存性です . スレッド 3 ICPU コア 3 データに時間の依存性があると並列処理できません . プロセス 2 スレ、ソド 4 ら℃ PU コア 4 例えば , 四則演算では加減算より , 乗除算を優先する 複数のプロセスを生成複数のスレッドを生成 CPU への割り当て ルールがあり , これを誤ると計算を間違えます . (d) マルチスレッドとマルチプロセスの併用 「正」 1 + 2 x 3 = 7 図 18 4 コアにプロセスとスレッドを割り当てる方法 「誤」 1 + 2 x 3 = 9 よる実行の同期が必要になります . これもデータの時 きちんとプログラムすればちゃんと計算できますが , 間依存性の一種です . 1 + 2 x 3 の通りにプログラムを書くと , コンピュータ 並列化の性能は直線的に伸びない・・アムダールの法則 はこの通りに計算して間違えます . このように , 並列化によって余計な処理が生じるた 並列化する場合は処理を分割しなければなりません . め , 並列化は必ずしも直線的に性能が伸びないことが しかし , 図 19 のように計算の優先順位は決まってい 知られています . これを「アムダールの法則」と呼び ます . その場合は並列化できません . ます . データの時間依存性で有名な例は , 前の値が決まら ないと次の値が決まらない場合です . 繰り返し処理で よく使う 土 = 土十 1 ー という演算が該当します . 前の変数 i に 1 を加えて , 次の変数 i に代入します . 前の値が決まらないと次が 決まりません . こうした記述があると並列化できす , 並列コンピューティングを生かせません ( 最近はこの ような場合 , 縮約 reduction という特別な手法で並列 化できる ). 時間依存性には , 前方依存と後方依存が ありますが , いずれにしても並列化できません . データを共有している場合も並列化できない 目的の計算 1 十 2 X 3 = 図 20 のように並列処理で共有しているデータ ( メモ 2X3=A 処理 2 リ ) への同時にアクセスする競合状態が生じる場合も , 1 十 A=B 並列化できません . 計算を誤ってしまいます . ロック (a) 処理を分ける (b) 処理の順序 やセマフォなどの排他制御が必要になり , 処理待ちに 図 19 四則演算の順序を間違えると計算結果がまるで違う ンタ技術 2016 年 3 月号 ロ レッド プロセス 1 1 E : 全体の性能倍率 ( 単体比 ) r : 単体の並列効率 れ : 並列数 図 21 に示すように , 並列数を増やしてもいずれ , 処理に順序があると 同時に実行できない 処理 1 時間 121

3. トランジスタ技術 2016年3月号

・ソフトウェア PWM とソフトウェア TON E の基本動作 ソフトウェア PWM は PWM ( パルス幅変調 ) の名のとおり 1 周期のサイクル数と , '1' 出 力の期間を決めます . 一方 , ソフトウェア TONE はデューティ比を 50 % ('I' 期間と℃ ' 期間の長さが同じ ) に固定で , 指定した周波数の方形波を出力するものです . TONE の名 のとおり , アラーム音のような音を出力するのに向いています . ・ソフトウェア PWM とソフトウェア TONE のしくみ ソフトウェア PWM とソフトウェア TONE はいずれも Linux の持つ「スレッド」機能を 利用しています . このことは実際の利用にあたってはほとんど気にする必要はありません こで簡単に説明しておきます . 図 9 のようにそれぞれの出力ごとに別々のスレッドを割り付けることで , 同時にいくつ ものポートから PWM やトーン波形を出力できるようにしているのです . 図 10 はソフトウェア PWM を三つとソフトウェア TONE 二つの計 5 個を同時に動かし たときの状態を見たものです . ファイル名が「 softPwmTone 」で , ps ( プロセス・ステー タス ) コマンドで調べると 1603 番として動作しています . そこで , さらに H オプションを つけてスレッドも表示するようにしてみると , 図のように五つのスレッドが作成されてい ることがわかります . ②ぐ 1 を期間値 ) X18 us だけⅡ an 。 sleep() を使ってウェイト ( 1 ) 田 " ( '1' ) を出力 この定周期動作には L ⅲ ux のシステムコールの一つである , nanosleep ( ) を利用しています . ソフトウェア PWM/ ソフトウェア TONE の各スレッドは 100 us 毎に動作しています . ③ "L" ( ℃ ' ) を出力 main() ソフトウェア PWM スレ、ソド PWM 出力 ソフトウェア PWM スレッド PWM 出力 ソフトウェア PWM スレッド PWM 出力 ソフトウェア TONE スレッド TONE 出力 ソフトウェア 丁 ONE スレッド TONE 出力 図 9 76 ソフトウェア PWM / ソフトウェア TONE とスレッドの考え方 トランシスタ技術 2016 年 3 月号別冊付録

4. トランジスタ技術 2016年3月号

リスト 3 動作中の CPU クロックを確認するシェル・スクリプト # ! /bin/sh 1 0 5 2 スレッド数 図 9 分散するスレッド数が実行時間に効いている スバコンとしての測定を行う CPU の us ( ユーザ使用率 ) が 100 % であり , 4 コアす べて使用していることを確認できます . スレッド数の ・スバコン用べンチマーク・ソフトを用意する 制御は環境変数を設定するだけです . べンチマーク・ソフト HPCG をインストールし , $ export=OMP NUM_THREADS=2 ーコー OpenMP によるマルチスレッド化の効果を測定します . $./a . out ロ HPCG は従来使われてきたべンチマーク・ソフト LINPACK の後継にあたり , 今後の性能指標に使われ 今度はユーザ使用率が 50 % になり , 2 コアだけ使用 る予定です . 「京」の HPCG 指標が公開されているため , していることを確認できます . ・パイ 2 との性能比較ができます ( p. 112 ラズベリ 表 1 参照 ). ・実行時間の計測 図 10 のように HPCG を用意します . make コマンド t ime コマンドを使うと , 図 8 のように実行時間を を実行すると , build/bin/xhpcg が生成されます . 測定できます . スレッド数の違いが実行時間の違いに現れます . ・結果・・・べンチマーク・ソフトウェア HPCG が real は実時間 , user は CPU のユーザ使用時間 , sys は OpenMP に向いていない システム使用時間です . ューザ時間が実時間を超えて 図 1 1 のようにスレッド数を環境変数で指定してお いるのは , スレッド分散されているためです . き , xhpcg を実行します . スレッド数を変えて実行時間を測定した結果を図 9 すると , HPCG-*. yaml ファイルが生成されます . に示します . OpenMP によるスレッド分散は効果的 約 20 分かかります . 最後の HPCG result 行が実行結 なようです . 実行時間がスレッド数 4 でスレッド数 1 果です . のほばレ 4 に短縮します . ラズベリー・パイ 2 の動作周波数は CPU 負荷に応 H PC G ェ e s u 1 t 土 s ▽ A 工 D w 土 t h a じて上下する GFLOP/S rating of: 0.0577359 BCM2836 の仕様上のクロック上限は 800MHz です 図 12 にスレッド分散によるべンチマーク結果を示 ( 当初 Br 。 adcom は仕様を公開していましたが現在は します . 結論としては , べンチマーク・ソフト HPCG 削除されています ) . ラズベリー・パイ 2 としては下 はスレッド分散に向いていません . 限値が 600MHz で , 上限が少しオーバークロックの 1 スレッドでは , 図 13 のように CPU 使用率が 25 % ( 1 900 MHz に設定しています . 負荷が低いときは コア分 ) に張り付いています . ところか図 14 に示すよ 600MHz で動作し , 消費電力を削減しています . うに , 2 スレッドでは 50 % に張り付かず , 25 % と行 現在の動作クロック値は以下のコマンドで知ること き来しています . つまり 2 コアをフルに使い切ってい ができます . 極ンシスタ技術 2016 年 3 月号 スレッド数を 2 に指定 $ export = OMP NUM THREADS=2 』 . /a . out $ time a. out の実行時間を表示する 0m9 . 609s 結果が表示 0m19 . 2 0 0 s u S e r される 0m0 . 0 0 0 s SYS 図 8 実行時間を Linux の time コマンドで調べてみる for 土 in 、 seq 10 、 CPU の動作周波数を取得する記述 do cat /sys/devices/system/cpu /cpuO/cpufreq/sca1ing—cur—freq sleep 1 done 25 20 $ vcgencmd measure clock frequency(45)=600000000 >CPU クロックの確認 動作中の CPU クロックを確認するシェル・スクリ プトをリスト 3 に示します . 負荷のかかるプログラム を実行すると 600 MHz から 900 MHz に変更される様 子を確認できます . なお , 本実験では基本性能を確認 するため , ラズベリー・パイ 2 をオーバークロックし ません . スレッド数を増やすと 処理時間は短くなる 1 5 4 3 1 ユ 28

5. トランジスタ技術 2016年3月号

スプーンを手にした人だけが料理 ( 共通リソース ) にアクセスできる ーテックス 図 14 リソースとミュ ァープル ( カーネル空間 ) できる人は 1 人だけ スプーン ( ミューテックス ) を手に ・サンプル・プログラム・・・スレッド作成と排他処理 かを keyNum で指定します . WiringPi では四つのミューテックスが用意されており , どのミューテックスを使うの サンプルを動作させたときの波形が図 15 と図 16 です . スレッドのサンプルは予定どお LED を 2 開 ms 点灯させる動作を繰り返します . こちらは thread ー alt. c としました . を開放すると , 取得待ちだったスレッド側がミューテックスを取得し , 今度は 1 番ピンの した後開放します . メイン側が 500 ms0 番ピンの LED を点灯させた後 , ミューテックス でミューテックスの取り合いを行い , ミューテックスを取得した側が LED を点灯 / 消灯 リスト 5 はミューテックスによる排他処理を行わせるサンプルです . スレッドとメイン thread. c としました . 態を反転し , メイン側では 500 ms 周期で 0 番ピンの状態を反転させます . ファイル名は リスト 4 はスレッドを利用したサンプルで , スレッド側では 200 ms 周期で 1 番ピンの状 リスト 4 スレッドのサンプル・プログラム #include く stdio. h> #include く wiringPi. h> PI_THREAD (Thread_LED) de1ay(200) ー digita1Write ( 1 ′ led); led ^ = 1 ー while(l) { unsigned char led; スレッド (200ms 周期 で 1 番ピンの LED を ON/ OFF) pinMode ( 0 ′ OUTPUT); pinMode (I,OUTPUT) ー / / 0 番ビン ( D 用 ) を出力に設定 ノ / 。 1 番ピン ( EP 用 ) を出力に設定 sts = piThreadCreate (Thread—LED) ー / / スレッド作成 土 f ( s ts ! = 0 ) { printf( ℃ an't Create Thread. Yイレ return ( 1 ) ー led = 0 ー while(l) { led ^ = 1 ー digitaIWrite (0 ′ led); delay ( 500 房 intmain(intargc' char *argv[]) int sts; unsigned char led; wiringPiSetup ( ) ー 94 ンタ技術 2016 年 3 月号 500ms 周期で 0 番ピンの LED を点滅 別冊付録

6. トランジスタ技術 2016年3月号

第 7 章 タイミング管理関数 #include く wiringPi . h> int piThreadCreate (void* (*function) (void*) ) 囲カ : 作成成功 : 0 。筰成失敗 : 0 以外 入力 : ・ function スレッド関数名 (a) スレッド作成の書式 ・ } / / スレッド処理関数 ( 関数名 : myTh 「 ead) ツノⅷ而 gPi の初期化 〃 myTh 「 ead() を別スレッドとして実行 (b) 使用例 PI_THREAD (myThread) { ・ wiringPiSetup ( ) ー sts=piThreadCreate (myThread) ー 図 12 スレッド作成 API というように記述し , これを , piThreadCreate (myThread) ) として , 別スレッドとして動作させます . ューテックスの操作用 API ・ vo 土 d piLock (int keyNum) ・ vo 土 d piUnlock(int keyNum) keyNum で指定された番号 ( 0 ~ 3 ) のミューテックスのロックとロック解除を行います , 書式は図 13 に示します . ミューテックスは一度に 1 スレッドしか取得できないアクセス権のようなものです . 図 14 のように , バイキング形式で , テープルには料理が置かれており , そこにスプーンと いうミューテックスが置かれている状態とします . このとき , スプーンを手にした人だけ がその料理 ( リソース ) にアクセスして手元の皿に移すことができるわけです . 同時に複数 の人がスプーンを取ろうとしても , スプーンを手にできる人は 1 人だけで , 他の人はスプ ーンが戻されるまで待たされます . このようにして , リソースに対するアクセス権を管理して , 同時に複数の人 ( スレッド ) が同じリソースにアクセスしないようにするわけです . piLock ( ) はミューテックスのロック , すなわちスプーンの取得に相当し , piUnlock() は ミューテックスのアンロック ( ロック解除 ) , すなわちスプーンを返すことに相当します . #include <wiringPi . h> VOid piLock (int keyNum) void piUnIock (int keyNum) カ : なし 入力 : ・ keyNum 〃ミゴーテッツス取得 〃ミューテックス開放 ミューテックス番号 ( 0 ~ 3 ) (a) ミューテックス・ロック / アンロックの書式 ノ / ミューテックス # 0 を取得 〃排他処理 ノ / ミューテックス # 0 を開放 (b) 使用例 piLock ( 0 房 piUn10ck(0) ー 図 13 ミューテックス・ロック / アンロック API ンタ技術 2016 年 3 月号 別冊付録 93

7. トランジスタ技術 2016年3月号

コンピュ ータ CPU クラスタ コンピュータ CPU コア f コア コア 3 コア 4 CPU CPU . ゴア 2 コア↑ コア 3 。コア 4 コア コア 2 コア 3 コア 4 コア 2 コア生 コア 1 コア 3 図 12 複数の CPU をつなげて処理を分散する・・・並列コンピュー ティングの型その 2 マルチ CPU ・分類 2 ・・・複数の CPU を使う 1 個の CPU で足りないなら複数の CPU で補えばよ いという発想です . 複数の CPU ( マルチ CPU ) を搭載 したコンピュータで実現します . 図 12 のように , 複数の CPU プロセスを分散し , 同 図 13 複数のコンピュータを接続して処理を分散する・・・並列コ 時に動かすことができます . ソフトウェアは MPI ンピューティングの型その 3 クラスタ・システム (Message passing lnterface) を使って開発します . PVM (ParalIeI VirtuaI Machine) という方法もありま すが , 現在の主流は MPI です . スレッド分散も併用 ■処理を分散するプログラムのつくり できます . ・プログラムの実行単位で処理を分散するときの概 ・分類 3 ・・・分散コンピューティング 念・・・「プロセス」と「スレッド」 1 台のコンピュータで足りないなら複数のコンピュ 処理を CPU コアに分散させるには , プログラムを そのように記述しておかなければなりません . そのよ ータで補えばよいという発想です . 図 13 のように 複数のコンピュータ ( これをノードという ) を連結し , うなプログラムを組み立てるときには , 「プロセス」 あたかも 1 台のコンピュータのように振る舞います . と「スレッド」という概念を考えます . 以下では , プ コンピュータ間は高速の通信網で結びます . これを ロセスとスレッドを単純化して解説します . インターコネクトと呼びます . 一般的にこのしくみを プロセスとは「プログラムの実行単位」です . 二つ 持つコンピュータをクラスタ・システムと呼びます . のプログラムを実行すれば二つのプロセスが起動しま す ( 図 14 ). 一方で , スレッドとはプロセスを下請け プロセスの実行は特定のノードに限定する理由がな いため , どのノードで実行されてもかまいません . も する「 CPU コアの実行単位」です ( 図 15 ). プロセス ちろん , 負荷の高いノードにプロセスを集中しないよ を親会社とするなら , スレッドは一つ以上の子会社と うに , 負荷を分散させる必要があります . いえます . マルチコアを持っ CPU が登場した当時に スレッドによる , プロセスによる , コンピュータに 考え出されたやり方です . よる分散がある大規模な分散コンピューティングであ 昔の CPU は 1 コアで , 単純に一つのプロセスが るスーパーコンピュータは , すべての技術を包含して つの CPU コアで動作していました . OS の構造も単純 でした . ところが , マルチコアの CPU が登場すると , います . 複数のコアを有効活用する必要がでてきました . そこ 2 個のコアに処理を分割 マルチコア CPU CPU コア 2 CPU コア 1 スレッド 1 スレッド 2 CPU コア 3 CPU コア 4 コンピュータ CPU ゴア 3 ゴア 4 CPU コア 3 コア 4 プログラム プログラム プログラム プログラム CPU CPU プロセス 2 (a) プログラムを 2 本実行 (b) プログラムを 1 本実行 図 14 プロセスはプログラムの実行単位 トランシスタ技術 2016 年 3 月号 スレッドは CPU コアの実行単位 図 15 119

8. トランジスタ技術 2016年3月号

#include <50ftTone . h> を忘れずに入れてください . それぞれの API について説明します . ソフトウェア PWM スレッド作成 ・ int softPwmCreate (int pin ′ int 土 n 土 t 土 a 工▽ alue ′ int pwmRange) ソフトウェア PWM 出力用のスレッドを作成します . 書式は図 1 1 のようになります . 出力先は pin で指定し , PWM の 1 周期は (pwmRange x 100 (s) になります . initialValue は '1' 期間の初期値です . この値は softPwmWrite() で変更できます . in ⅲ a Ⅳ alue が 0 のときは出力が℃ ' のままになり , pwmRange 以上のときは '1' のまま になります . 指定したピンは API 内部で OUTPUT モードに設定され , ℃ ' に初期化され ます . ソフトウェア PWM / ソフトウェア TONE のスレッドは開始時に piHiPri ( 50 ) として , 優 先度を 50 にしています ( piHiPri については第 7 章参照 ). ューザが作成したスレッドはデ フォルトでは優先度 0 と最も低くなっていますので , ソフトウェア PWM / TONE 機能が優 先されますが , 優先度を変更する場合には 50 未満にして , PWM や TONE の動作に影響 ソフトウェア TONE 出力用のスレッドを作成します . 書式は図 13 のようになります . ・ int softToneCreate (int pin) ソフトウェア TONE 出力スレッド作成 12 のようになります . pin で指定したソフトウェア PWM 出力の '1' 期間を value 値に変更します . 書式は図 ・ v 〇土 d softPwmWrite (int pin ′ int value) ソフトウェア PWM '1' 期間設定 を与えないようにした方がよいでしよう . 出力先は pin で指定します . Create した後の出力は℃ ' になっていて , 出力周波数も 0Hz ( 変 (a) ソフトウェア PWM スレッド作成の書式 ・ pwmRange PWM の周期カウント数 ( 1 カウント : 100 灯 s ) ~ ・ initialvalue 1 ' 期間の初期値 ピン番号 入力、・ p 土 出力 - : ズレッド作成ステータス ( 0 : 成功 0 以外 ! ュラー ) int softpwmcreate (int pin ′ int 土 n 土セ土 a1Va1ue ′ int pwmRange) #include く softpwm . h> #include く wiringPi . h> ・▽ 0 土 d softToneWrite (int pin ′ int freq) ソフトウェア TO N E 周波数設定 ソフトウェア PWM と同様 , スレッドの優先度は 50 に設定されています . 化しない ) になっています . wiringPiSetup ( ) ー softPwmCreate(0 ′ 30 ′ 100房 / ノ 0 番ピンを PWM 出力 . 一周期が 100 サイクルい 00X 100 us = 1 Oms) 〃、 1 ' 期間は 30 サイクル ( 30X 1004S =ams) (b) 使用例 図 1 1 78 ソフトウェア PWM スレッド作成 API ンシスタ技術 2016 年 3 月号別冊付録

9. トランジスタ技術 2016年3月号

CPU2 CPU2 アクセスに問題なし アクセスできない (a) 参照先のメモリ領域 (b) 参照先のメモリ領域 が同じ が異なる 2 4 図 20 異なる CPU から同じデータヘアクセスする競合が起きる 並列数 場合は並列化できない 図 21 並列化で有名なアムダールの法則 うようになりました . 以前は POSIX にのっとり , ス 性能は飽和します . レッド化するプログラムを手動で記述しなければなり ませんでした . これは非常に大変な作業でした . ・ループ処理をうまく分散させる コンパイラはループ箇所を見つけると可能なら自動 プログラムでもっとも時間を費やすのは繰り返し処 的にスレッド化します . コンパイラが時間の依存性を 理です . プログラムの局所に処理時間を費やすため , これを「プログラムの局所性原理」と呼びます . 見つけるとスレッド化しません . プログラマはオプションを指定するだけでコンパイ 単一の CPU コアを考えたとき , これには , 高速で ラの最適化と自動スレッド化の恩恵を受けることがで 小さなキャッシュ・メモリが有効です . そして , 並列 きます . 自分で最適なコードを記述する必要もなけれ 処理は , プログラムの中でもっとも時間のかかる繰り ば , スレッドのプログラムも記述する必要もありません . 返し処理を分散すると , 処理能力を大幅に向上できる という考え方です . いつほう , 膨大なデータがあると ・プログラムに埋め込むと並列化をアシストしてく 繰り返し処理も膨大になります . 計算の処理速度を上 れる 2 大関数ライブラリ (OpenMP と MPI) げるには , いかに繰り返し処理を並列化できるかにか コンパイラまかせで並列化することもできますが , かっています . OpenMP や MPI という , 並列化をアシストしてくれ ■並列化で使う定番ソフトウェア る関数ライプラリもあります . OpenMP はスレッド分散用で , ノード内でのみ並 ・今どきのコンバイラなら並列化はサッとできる 列処理できます . スレッド分散はノード間で行うこと 最近のコンパイラは賢くなり , 不要と思われるコー はできません . 一方 , MPI はプロセス分散用で , ノ ドを削除したり , コードを命令数の少ない方法に変更 ード内のみに限らず , ノード間でも行うことができま したりして , コード・サイズを小さくし , 実行速度を す . MPI の方が適用範囲が広いとも言えます . スレ 上げるコードの最適化を行います . 一般には , 最適化 ッド分散とプロセス分散の違いを図 22 に示します . レベルを 0 , 1 , 2 , 3 などと指定できます . 一般的に スレッド分散用ライブラリ OpenMP 数字が大きいほど最適化が行われます . OpenMP はコンパイラ gcc の機能の一部となってい サイズを小さくすることが必ずしも実行速度の短縮 ます . 明示的に並列化を行う場合 , プログラム中に につながらないことがあるため , サイズを犠牲にして # pragma で指定します . 使用方法は簡単で , for ルー も実行速度を優先させることがあります . プの直前に指定します . これにより , for ループが自 コンバイラの自動スレッド化機能 動的にスレッド分散されます . プログラムの記述例を 技術の進歩はすごいもので , スレッド化も自動で行 自動で CPLJ 資源の管理と負荷の分散をやってくれる商用ソフトもある ー企業で使う計算サーバは CPU 資源の管理と負荷 る CPU を見つけて , そこにジョブを割り当てると ? 一分散を自動で行うソフトウアを搭載していること い。た仕組みです . グリッドエンジンと呼ばれるソー フトウェアも同じ仕組みです . ・がほとんどです . 例えば , LSF というソフトウェア 1 ・があります . ジョブを投入すると自動的に空いてい ンタ技術 2016 年 3 月号 122 メモリ つ」 0 8 ( 0 乙・つ O メモリ 領域 1 領域 2 CPUI CPUI 領域 A 理想 実際 ( 効率 90 % ) 0 1 0 8 6

10. トランジスタ技術 2016年3月号

マルチ CPU CPU CPU コア 1 コア 2 CPU コア 4 が休止中 CPU CPU ↓ コア 3 コア 4 処理効率 75 % 図 16 並列化の基本・・・ 4 個のコアをきちんと動かして 処理効率を上げる で , プロセスをスレッド分割して , 同時に複数のコア を使用する , マルチスレッド・プログラムが登場しま した . 当然 , OS もマルチスレッド対応するため , 大 幅に書き換えられました . たとえば , 4 コアの場合 , 1 プロセスを四つのスレ ッドに分散し , すべてのコアを動かせば , 処理速度が 向上します . ーっのプロセスが 1 コアしか使用せず , CPU 残りの 3 コアが遊んでいるのはもったいないわけです . 四つのコアにしつかり働いてもらわないと , 性能を生 (b) CPU 使用率が IOO % ではない かしきれません ( 図 16 ). 図 17 OS はプロセスの実行タイミングをスケジュール管理し 昔のプログラムは 1 プロセスで 1 スレッドと考える てくれる こともできます . スレッドという考え方へ拡張したこ とで , マルチコアの CPU を有効活用できるようにな ■並列化のポイント りました . プログラム ( 計算のアルゴリズム ) によっては並列処 性能向上のニつの意味 理できず , 高速化が期待できないことがあります . 処 これらの手法を使う場合 , 性能向上という言葉には 理する順序が決まっている場合などです . 並列コンピ 複数の意味が生じてきます . ューティングを用いれば , 必ず高速化できるわけでは (1) ーっの処理を短時間に終わらせる . つまり , ありません . 気を付けるべきポイントがいくつかあり つのプロセスを複数のスレッドに負荷分散して短 ます . 時間に終わらせる 以下では , その代表例を紹介します . なお , ②複数の処理を同時処理する . つまり , 複数のプ の並列化という表現は , マルチスレッド化 , マルチプ ロセス負荷 ( つまりは複数のスレッド ) を分散して ロセス化 , クラスタ化をすべて含みます . 全体として短時間に終わらせる ・ CPU の負荷分散は計画的に 計算サーバとして利用する場合は , 1 スレッドは 1 ・プロセスやスレッドは必要なときだけ動く コアを 100 % 使い切るように動作させます ( 図 17 ). そ 実際のプロセスやスレッドは常に動き続けているわ のため , 計算を実行しているプロセスは CPU 使用率 けではなく , 何かのイベントがあるまで待機している 100 % の状態をキープします . CPU 資源を遊ばせてい ことがほとんどです . そのため , CPU コア以上の複 るのはもったいなく , 非効率です . 数のプロセスが常時起動されており , 待機状態にあり 他のプロセスが , これを妨げると性能劣化を招きま ます . これがいわゆる常駐です . たとえば , 4 コアで す . たとえば , 4 コアで 1 プロセスが 4 スレッドに分 も 100 個のプロセスが起動しています ( 待機スレッド 散して動作しているところに , さらに CPU を使い切 の数はもっと多い ). OS はこのプロセスを時間分割し るようなプロセスを起動すれば , OS はコアへのスレ てスケジュール管理します . ッド割り当てを頻繁に切り替えます . 完全に処理能力 実際の Linux OS では軽量プロセスという概念もある を超えて , オーバーワーク状態です . CPU の性能限界 実際の Linux ではプロセス , 軽量プロセス , スレッ という意味では 100 % の使用率は好ましくありません . ドが存在しています . そのため , この解説は厳密では こうしたことのないように , 計算サーバでは負荷の ありません . 計画を行わなければなりません . たとえば , 4 コアの ンタ技術 2016 年 3 月号 プログラム 2 プログラム 1 プログラム 5 CPU 使用率が 100 % なので これ以上入ら ない CPU プログラム 4 プログラム 3 (a) CPU 使用率が IOO% プログラム 2 プログラム 1 プログラム 4 CPU 使用率が 100 % でない ので別のプロ グラムを動か せる プログラム 3 120