Microsoft Word - openmp-txt.doc

Similar documents
(Microsoft PowerPoint \215u\213`4\201i\221\272\210\344\201j.pptx)

NUMAの構成

AICS 村井均 RIKEN AICS HPC Summer School /6/2013 1

コードのチューニング

Microsoft PowerPoint - OpenMP入門.pptx

演習1: 演習準備

Microsoft PowerPoint - 03_What is OpenMP 4.0 other_Jan18

enshu5_4.key

OpenMPプログラミング

C プログラミング演習 1( 再 ) 2 講義では C プログラミングの基本を学び 演習では やや実践的なプログラミングを通して学ぶ

openmp1_Yaguchi_version_170530

02_C-C++_osx.indd

2. OpenMP OpenMP OpenMP OpenMP #pragma#pragma omp #pragma omp parallel #pragma omp single #pragma omp master #pragma omp for #pragma omp critica

cp-7. 配列

数はファイル内のどの関数からでも参照できるので便利ではありますが 変数の衝突が起こったり ファイル内のどこで値が書き換えられたかわかりづらくなったりなどの欠点があります 複数の関数で変数を共有する時は出来るだけ引数を使うようにし グローバル変数は プログラムの全体の状態を表すものなど最低限のものに留

Microsoft PowerPoint - 阪大CMSI pptx

OpenMP (1) 1, 12 1 UNIX (FUJITSU GP7000F model 900), 13 1 (COMPAQ GS320) FUJITSU VPP5000/64 1 (a) (b) 1: ( 1(a))

PowerPoint プレゼンテーション

Microsoft PowerPoint - 09.pptx

enshu5_6.key

プログラミング実習I

Microsoft PowerPoint - 演習1:並列化と評価.pptx

関数の動作 / printhw(); 7 printf(" n"); printhw(); printf("############ n"); 4 printhw(); 5 関数の作り方 ( 関数名 ) 戻り値 ( 後述 ) void である. 関数名 (

バイオプログラミング第 1 榊原康文 佐藤健吾 慶應義塾大学理工学部生命情報学科

XMPによる並列化実装2

01_OpenMP_osx.indd

NUMAの構成

Microsoft PowerPoint - 計算機言語 第7回.ppt

HPC143

Microsoft Word - no11.docx

Microsoft PowerPoint - kougi7.ppt

Microsoft PowerPoint - 阪大CMSI pptx

講習No.1

情報工学実験 C コンパイラ第 2 回説明資料 (2017 年度 ) 担当 : 笹倉 佐藤

Microsoft PowerPoint - C言語の復習(配布用).ppt [互換モード]

POSIXスレッド

memo

C

Microsoft PowerPoint - HPCseminar2013-msato.pptx

書式に示すように表示したい文字列をダブルクォーテーション (") の間に書けば良い ダブルクォーテーションで囲まれた文字列は 文字列リテラル と呼ばれる プログラム中では以下のように用いる プログラム例 1 printf(" 情報処理基礎 "); printf("c 言語の練習 "); printf

生物情報実験法 (オンライン, 4/20)

gengo1-11

Microsoft Word - 計算科学演習第1回3.doc

memo

C C UNIX C ( ) 4 1 HTML 1

Microsoft PowerPoint - lec10.ppt

Microsoft PowerPoint - 11.pptx

Prog1_10th

memo

プログラミングI第10回

Microsoft PowerPoint - KHPCSS pptx

C-programming_kouza4(2007)

コンピュータ工学講義プリント (7 月 17 日 ) 今回の講義では フローチャートについて学ぶ フローチャートとはフローチャートは コンピュータプログラムの処理の流れを視覚的に表し 処理の全体像を把握しやすくするために書く図である 日本語では流れ図という 図 1 は ユーザーに 0 以上の整数 n

kiso2-09.key

Slide 1

Microsoft PowerPoint - kougi6.ppt

Microsoft PowerPoint ppt [互換モード]

Microsoft Word - Training10_プリプロセッサ.docx

GPU チュートリアル :OpenACC 篇 Himeno benchmark を例題として 高エネルギー加速器研究機構 (KEK) 松古栄夫 (Hideo Matsufuru) 1 December 2018 HPC-Phys 理化学研究所 共通コードプロジェクト

Microsoft PowerPoint ppt

PowerPoint Presentation

FORTRAN( と C) によるプログラミング 5 ファイル入出力 ここではファイルからデータを読みこんだり ファイルにデータを書き出したりするプログラムを作成してみます はじめに テキスト形式で書かれたデータファイルに書かれているデータを読みこんで配列に代入し 標準出力に書き出すプログラムを作り

02: 変数と標準入出力

プログラミング基礎

kiso2-03.key

Microsoft Word - VBA基礎(6).docx

Si 知識情報処理

PowerPoint Presentation

Microsoft Word - no02.doc

コマンドラインから受け取った文字列の大文字と小文字を変換するプログラムを作成せよ 入力は 1 バイトの表示文字とし アルファベット文字以外は変換しない 1. #include <stdio.h> 2. #include <ctype.h> /*troupper,islower,isupper,tol

C 言語の式と文 C 言語の文 ( 関数の呼び出し ) printf("hello, n"); 式 a a+4 a++ a = 7 関数名関数の引数セミコロン 3 < a "hello" printf("hello") 関数の引数は () で囲み, 中に式を書く. 文 ( 式文 ) は

Microsoft PowerPoint ppt [互換モード]

#include<math.h> 数学関係の関数群で sin() cos() tan() などの三角関数や累乗の pow() 平方根を求める sqrt() 対数 log() などがあります #include<string.h> 文字列を扱う関数群 コイツもまた後日に 4. 自作関数 実は 関数は自分

スライド 1

memo

ex04_2012.ppt

Microsoft Word - 3new.doc

JavaプログラミングⅠ

OpenMP 3.0 C/C++ 構文の概要

Total View Debugger 利用の手引 東京工業大学学術国際情報センター version 1.0

研究背景 大規模な演算を行うためには 分散メモリ型システムの利用が必須 Message Passing Interface MPI 並列プログラムの大半はMPIを利用 様々な実装 OpenMPI, MPICH, MVAPICH, MPI.NET プログラミングコストが高いため 生産性が悪い 新しい並

並列プログラミング入門(OpenMP編)

OpenMP¤òÍѤ¤¤¿ÊÂÎó·×»»¡Ê£±¡Ë

1.overview

02: 変数と標準入出力

PowerPoint プレゼンテーション

about MPI

C のコード例 (Z80 と同機能 ) int main(void) { int i,sum=0; for (i=1; i<=10; i++) sum=sum + i; printf ("sum=%d n",sum); 2

1 return main() { main main C 1 戻り値の型 関数名 引数 関数ブロックをあらわす中括弧 main() 関数の定義 int main(void){ printf("hello World!!\n"); return 0; 戻り値 1: main() 2.2 C main

Microsoft Word - no202.docx

gengo1-12

スライド 1

ポインタ変数

OpenMP¤òÍѤ¤¤¿ÊÂÎó·×»»¡Ê£±¡Ë

目次

関数の呼び出し ( 選択ソート ) 選択ソートのプログラム (findminvalue, findandreplace ができているとする ) #include <stdio.h> #define InFile "data.txt" #define OutFile "sorted.txt" #def

gengo1-12

Microsoft PowerPoint - prog03.ppt

Microsoft PowerPoint - 12.ppt [互換モード]

関数の呼び出し ( 選択ソート ) 選択ソートのプログラム (findminvalue, findandreplace ができているとする ) #include <stdiu.h> #define InFile "data.txt" #define OutFile "surted.txt" #def

Transcription:

( 付録 A) OpenMP チュートリアル OepnMP は 共有メモリマルチプロセッサ上のマルチスレッドプログラミングのための API です 本稿では OpenMP の簡単な解説とともにプログラム例をつかって説明します 詳しくは OpenMP の規約を決めている OpenMP ARB の http://www.openmp.org/ にある仕様書を参照してください 日本語訳は http://www.hpcc.jp/omni/spec.ja/ にあります また OpenMP のチュートリアル http://www.hpcc.jp/omni/openmp-tutorial.pdf にありますので 参考にしてください 1 OpenMP の特徴と並列プログラミングモデル OpenMP は 新しい言語ではありません C や Fotran などの既存の逐次言語にプラグマ (#pragma で始まるCの指示文のこと ) やコメント行 (Fotran では $! で始まる行 ) で 指示を加えることにより OpenMP の並列プログラミングモデルに従ったプログラミングをするための仕様を定めたものです OpenMP では以下のような特徴があります (1) 既存の逐次プログラムをベースに並列プログラムを作ることができる (2) 指示文を使って スレッドを生成 制御することができ スレッドライブラリなどを使うよりも簡単にスレッドプログラミングができる (3) 徐々に指示文を加えることにより 段階的に並列化をすることができる (4) 基本的に OpenMP の指示文を無視することにより 元の逐次プログラムになります ( 逐次の semantics を保持している ) 従って 逐次と並列プログラムを同じソースで管理することができます このような特徴から MPI のメッセージ通信のプログラミングに比べ非常に簡単に並列化することができます OpenMP の規約では これらの要素を定義しています (1) 指示文 (2) 実行時ルーチン (3) 環境変数図に OpenMP のアーキテクチャの概略について示します OpenMP はこれらの要素を通じて 共有メモリのマルチプロセッサの並列プログラミングモデルを提供しています 共有メモリを使ったマルチスレッドプログラミングでは 共有メモリ上でプロセッサによる複数の実行の流れを制御するプログラムを書きます スレッドとは実行の流れのことで OpenMP では この制御をコンパイラに対する指示文で行います ユーザアプリケーションプログラムユーザ OpenMP のプログラムは通常の逐次プログラムと同じように main から始まります #pragma OpenMP 指示文 構文環境変数で始まる行は指示文といいます C 言語では #pragma omp で始まるプラグマを用います #pragma omp OpenMP 指示文... 実行時ルーチン OpenMP 実行時ライブラリ スレッドライブラリオペレーティングシステム - 1 -

指示文がなければ 通常の逐次プログラムと何ら変わりがありません まず 以下のようなプログラムを考えて見ましょう A... foo(); /*..B... */ fork A C. Call foo() Call foo() Call foo() Call foo() B D join C E... A は通常の逐次プログラムと同じように 実行されます 次に parallel 指 D 示文 に続くブロック文が複数のスレッドで並列に実行されます このブロック文の実行が終わる E と すべてのスレッドの終了を待って 逐次に戻り Cの部分が逐次に実行されます また 次の があると このブロック文が複数のスレッドで実行されます 逐次から複数のスレッドになることを fork 1つのスレッドに戻ることを join といい このような実行モデルは fork-join モデルといいます BやDの parallel 指示文があると この中の文は重複して実行されます 例では Bの関数呼び出しも含めて それぞれのスレッドで実行されます parallel 指示文で複数のスレッドで実行されるブロックを並列リージョンと呼びます また この並列リージョンを実行する複数のスレッドのことを team と呼びます この team 内のスレッドは 0 から番号がつけられており 元の逐次部分を実行しているスレッドは 0 番になり これをマスタースレッドと呼びます 2 Hello World:OpenMP による並列プログラミングさて 具体的な例を使って説明していくことにしましょう まずは 良く C のプログラムはじめに学習する hello world のプログラムを OpenMP 版を考えることします ここではスレッドの番号 ( すなわち 0 から始まるスレッドの番号 ) を出すことにします #include <stdio.h> main() printf("hello world from %d of %d\n", omp_get_thread_num(), omp_get_num_threads()); - 2 -

プログラム中 #pramga で始まる行はコンパイラに対する指示文です # で始まっているので通常の C コンパイラにとってはコメント行です pragma の後の omp キーワードにより OpenMP コンパイラは このコメント行がコンパイラに対する指示文であると認識します parallel 指示文は 次に続く文あるいはブロックを並列に実行するコードを生成させます printf では OpenMP 処理系の実行時ライブラリ関数である omp_get_thread_num 関数および omp_get_thread_threads 関数が呼ばれています これら関数はそれぞれスレッド番号 スレッドの数を返す関数です 上記プログラムを今回使用する OpenMP コンパイラ Omni OpenMP で コンパイルして実行してみましょう コマンドは omcc で /opt/omni/bin にあります % omcc -o omphello omphello.c %./omphello #pragma parallel で指定された部分が それぞれのスレッドで実行され 4CPU のマシンでは 次のような結果が得られるはずです hello world from 0 of 4 hello world from 2 of 4 hello world from 1 of 4 hello world from 3 of 4 OpenMP では並列部分がいくつのスレッドで実行されるのかは プログラムでは指定しません 通常 共有メモリマシンで実行する場合には何個の CPU があるかが実行開始時に調べ その CPU と同じ数のスレッドが生成 それぞれの CPU でスレッドが実行されます 実験用のマシン上では 2CPU なので hello world from 0 of 2 hello world from 1 of 2 となるはずです 確かめてください もしも スレッド数を変えたい場合には環境変数 OMP_NUM_THREADS で制御します csh 環境では 以下のようにして環境変数にスレッド数をセットします % setenv OMP_NUM_THREADS 4 このスレッド数は実際の CPU の数よりも多くても少なくてもかまいません CPU 数よりも少ないスレッド数の場合には一部の CPU しか使われません CPU 数よりも多いスレッド数が指定された場合には オペレーティングシステムのスケジューリングにより各スレッドに C PU が適当にスレッドが割り当てられて 実行されます この場合にはスレッド数を CPU 数よりも増やしたからといって 実行速度が速くなるわけではないことを注意してください ( 実際 遅くなることもあります ) 本当に CPU が並列に動いているのか これを確かめるためには コマンド xcpustate を使います これをバックグラウンドで動かしておきましょう % xcpustate& このコマンドはウインドウ上に CPU の数分だけの棒グラフが出て CPU が動き出すと 赤い棒グラフになって動いているのがわかります hello world のプログラムでは あまりにも実行時間が短くて ちょっとわかりにくいかもしれません このコマンドは 同時に login しているユーザがプログラムを動かしているときにも表示されますから 他の人が使っていないことを確認するにも便利です - 3 -

3 ワークシェアリング指示文の使い方 : ベクトル計算の並列化 OpenMP では 並列リージョンは全てのスレッドで同じコードが実行されます スレッド番号を取得し明示的にマルチスレッドプログラミングをすることもできますが ワークシェアリング指示文を使うことによって ループなどを簡単に並列化することができます ワークシェアリング指示文とは 並列リージョンで team 内のスレッドで指示された文を分割して実行するための指示文です 前に 並列リージョンでは 同じ文を重複して実行すると述べましたが ワークシェアリング指示文のところでは指定された部分を分割して実行します 次の例について考えてみましょう int A[1000]; main() int i; for(i = 0; i < 1000; i++) A[i] = i; printf("sum = %d n",sum(a,1000)); int sum(int *a, int n) int s; s = 0; for(i = 0; i < n; i++) s += a[i]; return s; 関数 sum は n 個の数を加算する関数です これを並列化するためには 加算する配列を分割して 各スレッド (CPU) がその部分を加算し その結果を最終的に合計して 全体の加算をすればいいことになります ( 図 ) このようなプログラミングの場合には for 指示文が便利です for 指示文は ループを並列化するためのワークシェアリング指示文です int sum(int *a, int n) int s; s = 0; #pragma omp for reduction(+:s) for(i = 0; i < n; i++) s += a[i]; return s; 1 2 3 4 1000 逐次処理の場合 + S 1 2 250 251 500 501 750 751 1000 + + + + プロセッサ 1 プロセッサ 2 プロセッサ 3 プロセッサ 4 + 並列処理の場合 S - 4 -

parallel 指示文で生成されたスレッドは for 指示文により for ループの各部分を分担して実行します for 指示文は 並列リージョンを実行する複数のスレッドで for 指示文の後にあるループを並列に実行します 例えば 4 スレッドで並列実行している場合には 上の例では i が 0 から 249 まではスレッド 1, 250 から 499 まではスレッド 2... というように各スレッドで並列に実行します この場合は均等にあらかじめ分割して実行しますが ループの実行時間がばらつく場合などには動的にループを実行するなど 実行の仕方も指定することができます for 指示文では 並列実行するループを全てのスレッドがそのループの実行を終了するまで 待ち合わせます 並列リージョンに 1 つの for 指示文で指定される並列ループのみがある場合には 以下のように 1 つにすることができます for reduction(+:s) for(i = 0; i < n; i++) s += a[i]; さて OpenMP の指示文にある reduction は何をしめすのでしょうか? この文は 変数 s が共有されて加算される変数であることを指示します このような指示句をデータスコープ属性の指定するものです 例えば 次のような例を考えてみましょう #pragma omp for private(t) for(i = 0; i < 1000; i++) t =...;...=... t...... for 指示文の後にある private(t) は ループ並列実行する場合に変数 t をそれぞれのスレッドで別々の変数を持つことを指定するもので 変数データのスコープ属性の指定をするものです 通常 なにも指定しない変数は全てのスレッドで共有されます しかし 例にある変数 t のようにループ内で一時的に使われる変数の場合は private(t) がないと並列実行しているスレッドが同じ変数に書きこんでしまうため 正しく並列化ができなくなります データスコープ属性には以下の種類があります shared(var_list) 構文内で指定された変数がスレッド間で共有される private(var_list) 構文内で指定された変数が private firstprivate(var_list) private と同様であるが 直前の値で初期化される lastprivate(var_list) private と同様であるが 構文が終了時に逐次実行された場合の最後の値を反映する reduction(op:var_list) reduction アクセスをすることを指定 スカラ変数のみ 実行中は private 構文終了後に反映 4 その他の指示文 ワークシェアリング指示文には ループを並列化する for 指示文の他に 1 つのスレッドのみで実行する single 指示文 異なる部分を別々のスレッドで実行する section 指示文があります 以下のコードでは single 指示文で指定されたブロック文は一つのスレッドでしか実行されません - 5 -

#pragma omp single statements この指示文では すべてのスレッドが到着するまで 待ち合わせをします section 指示文では #pragma omp sections で囲まれたブロックのなかで #pragma omp section で指示された部分は別々のスレッドで実行されます これを使っていわゆるタスク並列のプログラミングを行うことができます #pragma omp sections #pragma omp section section1 #pragma omp section section2 また この指示文でもすべてのスレッドはこの指示文を実行するまで待ち合わせます で複数スレッドで実行させる時に すべてのスレッドを待ち合わせる操作がバリア操作です この操作を行う指示文がバリア指示文です #paramga omp barrier なお OpenMP の指示文は複数のスレッドで実行されている場合にしか有効でありません つまり で指定される並列リージョン以外では無効になります ( だだし 並列リージョン内から呼び出された関数でも 複数のスレッドで同時に実行されていますから 有効になることがあります ) 5 Laplace 方程式 OpenMP による Laplace 方程式プログラムを図に示します 元の逐次版のプログラムに 5 行のコンパイラ指示文を加えるだけで並列化できます #pramga omp parallel で do ループ全体を並列化しています 各 for 指示文は ループの並列化を行っています parallel 指示文で指定された並列リージョンでは 複数のスレッドで実行されます ワークシェアリング指示文では それらのスレッドでループを分割して並列実行することに注意してください スレッドは並列リージョンの最初で生成され ループごとに生成されるわけではありません #paramga omp signle では 1 つのスレッドだけで 変数 err を初期化します その後 の for 構文では err に対して reduction が指定されています このプログラムは 通常のコンパイラで指示文を無視してコンパイルすることで 元の逐次プログラムとして実行することができます main() double start, end; double err, diff; int i, j; init(u); init(uu); start = second(); - 6 -

private(i, j, diff) do /* copy */ #pragma omp for for (i = 1; i < YSIZE - 1; i++) for (j = 1; j < XSIZE - 1; j++) uu[i][j] = u[i][j]; /* update */ #pragma omp for for (i = 1; i < YSIZE - 1; i++) for (j = 1; j < XSIZE - 1; j++) u[i][j] = (uu[i - 1][j] + uu[i + 1][j] + uu[i][j - 1] + uu[i][j + 1])/4.0; #pragma omp single err = 0.0 #pragma omp for reduction(+:err) for (i = 1; i < YSIZE - 1; i++) for (j = 1; j < XSIZE - 1; j++) diff = uu[i][j] - u[i][j]; err += diff*diff; while (err > EPS); end = second(); printf("time = %f seconds\n", end - start); サンプルプログラムとして 準備しておきますので 2CPU の実験用のマシンで約 2 倍になることを確認してみましょう 最初に述べたように このプログラムを普通の C コンパイラでもコンパイルできます この場合は単なる逐次プログラムになります % cc -o seq laplace.c でコンパイルした逐次の seq と % omcc -o omp laplace.c としてコンパイルした並列版の omp とを実行して実行時間を比較してみてください - 7 -