汎用プログラミング環境を用いた GPGPU に関する研究 大島 聡史 電気通信大学 大学院情報システム学研究科 博士 (工学) の学位申請論文 2009 年 3 月 汎用プログラミング環境を用いた GPGPU に関する研究 博士論文審査委員会 主査 本多 弘樹 教授 委員 曽和 将容 教授 委員 多田 好克 教授 委員 吉永 努 准教授 委員 近藤 正章 准教授 著作権所有者 大島 聡史 2009 年 Study of GPGPU Using Commodity Programming Environment Satoshi OHSHIMA Abstract GPU (Graphics Processing Unit) is suitable for parallel processing and has high performance than existing CPU (Central Processing Unit), so GPU is now being used for various applications. Many applications are getting speed-up using GPGPU (General-Purpose computation using GPUs), while the difficulty of GPU programming is under problem. Application programmer must use special programming languages and libraries for GPGPU programming to create programs running on GPUs, but using such languages and libraries are difficult for programmers because it is necessary to learn GPU’s architecture, execution model of GPU, and programming language’s specification. Therefore it is a challenge of GPGPU to make GPGPU programming easy. In this paper, two approaches which make using GPGPU easy with commodity parallel programming environments are proposed. The first approach is a “parallel computation library” which hides parallel programming from application programmers by offering parallelized computation kernels. This library has APIs similar to CPU’s libraries and computes using CPUs and GPUs. To get a high performance in anytime, this library divides the problem and executes them in parallel using CPUs and GPUs when problem size is big enough and a balance between CPU’s performance and GPU’s performance is suitable, and uses an only CPU in other cases with appropriate balance suggested by a tuning-script and a divide-module. “GPUPC GEMM Library” is a parallel matrix-matrix multiplication library based on this approach. This library can get a high performance with GPGPU systems without parallel programming. The second approach is a “parallel programming environment” which offers a parallel programming environment like as existing parallel programming environments used on CPU. “OMPCUDA” is an OpenMP implementation for CUDA based on this approach. OMPCUDA can execute parallel regions of OpenMP programs on a GPU, so that programmers can execute parallel programs on a GPU without learning and writing GPU-specific parallel programs. Contributions of this study are proposal of new approaches which make using GPGPU easy for many application programmers and evaluation of the effectiveness of approaches by implementing a library (GPUPC GEMM Library) and a system (OMPCUDA). Results of this study are significant from the perspective of indicating how easy-to-use environment for application programmers in computing systems having GPU should be. 汎用プログラミング環境を用いた GPGPU に関する研究 大島 聡史 概要 GPU (Graphics Processing Unit) は既存の CPU (Central Processing Unit) と比 べて並列処理による高い演算性能を持つため,画像処理以外の処理を含めた様々な 用途への利用が進められている.GPU を用いた汎用演算 GPGPU (General-Purpose computation using GPUs) により様々なアプリケーションの高速化が行われている 中,GPU プログラミングの難しさが問題となっている. 現在アプリケーションプログラマが GPU 上で動作するプログラムを作成するに は,GPU (GPGPU) 専用のプログラミング言語やライブラリ (プログラミング環境) を用いる必要があり,GPU のアーキテクチャや GPU 向けのプログラミング環境で 利用される実行モデルについて理解する必要がある.このようにアプリケーション プログラマにとって GPGPU プログラミングは難しく手間がかかるため,GPGPU を容易に利用できるようにすることは GPGPU の大きな課題である. 本研究では,現在 CPU を対象とした並列化プログラミングに利用されている汎 用プログラミング環境を GPGPU でも利用可能としアプリケーションプログラマに 対する GPGPU の利用を容易にすることを提案する. また提案に対する具体的なアプローチとして “並列計算ライブラリによるアプロー チ” と “並列プログラミング環境によるアプローチ” の 2 つのアプローチを挙げ,そ れぞれのアプローチに基づきライブラリや処理系を実装して有効性の検証を行った. 各アプローチの概要と得られた成果は以下の通りである. 1. 並列化された計算カーネルを提供することで並列化プログラミング自体を隠 蔽する並列計算ライブラリ (並列計算ライブラリによるアプローチ) • CPU 単体で実行されるライブラリと同様の API を持つ GPU 向けのライ ブラリを提供し,GPU に関する知識がないアプリケーションプログラマ でも GPU の持つ高い並列演算性能を活用可能とすることを目的とした. • 既存の GPU 向け並列計算ライブラリには “CPU 単体で実行されるライ ブラリと同様の API を持つ GPU 向けのライブラリを提供するだけでは 対象問題のデータ規模や CPU-GPU 間での負荷分散に関する課題があり 良い性能が得られない可能性がある” という問題点があることを指摘し た.また解決のために “CPU 単体で実行されるライブラリと同様の API を持ちながら,対象問題のデータ規模が小さい場合には CPU のみで演算 を行い,データ規模が大きい場合には CPU と GPU の性能バランスにあ わせて CPU と GPU で適切な問題分割・並列実行を行う機構を持つ並列 計算ライブラリ” を提案し,実装方法や実装上の問題についての検討を 行った. • 提案に基づき行列積和計算を対象としたライブラリ “GPUPC GEMM Library” を実装し,テストプログラムやベンチマークプログラムを用いて 実装の手間と性能について評価を行った. • 評価の結果,GPUPC GEMM Library が備えるチューニングスクリプト およびスクリプトの出力結果にあわせて適切に問題分割を行う問題分割 機構によって,本ライブラリを利用するアプリケーションプログラマが GPU に関する知識や実行対象計算機システムの CPU と GPU の性能バ ランスを気にする必要なく GPU の持つ高い並列演算性能を常に容易に利 用できることを確認した. 2. 並列計算アルゴリズムを実装するための並列化プログラミング言語や並列化プ ログラミング用のライブラリ (並列化プログラミング環境によるアプローチ) • CPU を対象とした並列化プログラミング環境を GPU プログラミングに も利用できるようにすることで,アプリケーションプログラマにとって GPGPU 専用のプログラミング環境の習得などの手間を削減し,GPGPU を容易に利用可能にすることを目的とした. • 既存の CPU 向け並列化プログラミング環境を GPGPU プログラミング にも利用可能とすることを提案し,典型的な GPU のハードウェア構成と 既存の CPU 向け並列化プログラミング環境との対応付けを検討した.さ らに GPGPU 環境の 1 つである CUDA に対してより具体的な対応付けを 検討した. • 検討に基づき CUDA 向けの OpenMP 処理系 “OMPCUDA” を実装し,テ ストプログラムを用いて利用の手間と性能について評価を行った. • 評価の結果,OMPCUDA は OpenMP の典型的な問題であるループの並 列化に対して,OpenMP を用いた簡単な並列化記述によって GPU 上の多 数の演算器を有効に利用することで高い性能が得られることを確認した. 以上の 2 つのアプローチにより,汎用プログラミング環境を用いて GPGPU を利 用可能とすることで,アプリケーションプログラマに対する手間を増加させること なく GPGPU の高い並列演算性能を容易に利用可能とできることを示した. 本研究の今後の課題としては,アプリケーションプログラマにとっての手間の増 加と得られる性能とのトレードオフに関する課題と,本研究の成果を GPU 以外の ハードウェア (GPU 以外の SIMD 型アクセラレータ) や OpenCL と比較することを 挙げた. 本研究の貢献は,GPGPU を多くのアプリケーションプログラマが容易に活用で きるようにするアプローチを提案し,提案に基づいてライブラリや処理系の実装を 行い有効性を実証した点にある.この成果は,今後さらに普及が広がると考えられ る GPU を搭載した計算機システムにおけるアプリケーションプログラマにとって 使いやすい利用環境のあり方を示すものとして意義がある. 目次 i 目次 1 2 序論 1 1.1 本研究の背景と目的 . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.2 本研究のアプローチ . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.3 本論文の構成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 GPU に関する技術動向と本研究の位置づけ 2.1 8 GPU のアーキテクチャとプログラミング環境 . . . . . . . . . . . . . 8 2.1.1 GPU と GPGPU . . . . . . . . . . . . . . . . . . . . . . . . . 8 2.1.2 GPGPU プログラミング環境 . . . . . . . . . . . . . . . . . . 10 2.2 SIMD 型アクセラレータとしての GPU . . . . . . . . . . . . . . . . . 15 2.3 プログラミング環境に関する研究の動向 . . . . . . . . . . . . . . . . 20 2.4 2.3.1 GPU 向けのプログラミング環境 . . . . . . . . . . . . . . . . . 20 2.3.2 CPU 向けのプログラミング環境 . . . . . . . . . . . . . . . . . 25 SIMD 型アクセラレータやプログラミング環境に関する研究と本研究 との関係 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 3 並列計算ライブラリによるアプローチ 31 3.1 CPU と GPU を用いて問題分割・並列実行を行うライブラリの提案 . 31 3.2 CPU と GPU を用いて問題分割・並列実行を行うライブラリの実装 . 35 3.2.1 CPU と GPU を用いた並列処理の実装 . . . . . . . . . . . . . 35 3.2.2 CPU と GPU による適切な問題分割を行うための仕組み . . . 36 3.2.3 複数の CPU や複数の GPU を搭載した計算機システム向けの 実装 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 3.3 GPUPC GEMM Library : CPU と GPU を用いて問題分割・並列実 行を行う行列計算ライブラリ の設計と実装 . . . . . . . . . . . . . . . 47 3.4 3.3.1 ライブラリが対象とする範囲 . . . . . . . . . . . . . . . . . . 47 3.3.2 ライブラリの設計と実装 . . . . . . . . . . . . . . . . . . . . . 49 GPUPC GEMM Library の評価 . . . . . . . . . . . . . . . . . . . . . 59 3.4.1 単純な行列積和計算を用いた性能確認 . . . . . . . . . . . . . 59 目次 4 ii 3.4.2 HPL ベンチマークを用いた性能確認 . . . . . . . . . . . . . . 70 3.4.3 利用の手間と得られる性能に関する評価 . . . . . . . . . . . . 75 並列化プログラミング環境によるアプローチ 4.1 77 既存の CPU 向け並列化プログラミング環境を用いた GPGPU プログ ラミングの提案 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 4.2 4.3 5 4.1.1 既存の CPU 向け並列化プログラミング環境と GPGPU . . . . 78 4.1.2 既存の CPU 向け並列化プログラミング環境と CUDA . . . . . 83 OMPCUDA : CUDA 向け OpenMP の提案と実装 . . . . . . . . . . . 98 4.2.1 全体の構成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 4.2.2 プログラム変換機構の実装 . . . . . . . . . . . . . . . . . . . . 103 4.2.3 実行時ライブラリの実装 . . . . . . . . . . . . . . . . . . . . . 105 OMPCUDA の評価 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 4.3.1 行列積を用いた性能確認 . . . . . . . . . . . . . . . . . . . . . 111 4.3.2 円周率の計算 (グレゴリ級数) を用いた性能確認 . . . . . . . . 115 4.3.3 実装の手間や記述の容易性に関する評価 . . . . . . . . . . . . 122 結論 125 5.1 研究成果の概要 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 5.2 今後の課題 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 謝辞 135 参考文献 136 A 付録 1: CUDA を用いた実装のソースコード 148 図目次 iii 図目次 1 既存の CPU 向けプログラミング環境と GPU . . . . . . . . . . . . . . 4 2 画像処理と並列計算 9 3 画像描画処理と汎用演算 . . . . . . . . . . . . . . . . . . . . . . . . . 11 4 単純な配列加算プログラムの例 (一部抜粋) . . . . . . . . . . . . . . . 13 5 CSX のハードウェア構成図 . . . . . . . . . . . . . . . . . . . . . . . 16 6 Cell のハードウェア構成図 . . . . . . . . . . . . . . . . . . . . . . . . 18 7 ストリーミング言語の概念 . . . . . . . . . . . . . . . . . . . . . . . . 21 8 BrookGPU を用いたプログラムの例 . . . . . . . . . . . . . . . . . . . 22 9 RapidMind を用いたプログラムの例 . . . . . . . . . . . . . . . . . . 23 10 SPRAT を用いたプログラムの例 . . . . . . . . . . . . . . . . . . . . 24 11 典型的な GPGPU プログラムの処理手順 . . . . . . . . . . . . . . . . 32 12 スレッドを用いた並列実行の失敗例 . . . . . . . . . . . . . . . . . . . 37 13 提案するライブラリの構造 . . . . . . . . . . . . . . . . . . . . . . . . 38 14 複数 CPU を用いた実装の例 1 . . . . . . . . . . . . . . . . . . . . . . 42 15 複数 CPU を用いた実装の例 2 . . . . . . . . . . . . . . . . . . . . . . 43 16 複数 CPU と複数 GPU を用いた実装の例 1 . . . . . . . . . . . . . . . 45 17 複数 CPU と複数 GPU を用いた実装の例 2 . . . . . . . . . . . . . . . 46 18 BLAS における GEMM の関数定義 . . . . . . . . . . . . . . . . . . . 48 19 ベクトル演算を利用した行列積の例 . . . . . . . . . . . . . . . . . . . 51 20 ベクトル演算が利用できない行列積の例 . . . . . . . . . . . . . . . . 52 21 問題分割方法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 22 ライブラリの設計 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 23 複数 CPU・複数 GPU 対応版 GPUPC GEMM Library の構造 . . . . 57 24 各問題サイズに対する実行時間と CPU に対する実行時間比 (環境 1) . 61 25 各問題サイズに対する実行時間と CPU に対する実行時間比 (環境 2) . 62 26 各問題サイズに対する実行時間と CPU に対する実行時間比 (環境 3) . 63 27 各問題サイズに対する実行時間と CPU に対する実行時間比 (環境 . . . . . . . . . . . . . . . . . . . . . . . . . . . 1:DGEMM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 図目次 28 iv 各問題サイズに対する実行時間と CPU に対する実行時間比 (環境 2:DGEMM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 29 各問題サイズに対する実行時間と CPU に対する実行時間比 (環境 3:DGEMM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 30 2CPU+2GPU での性能評価 (SGEMM) . . . . . . . . . . . . . . . . . 69 31 HPL の性能パラメタ (括弧内は初期値) . . . . . . . . . . . . . . . . . 71 32 CPU による HPL の性能調査:問題サイズと性能 (環境 1) . . . . . . . 72 33 CPU による HPL の性能調査:ブロックサイズと性能 (環境 1) . . . . 72 34 GPUPC GEMM Library を用いた HPL の実行結果 (環境 1) . . . . . . 74 35 典型的な GPU のハードウェア構成 . . . . . . . . . . . . . . . . . . . 79 36 CUDA のハードウェアモデル . . . . . . . . . . . . . . . . . . . . . . 85 37 CUDA のメモリモデル . . . . . . . . . . . . . . . . . . . . . . . . . . 88 38 SIMD プログラミングと CUDA との対応付け . . . . . . . . . . . . . 90 39 スレッドライブラリを用いたマルチスレッドプログラミングと CUDA との対応付け . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 40 OpenMP を用いた並列化プログラミングと CUDA との対応付け . . . 94 41 通信ライブラリを用いたマルチプロセスプログラミングと CUDA と の対応付け . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96 42 OpenMP と OMPCUDA の実行モデルとの対応付け . . . . . . . . . . 100 43 Omni と OMPCUDA の関係および OMPCUDA の構成 . . . . . . . . 101 44 プログラム変換機構の処理手順 . . . . . . . . . . . . . . . . . . . . . 104 45 OMPCUDA における for ループのスケジューリング例 . . . . . . . . 107 46 行列積のソースコード 1 (3 重ループ) . . . . . . . . . . . . . . . . . . 113 47 行列積のソースコード 2 (2 重ループ) . . . . . . . . . . . . . . . . . . 113 48 行列積の実行時間 1 (問題サイズ 1024) . . . . . . . . . . . . . . . . . 114 49 行列積の実行時間 2 (問題サイズ 1024) . . . . . . . . . . . . . . . . . 116 50 円周率計算のソースコード . . . . . . . . . . . . . . . . . . . . . . . . 116 51 円周率の求解の実行時間 1 (問題サイズ 0x10000000) . . . . . . . . . 118 52 円周率の求解の実行時間 2 (問題サイズ 0x10000000) . . . . . . . . . 120 53 円周率の求解の実行時間 3 (問題サイズ 0x10000000) . . . . . . . . . 121 表目次 v 表目次 1 SIMD 型アクセラレータの基礎的なデータ . . . . . . . . . . . . . . . 15 2 評価環境 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 3 評価環境 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 4 行列積のプログラム行数と GPU に関する知識の必要性 . . . . . . . . 122 5 円周率求解のプログラム行数と GPU に関する知識の必要性 . . . . . 124 1 序論 1 1.1 本研究の背景と目的 気象,医療,宇宙など様々な分野において,高性能な計算機を用いた計算が必須 となっている [1, 2, 3].これらの分野では高速,高精度,大規模な計算が要求され るため,より高性能な計算機が必要とされている [4, 5, 6, 7, 8].また近年では個人 ユースのパーソナルコンピュータ (PC) においても動画像処理など計算量の多い処 理を行う機会が増加し,高性能な計算機の要求が高まっている. 計算機の演算性能に大きな影響を与えるプロセッサ (CPU) の性能に注目すると, 従来はプロセスの微細化とクロック周波数の向上によりその性能を向上させてきた ことがわかる.例えば 1993 年の Pentium プロセッサが 800nm プロセスルール・ク ロック周波数 60MHz だったのに対して,2005 年の Pentium4 プロセッサ (Prescott コア) は 90nm プロセスルール・クロック周波数 3.80GHz に達している [9]. しかしながら今日のプロセッサにおいては,微細化が進むとリーク電流が増加し 消費電力が増加してしまうことや,微細化が原子の大きさによる物理的限界に近づ きつつあるため微細化そのものが難しくなっていること,またクロック周波数の向 上が発熱量や消費電力の増加につながることなどが問題となっている.その結果, 2008 年末の時点で利用されている CPU のプロセスルールは 2005 年のプロセスルー ルの半分である 45nm にとどまっており,またクロック周波数についても,適切な 冷却機構の元で運用されるサーバ向け CPU が 5GHz 以上の周波数を達成している [10] ものの,コンシューマ向けの多くの CPU では 4GHz 未満の周波数にとどまって いるのが現状である. 今日における CPU の性能への関心は,これまでのシングルコア CPU によるシン グルスレッドの性能から,複数のコアを 1 パッケージに収めたマルチコア CPU の性 能へと向けられている.2008 年末の時点では,2 つから 4 つのコアを搭載したマル チコア CPU (デュアルコア CPU・クアッドコア CPU) が主流となっており,主要な CPU ベンダーは 4 つ以上のコアを搭載した CPU の開発・リリースに注力している [11, 12]. 一方で,既存の CPU と比べてより高い並列度を持ち理論演算性能や電力あたり 性能が高い新しいハードウェアへの注目が高まっている.その中でも,主に PCI- 1.1 本研究の背景と目的 2 Express 接続のビデオカードとして提供されている画像処理用のハードウェア “GPU (Graphics Processing Unit)” は,既存の CPU と比べて多数の演算を同時に実行可 能であり高い理論演算性能を持つため注目されている.特に,ハイエンドモデルの GPU では同時に 200 以上の演算が可能であり,また最大理論演算性能は 1TFLOPS に達している [13, 14].近年では GPU を用いた汎用演算 “GPGPU (General-Purpose computation using GPUs)” [15, 16, 17, 18] によりプログラムの高速化を行った旨の 報告が相次いでいる [19, 20, 21, 22, 23]. 今日の GPU は高速・高解像度な画面出力および動画再生支援機能などの要求に ともない多くの PC に搭載されており,広く普及が進んでいるハードウェアである. そのため GPGPU を利用可能な計算機システムの普及が進んでいる一方,GPGPU プログラミングの難しさが GPGPU の普及における大きな問題となっている.現在 提供されている GPGPU 向けのプログラミング言語やライブラリ (以下本論文では, プログラミング言語やライブラリをまとめてプログラミング環境と呼ぶ) は,GPU のハードウェアアーキテクチャと強く関連づけられた言語仕様や,既存のプログラ ミング手法とは異なる新たな実行モデルを習得しなければ利用できないため,アプ リケーションプログラマにとっては利用に手間がかかり,大きな負担となっている. 現在の GPU は,ハードウェアアーキテクチャやプログラミング言語など新たな知 識や技術を習得し,手間のかかる実装を行うことではじめて高い性能を達成するこ とが可能なハードウェアである.手間をかけずに GPU の性能を活用するのは難し い一方で,かけた手間に対して性能が得られないことも少なくはない.アプリケー ションプログラマが現実的にかけられる手間には限度があるうえに,特定のハード ウェアでのみ有効な知識や技術の習得は活用できる範囲が限られるという理由で敬 遠される可能性もある.そのため GPU の性能を活用できるユーザは一部のパワー ユーザに限られており,一般の多くのアプリケーションプログラマにとって GPU の 利用は難しいのが現状である. そこで本研究では,既存の CPU 向けプログラミングに利用されている汎用プロ グラミング環境を用いて GPGPU を利用できるようにすることで,アプリケーショ ンプログラマが GPGPU を容易に活用可能とすることを目指す. 1.2 本研究のアプローチ 1.2 3 本研究のアプローチ アプリケーションプログラマにとって GPGPU の利用が難しい原因として,GPGPU を利用するためにハードウェアアーキテクチャと強く結びついた言語やライブラリ を利用する必要があることが挙げられる. 既存の CPU 向けプログラミングにおいては,多くのアプリケーションプログラマ は機械語やアセンブラ言語といった低級言語ではなく,C/C++や Java などの高級 言語を利用している.高級言語はハードウェアアーキテクチャとの結びつきが弱い ため,アプリケーションプログラマは対象とする計算機システムの詳細なハードウェ アアーキテクチャの知識がなくてもプログラムを記述し動かすことができる.また, 多くのコンパイラやインタプリタは複数の CPU アーキテクチャに対応しているた め,アプリケーションプログラマは CPU の違いを気にせずプログラミングを行う ことが可能であり,最適化コンパイラによって同一のソースコードから対象 CPU ご とに最適化された実行ファイルを得ることもできる. さらに,ソースコードを再利用するためやアルゴリズムを実装する手間を削減す るため,そして最適化プログラミングの手間を削減するために,様々なライブラリ 1 . が利用されている (図 1-°) 一方で現在 GPGPU 向けに提供されているプログラミング環境は,GPGPU 専用 の言語やライブラリ,もしくは新しい実行モデルのプログラミング環境である (図 2 2 章) .これらを用いて GPGPU プログラミングを行うには,GPU のハード 1-°, ウェアアーキテクチャに関する知識や,新しいプログラミング言語の言語仕様や実 行モデルの理解が必要であるため,アプリケーションプログラマにとって手間がか かり負担が大きいことが問題となっている. これらの問題に対して本研究では,GPU が並列処理による高い演算性能を持つ ハードウェアであることから,現在 CPU 向けの並列化プログラミングに利用され ている汎用プログラミング環境が GPGPU プログラミングにも利用できれば,アプ リケーションプログラマが GPGPU を容易に利用できると考えた.そこで現在 CPU 向けの並列化プログラミングに利用されている汎用プログラミング環境として “並 列化された計算カーネルを提供することで並列化プログラミング自体を隠蔽する並 列計算ライブラリ (並列計算ライブラリ)” と “並列計算アルゴリズムを実装するた 1.2 本研究のアプローチ 図 1: 既存の CPU 向けプログラミング環境と GPU 4 1.2 本研究のアプローチ 5 めの並列化プログラミング言語や並列化プログラミング用のライブラリ (並列化プ ログラミング環境)” の 2 つを挙げ,これらを用いてアプリケーションプログラマが GPGPU を容易に利用可能とする方法を提案する. なお本研究で対象とする計算機システムは,シングルコアまたはマルチコアの CPU が 1 個と GPU が 1 枚から数枚搭載された 1 台の計算機からなる計算機システムとす る.複数台の計算機からなる計算機システムについては,基本的には各計算機の性 能が GPU により向上したものとみなした上で複数台の計算機向けの手法を用いる ことで対応できると考えられるため,本研究では扱わない. アプローチ 1 : 並列計算ライブラリ アプリケーションプログラマに対して容易に GPU の並列演算性能を利用できる ようにする方法として,GPU 向けに並列化された計算カーネルを提供する並列計算 ライブラリを作成し,GPU 向けの並列化プログラミングを行わなくても GPU の持 つ並列演算性能を利用できるようにするという方法が考えられる.この方法では並 列化プログラミング自体を隠蔽することができるため,アプリケーションプログラ マは API さえ理解していれば GPU の持つ並列演算性能を利用することが可能とな り,アルゴリズムの実装や GPGPU プログラミング習得の手間を大きく削減できる と期待できる. しかしながら,単に GPU 上での並列計算と CPU-GPU 間でのデータ転送や GPU の制御処理をまとめただけのライブラリでは,対象問題のデータ規模が小さい場合 などいくつかの場合に高い性能が得られない可能性が生じてしまう. そこで本アプローチでは,こうした性能が得られないという問題を解決し常に高 い性能を得ることができる並列計算ライブラリの提案と設計を行う.また提案した アプローチに基づいて CPU と GPU を用いて問題分割・並列実行を行う数値計算ラ イブラリ “GPUPC GEMM Library” を実装し,テストプログラムやベンチマークを 用いて利用の手間や性能の面から提案アプローチの評価を行う. 1.3 本論文の構成 6 アプローチ 2 : 並列化プログラミング環境 並列計算ライブラリにより並列化プログラミング自体を隠蔽するアプローチ 1 は, 対象プログラムが典型的なアルゴリズムの組み合わせなどライブラリ化に適した処 理により支配的な場合に特に有効である.しかしながら全てのアプリケーションが これに該当するわけではなく,アプリケーションプログラマが自ら詳細なアルゴリ ズムの実装を行う必要があることも少なくない. 一方で既存の GPGPU プログラミング環境は,GPU のアーキテクチャや新しいプ ログラミング言語の言語仕様などを理解しなくては利用できないため,アプリケー ションプログラマにとって容易に利用できるとは言い難い.しかしもし既存の CPU 向けプログラミング環境を用いて GPGPU プログラムを記述することができれば, アプリケーションプログラマは GPU のアーキテクチャや新しいプログラミング言 語の言語仕様などを習得する手間をかけずに GPGPU を利用可能となることが期待 できる. そこで本アプローチでは,既存の CPU 向けの並列化プログラミング環境を用いた GPGPU プログラミングを提案する.また提案したアプローチに基づいて GPGPU 環境の 1 つである CUDA 向けの OpenMP 処理系 “OMPCUDA” を実装し,テスト プログラムを用いて利用の手間や性能の面から提案アプローチの評価を行う. 1.3 本論文の構成 本論文は 5 つの章により構成される. 第 1 章は本章であり,本研究の背景やアプローチについて述べた. 第 2 章では GPU に関する技術動向や GPGPU 向けのプログラミング環境につい ての研究を整理し,またしばしば GPU と性能やハードウェアアーキテクチャを比 較されるいくつかのハードウェアについての確認やプログラミング環境に関する研 究についての確認を行い,本研究の位置づけを明確にする. 第 3 章では,汎用プログラミング環境を用いて GPGPU を容易に利用可能とする ための手法として,並列計算ライブラリによるアプローチを提案し,提案に基づく ライブラリを実装して利用の手間や性能についての評価を行う. 1.3 本論文の構成 7 第 4 章では,汎用プログラミング環境を用いて GPGPU を容易に利用可能とする ための手法として,並列化プログラミング環境によるアプローチを提案し,提案に 基づく処理系を実装して利用の手間や性能についての評価を行う. 第 5 章では,本研究の結言として研究成果と今後の課題についてまとめ,本研究 の意義を述べる. 8 GPU に関する技術動向と本研究の位置づけ 2 本章では,本研究が対象とする GPU のアーキテクチャおよび現在 GPGPU に用 いられているプログラミング言語やライブラリなどのプログラミング環境について 確認・整理する.さらに,GPU と共通点を持ちしばしば “SIMD 型アクセラレータ” として GPU とともに扱われる他のハードウェアや,マルチコア CPU や SIMD 型ア クセラレータを対象として開発されているプログラミング環境について確認し,本 研究の位置づけを明確にする. 2.1 2.1.1 GPU のアーキテクチャとプログラミング環境 GPU と GPGPU GPU は画像処理用のハードウェアである.狭義にはグラフィックスカード上の LSI やチップセットに統合されたグラフィックスチップが GPU であり,広義にはグ ラフィックスカードそのもの,すなわち LSI のみではなく LSI に接続されたメモリ (DRAM) やデコーダチップなどグラフィックスカード上に搭載されたモジュールな どもまとめて GPU と呼ばれている.また,GPU の持つ演算性能を GPU 本来の目 的である画像処理に限らず様々な処理 (汎用演算:General-Puspose computation) に も活用するのが GPGPU (General-Purpose computation using GPUs) である. 本来 GPU に求められていた画像処理とは,古くは多色・高速・高解像度な 2 次元 の画像描画処理であり,現在ではより複雑な 3 次元の画像描画処理へと変化してき ている.これらの画像描画処理は頂点やピクセルを単位として多数同時に処理でき る (図 2) ことから,GPU は CPU と比べて並列演算性能を重視した性能向上が行わ れてきた [24]. 3 次元物体の陰影を表現する際などには複雑で多彩なアルゴリズムの実装が要求 されるが,アルゴリズムをハードウェアレベルで実装する場合,新たな描画アルゴ リズムに対応するにはハードウェアを変更しなくてはならない.そこで,GPU が行 う描画処理の内容をソフトウェアプログラムによって変更可能とする機構 “プログ ラマブルシェーダ” が利用されるようになった. 以上の結果現在の GPU は,既存の CPU と比較すると制限が多いものの様々なア 2.1 GPU のアーキテクチャとプログラミング環境 図 2: 画像処理と並列計算 9 2.1 GPU のアーキテクチャとプログラミング環境 10 ルゴリズムを実装できるだけのプログラマビリティを持ち,またハードウェアレベ ルでの高い並列性を持つため,並列性の高い問題に対しては CPU を大きく上回る 性能を発揮可能なハードウェアとなっている.そのため GPU は,画像処理以外に も様々な演算に対して高い性能が得られる可能性を見いだされ,GPU を用いた汎用 演算 GPGPU が注目されるようになった. 現在の GPU は,本来の用途である高度な画像処理 [25, 26] だけではなく,各種の シミュレーション [23, 19, 27, 28] や,LU 分解 [21, 22] や FFT[29, 30] などの様々な数 値計算問題 [31, 32, 33, 34, 35],動画像変換等のマルチメディア処理 [36] など,様々 な分野で高い性能を発揮している.さらに GPU ベンダも GPU の汎用演算性能を重 視した製品開発や発表などを行っており [13, 14],今後も多くの分野で GPGPU の 活用が進むことが考えられる. 2.1.2 GPGPU プログラミング環境 初期の GPGPU では,画像描画処理の手続きと演算とを対応付けて利用していた. すなわち,CPU から GPU 上のメモリ (主にテクスチャ) へのデータセットを入力, プログラマブルシェーダを用いた画像描画処理を演算,GPU から CPU へのデータ の書き戻し (描画結果の取得) を出力とみなして処理を行っていた (図 3). 一方,GPU を用いて画像描画処理を行うプログラムを作成するには,GPU の動 作タイミング制御や CPU-GPU 間の通信などを行う CPU 上で実行されるプログラ ムを記述するために DirectX[37] や OpenGL[38] といったグラフィックス API が,ま た GPU 内部の処理ユニットが行う処理を記述するために GPU 向けのアセンブリ言 語や HLSL,GLSL,Cg[39] といった専用の高級言語 (シェーダ言語) が用いられて きた. 初期の GPGPU におけるプログラム作成にはこれら画像描画処理向けのプログラ ミング環境が利用された.グラフィックス API やシェーダ言語は標準化が進んでお り対応 GPU も多く,画像描画処理との親和性が高い.そのため画像描画処理向け のプログラミング環境を用いた GPGPU は,現在でも画像描画処理関係の GPGPU プログラミングでは広く用いられている.しかし,画像描画処理向けのプログラミ ング環境を用いて汎用的な演算を記述するには,対象問題を画像描画処理プログラ ミングに対応させる独自のプログラミング手法を習得し利用する必要がある. 2.1 GPU のアーキテクチャとプログラミング環境 図 3: 画像描画処理と汎用演算 11 2.1 GPU のアーキテクチャとプログラミング環境 12 ここで GPGPU プログラミングの例として,画像描画処理を用いた単純な配列の 加算を考える.配列の加算を実現するために必要な処理とその手順は以下の通りで ある. 1. CPU 側では,入力データとして用いるための配列を 2 つと,出力データを格 納するための配列を 1 つ用意する. 2. GPU 側では,入力データを格納するためのテクスチャを 2 つと,描画結果を 格納するための出力用バッファ (書き込み可能設定を施されたテクスチャ) を 1 つ用意する. 3. 入力データ配列に格納されているデータを CPU から GPU へ送信し,GPU 上 のテクスチャメモリへ配置する. 4. 描画処理の出力先をフレームバッファ (書き込まれた内容が画面表示に反映さ れるバッファ) から 2 で用意した出力用バッファへと変更し,テクスチャデー タの読み出しと加算処理が記述されたシェーダプログラムを用いて描画処理を 行う. 5. 出力用バッファの内容を GPU から CPU へ読み出し,出力データ配列に格納 する. これら一連の処理に対応する OpenGL と GLSL を用いたプログラムの例 (ソース コードの一部抜粋) を図 4 に示す.このように,GPGPU プログラムを作成するには 対象アプリケーションのアルゴリズムに加えて画像処理のためのプログラミング手 法や GPU アーキテクチャについての知識が必要であり,その上プログラムの記述 量も多く,アプリケーションプログラマにとって大きな負担となってきた. そこで近年では,画像描画処理向けのプログラミングを必要とせずに GPGPU プ ログラミングを行える新しい言語やライブラリの研究が進められている.例えば米 NVIDIA 社の CUDA[40] や米 AMD 社の CTM[41] および Stream[42] は,GPU ベン ダが提供する GPGPU 向けのプログラミング環境である.これらのプログラミング 環境を用いることで画像描画処理向けのプログラミング環境と比べて直接的なプロ グラミングが可能となるとともに,GPU のアーキテクチャに適した実装を行うこと で高い性能を得ることが可能となる. 2.1 GPU のアーキテクチャとプログラミング環境 // GPU による処理 ( 描 画 内 容 の 記 述 ) uniform samplerRECT texUnit0 , t e x U n i t 1 ; void main ( void ) { vec2 TexA = vec2 ( 0 . 0 , 0 . 0 ) ; vec2 TexB = vec2 ( 0 . 0 , 0 . 0 ) ; TexA . x= g l F r a g C o o r d . x ; TexA . y= g l F r a g C o o r d . y ; TexB . x= g l F r a g C o o r d . x ; TexB . y= g l F r a g C o o r d . y ; g l F r a g C o l o r = texRECT ( texUnit0 , TexA) + texRECT ( texUnit1 , TexB ) ; } // CPU による処理 ( G P U の 制 御 な ど の 記 述 ) g l u t I n i t (& argc , argv ) ; g l u t I n i t W i n d o w S i z e ( 6 4 , 6 4 ) ; // OpenGL 初期化 glutCreateWindow ( ‘ ‘ GpgpuArrayAdd ’ ’ ) ; g l e w I n i t ( ) ; glGenFramebuffersEXT ( 1 , &f b ) ; // T e x t u r e の 生 成 な ど glBindFramebufferEXT (GL FRAMEBUFFER EXT, f b ) ; glGenTextures ( 4 , nTexID ) ; g l B i n d T e x t u r e ( opt1 , t e x i d ) ; g l T e x P a r a m e t e r i ( opt1 , GL TEXTURE MIN FILTER, GL NEAREST ) ; glTexParameteri ( . . . . . . ) ; glTexImage2D ( opt1 , 0 , opt2 , w, h , 0 , GL RGBA, GL FLOAT, 0 ) ; glMatrixMode (GL PROJECTION ) ; g l L o a d I d e n t i t y ( ) ; gluOrtho2D ( 0 . 0 , nTexCX , 0 . 0 , nTexCY ) ; glMatrixMode (GL MODELVIEW) ; g l L o a d I d e n t i t y ( ) ; g l V i e w p o r t ( 0 , 0 , nTexCX , nTexCY ) ; glUseProgramObjectARB ( programObject ) ; g l B i n d T e x t u r e (TEX OPT1, nTexID [ 0 ] ) ; // T e x t u r e へ の デ ー タ セ ッ ト glTexSubImage2D (TEX OPT1, ... , GL FLOAT, fDataA ) ; glTexEnvi (GL TEXTURE ENV, GL TEXTURE ENV MODE, GL REPLACE ) ; glFramebufferTexture2DEXT (GL FRAMEBUFFER EXT, . . . , nTexID [ 2 ] , 0 ) ; g l A c t i v e T e x t u r e (GL TEXTURE0 ) ; g l B i n d T e x t u r e (TEX OPT1, nTexID [ 0 ] ) ; glUniform1iARB ( texUnit0 , 0 ) ; g l A c t i v e T e x t u r e (GL TEXTURE1 ) ; glUniform1fARB ( . . . . . . ) ; g l D r a w B u f f e r (GL COLOR ATTACHMENT0 EXT ) ; // 描 画 処 理 g l B e g i n (GL QUADS ) ; glTexCoord2f ( 0 . 0 , 0 . 0 ) ; g l V e r t e x 2 f ( 0 . 0 , 0 . 0 ) ; glTexCoord2f (nTexCX , 0 . 0 ) ; g l V e r t e x 2 f (nTexCX , 0 . 0 ) ; glTexCoord2f (nTexCX , nTexCY ) ; g l V e r t e x 2 f (nTexCX , nTexCY ) ; glTexCoord2f ( 0 . 0 , nTexCY ) ; g l V e r t e x 2 f ( 0 . 0 , nTexCY ) ; glEnd ( ) ; g l R e a d B u f f e r (GL COLOR ATTACHMENT0 EXT ) ; // 結 果 の 取 得 g l R e a d P i x e l s ( 0 , 0 , nTexCX , nTexCY ,GL RGBA, GL FLOAT, f D a t a R e s u l t ) ; 図 4: 単純な配列加算プログラムの例 (一部抜粋) 13 2.1 GPU のアーキテクチャとプログラミング環境 14 しかしながら,GPU のハードウェアアーキテクチャは製品によって異なる部分 も多い.現在 GPGPU に利用されている主な GPU として,NVIDIA 社の GeForce・ Quadro・Tesla シリーズと AMD 社の Radeon・FireStream シリーズが挙げられる. これらの GPU はいずれも GPU 上に多数の演算器や複数種類のメモリを搭載するな ど共通の特徴を持ってはいるものの,各演算器の性能やメモリの種類と性能などの 詳細なハードウェア構成は異なっている.さらに CUDA や CTM および Stream と いったプログラミング環境は言語仕様や実行モデルが GPU のアーキテクチャと強く 関連しているため,これらのプログラミング環境を利用するユーザは GPU のアー キテクチャについて理解する必要があり,また利用可能な GPU が限られているた め実行環境に合わせてプログラミング環境を習得して利用せねばならない.以上か ら,GPU ベンダの提供するプログラミング環境はアプリケーションプログラマに対 して GPGPU プログラミングの難しさや手間を解消できているとは言い難い. GPU は多くの PC に搭載されており,GPGPU を利用可能な計算機システムは広 く普及していると言える.しかしながら GPGPU プログラムの作成が難しいため多 くの GPU は演算性能を活用されておらず,GPGPU が広く普及し有効に活用され るには,GPGPU プログラムを容易に作成することが可能な仕組みが必要である. 2.2 SIMD 型アクセラレータとしての GPU 2.2 15 SIMD 型アクセラレータとしての GPU GPU 以外にも,既存の CPU と比べてより高い並列度を持ち,理論演算性能や電力 あたり性能が高い新しいハードウェアの開発や普及が進みつつある.特に ClearSpeed 社の浮動小数点アクセラレータカード (以下 CSX) [43] や,SCEI・東芝・IBM が共 同開発した Cell Broadband Engine および Cell Broadband Engine の強化版である IBM の PowerXCell 8i (以下 Cell) [44] は,しばしば GPU と対比される.これらの ハードウェアはいずれも,既存の CPU と比べて単純なコアを複数搭載することで演 算性能を高めているため,SIMD (Single Instruction Multiple Data) 処理や MIMD (Multiple Instruction Multiple Data) 処理などの並列処理に適しており,また対象ア プリケーションの中でも特に並列度の高い部分を重点的に高速化するアクセラレー タとして利用されている.そのため本論文では GPU を含めたこれらのハードウェ アを “SIMD 型アクセラレータ” と呼び,本節では SIMD 型アクセラレータのハード ウェアアーキテクチャやプログラミング環境について概観する. なお,各 SIMD 型アクセラレータの動作周波数や理論演算性能などの基礎的な性 能データとアプリケーションプログラマに対して提供されているプログラミング環 境については,表 1 の通りである. 表 1: SIMD 型アクセラレータの基礎的なデータ CPU (比較用) GPU CSX Cell 製品モデル Xeon X5482 GeForceGTX280 e720 GigaAccell 180 演算器 (コア) 数 4 240 192 1(PPU)+8(SPU) クロック周波数 3.20GHz 602MHz(Core) 250MHz 2.8GHz (PPU,SPU 共通) 1296MHz(SP) 搭載メモリ容量 ー 1GB 8GB max 4GB メモリ帯域幅 12.8GB/s 141.7GB/s 96GB/s 25.6GB/s 最大消費電力 150W 236W 25W 150W CPU との接続 ー PCIe x16(Gen2) PCIe x16(Gen1) EIB † プログラミング環境 ー CUDA Cn C/C++ or シェーダ言語 with 専用 SDK 理論演算性能 (単精度) 51.2GFLOPS 933GFLOPS 96GFLOPS 180GFLOPS 出典 PlatformBrief[45] TechnicalBrief[46] ProductBrief[47] 製品カタログ [48] † ホスト PC との接続は PCIe x16 2.2 SIMD 型アクセラレータとしての GPU 16 CSX CSX は,ClearSpeed 社が浮動小数点アクセラレータカードとして開発している ClearSpeed Advance アクセラレータカードであり,PCI-Express または PCI-X 接続 の拡張カードとして提供されているハードウェアである.東京工業大学が所有する スーパーコンピュータ TSUBAME に搭載されているアクセラレータとして知られ ている [5].(ただし実際に TSUBAME に搭載されているのは表中の e720 より 1 世 代前の製品である.) CSX は,電力あたりの演算性能が高いことが特徴である.200 近い多数の演算器 を低速に動作させることで,低い消費電力と高い演算性能を達成している. CSX の構成の 1 つである e720 のハードウェア構成を図 5 に示す [49, 50, 47].e720 はアクセラレータカード上にアクセラレータチップと大容量メモリ (DRAM) を搭 載しており,アクセラレータチップ上には 96 の浮動小数点演算ユニットが搭載され たコアが 2 つ搭載されている. 図 5: CSX のハードウェア構成図 2.2 SIMD 型アクセラレータとしての GPU 17 CSX を利用する方法としては,ベンダによって提供されている並列計算ライブラ リを利用する方法と,CSX 用のプログラミング環境を用いてプログラムを作成する 方法とが提供されている. CSX ではベクトル計算や行列計算,FFT など,典型的な演算に関する並列計算ラ イブラリがベンダによって提供されている.そのためこれらの問題を高速化したい 場合には,CSX のアーキテクチャや実行モデルなどを知らずとも,提供されている ライブラリを利用することで容易に高速化を行うことができる. 一方,アプリケーションプログラマが CSX 上で動作するプログラムを作成した い場合には,専用のプログラミング言語である Cn 言語 [51] を利用する必要がある. Cn 言語は C/C++言語を CSX のメモリモデルにあわせて拡張した言語である.Cn 言語には poly と mono という変数宣言時に利用可能な予約語があり,これらを用い ることで CSX 上でのメモリ配置を明示的に指定することができる.さらに,CSX を制御するための API を利用可能にするライブラリが提供されており,これを用い ることで CPU-CSX 間のデータ送受信等を行うことができる.Cn 言語を用いたプロ グラミングにおいては,CPU 上で動作するホストプログラムと CSX 上で動作する デバイスプログラムを個別のソースコードとして記述し,各々のソースコードから 個別の実行ファイルを生成する.実行時には CSX 上でデバイスプログラムを実行し ておき,CPU 上のホストプログラムからデバイスプログラムに対して演算対象デー タの送信や演算結果の取得等を行うという実行の流れとなる. Cell Cell は,SCEI・東芝・IBM が共同開発した,既存の CPU と同程度の機能を持つ制御 用コア PPE と演算専用のより単純なコア SPE を組み合わせたマイクロプロセッサで ある.PLAYSTATION3 のプロセッサとしてや,米 Los Alamos National Laboratory が所有するスーパーコンピュータ Roadrunner が備えるアクセラレータカードに搭載 されているプロセッサとして [52] 知られている.また,SPE のみを搭載したメディ ア処理用のアクセラレータカード SpursEngine としても利用されている [53]. Cell のハードウェア構成を図 6 に示す.Cell は LSI 上に 1 つの PPE と 8 つの SPE (PLAYSTATION3 では 1 つが無効化されており 7 つの SPE が利用可能となってい る),さらに DRAM を搭載している.PPE (PowerPC Processor Element) は,Power 2.2 SIMD 型アクセラレータとしての GPU 18 アーキテクチャを基にした 2 スレッド同時実行可能なインオーダ型のプロセッサ PPU (PowerPC Processor Unit) を核とする,SPE の制御や外部デバイスへの入出力制 御等を受け持つ汎用プロセッサである.SPE (Synergistic Processor Element) は演 算専用のシンプルなプロセッサであり,核となる演算用ユニット SPU (Synergistic Processor Unit),SPU ごとのローカルメモリ LS (Local Store),メインメモリや他 の SPE との通信を行う MFC (Memory Flow Controller) から構成されている.PPE と SPE は EIB (Element Interconnect Bus) と呼ばれる高速なリングバスで接続さ れている.こうしたハードウェア構成から,Cell は異なる種類のコアを混載した “ 非対称型マルチコアプロセッサ” の一種であると言える.PPE と SPE をあわせて 200GFLOPS 程度の単精度浮動小数点演算性能を持つ. 図 6: Cell のハードウェア構成図 Cell に搭載された PPE は既存の CPU に近いハードウェアであるため,Linux な どの OS を動作させることが可能であり,また PPE のみを用いるプログラムであれ ば,既存の PowerPC アーキテクチャCPU 向けプログラムと同様に作成し実行する ことができる.しかしながら Cell の持つ高い演算性能を得るには,SPE を効果的に 活用できるようにプログラムを作成する必要がある. 2.2 SIMD 型アクセラレータとしての GPU 19 SPE を活用したプログラムを作成するには,C/C++言語と各コアの制御等を行 う専用のライブラリ (SDK) を用いる.CSX と同様に,PPE 上で動作するプログラ ムと SPE 上で動作するプログラムを個別のソースとして記述し,各々のプログラム から個別の実行ファイルを生成する.実行時には PPE プログラムから SPE プログ ラムを起動して利用する. PPE と複数の SPE との間のデータ転送を考慮したプログラミングの難しさや手間 を削減し,また PPE 向けのプログラムと SPE 向けのプログラムを個別に記述する手 間を削減するために,Cell 向けのコンパイラやライブラリについての研究がいくつか 行われている.IBM の XL C/C++ for Multicore Acceleration for Linux[54] は,マル チコア CPU や Cell に対応したコンパイラであり,OpenMP を用いたシングルソー スによる Cell プログラム開発も可能となっている.西 Barcelona Supercomputing Center の Cell Superscalar (CellSs)[55] も,OpenMP とは異なるが指示子の挿入によ るシングルソースでの Cell プログラム開発を可能としている.また電気通信大学で は POSIX スレッドを用いてシングルソースによる Cell プログラム開発を可能とす るプログラム変換ツールを提案している [56]. 2.3 プログラミング環境に関する研究の動向 2.3 20 プログラミング環境に関する研究の動向 GPU を用いることにより高い演算性能が得られる一方で,アプリケーションプロ グラマにとって GPGPU プログラミングが難しく手間がかかることは広く認識され ており,これまでに GPGPU プログラミングを容易にするためのプログラミング環 境に関する研究がいくつか行われてきた.またマルチコア CPU が普及し,今後さら に多数のコアを搭載した CPU の普及が見込まれていることから,高い並列性を持 つプログラムの容易な記述に向けた新しい並列化プログラミング環境に関する研究 も行われている.本節ではこれらのプログラミング環境について確認する. 2.3.1 GPU 向けのプログラミング環境 GPGPU プログラミングが難しい大きな要因として,ハードウェアアーキテクチャ への依存性が高い専用の言語やライブラリを用いる必要があることが挙げられる. ハードウェアアーキテクチャや言語仕様について学習する手間を削減し GPGPU を 容易に利用できるようにするには,ハードウェアアーキテクチャへの依存性が低く 汎用性・抽象度の高いプログラミング環境が必要である.そこで近年では,ハード ウェアアーキテクチャに依存しない新たなプログラミング環境に関する研究がいく つか行われている.これらの研究の中から本項では,ストリームプログラミング言 語,OpenCL,コンピュータビジョンアプリケーション用のプログラミング環境の 3 つについて確認する. ストリームプログラミング言語 ストリームプログラミング言語とは,“「ストリーム (stream) と呼ばれる入力デー タ」に対して「カーネル (kernel) と呼ばれる演算操作」を作用するものとみなすス トリーミングモデル” (図 7) に基づく処理 (ストリーム処理) を記述するためのプロ グラミング言語である.近年,GPU に適しており GPGPU による高速化が期待で きる問題としてストリーム処理が注目されており,GPU 向けストリームプログラミ ング言語の研究が行われている.以下にストリームプログラミング言語の例をいく つか挙げる. 米 Stanford University の BrookGPU [57] は,既存の C 言語を元に拡張を加えた 言語仕様といくつかのライブラリ関数を提供するオープンソースのストリーミング 2.3 プログラミング環境に関する研究の動向 21 図 7: ストリーミング言語の概念 言語である.BrookGPU を用いたプログラムの例を図 8 に示す.この例では,GPU 上で実行される並列計算部 (カーネル) が関数として独立に記述されていることや, カーネルの実行前後で streamRead および streamWrite という関数を用いて明示的 に入出力の指定が行われていることが確認できる.図中のカーネルでは 2 つの変数 を加算してもう 1 つの変数への代入を行っているが,各変数は配列であり,配列の 各要素に対する演算が GPU 上の多数の演算器によって独立に並列処理される. BrookGPU はカーネルを実行するバックエンドとして DirectX9,OpenGL,CPU, CTM に対応している.AMD 社が BrookGPU を元にして自社の GPU 向けのストリー ミング言語 Brook+[58] を開発しているが,これは BrookGPU の CTM をバックエ ンドとした実装をベースにしていると考えられる. 加 RAPIDMIND 社の RapidMind[59] は,加 University of Waterloo で開発された オープンソースのメタプログラミング言語 Sh[60] を元にしたストリーミング言語で ある.RapidMind を用いたプログラムの例を図 9 に示す.RapidMind も BrookGPU と同様にカーネルとカーネルへの入出力を明示的に指定していることが確認できる 一方で,BrookGPU によるカーネルの記述が既存の C/C++言語における関数の記 述に似た形式で行われていたのに対して,RapidMind によるカーネルの記述はより 独特な記述によって行われていることがわかる. RapidMind の特徴として,実行環境として CPU や GPU だけではなく Cell にも 対応している点が挙げられる.そのため単一の言語を用いて CPU・GPU・Cell 向け のプログラムを記述可能であり,アプリケーションプログラマにとっては実行環境 ごとにプログラミング言語を習得し直すという大きな手間が削減できると言える. 東北大学の SPRAT[61] は,実行時環境に特徴があるストリーミング言語である. 本研究のアプローチ 1 (3 章) で述べているように,GPGPU においては対象問題の 2.3 プログラミング環境に関する研究の動向 // カ ー ネ ル k e r n e l void k f u n c ( f l o a t x<>, f l o a t y<>, out f l o a t z<>){ z = x + y; } int main ( ) { f l o a t a<100>; f l o a t b<100>; f l o a t c <100>; // 入 力 ス ト リ ー ム の 指 定 streamRead ( a , data1 ) ; streamRead ( b , data2 ) ; // カ ー ネ ル の 実 行 kfunc ( a , b ) ; // 出 力 ス ト リ ー ム の 指 定 streamWrite ( c , r e s u l t ) ; return 0 ; } 図 8: BrookGPU を用いたプログラムの例 22 2.3 プログラミング環境に関する研究の動向 23 int main ( ) { // カ ー ネ ル Program k f u n c=BEGIN{ In<Value3f >x , y ; Out<Value3f >z ; z = x + y; }END; // 入 出 力 ス ト リ ー ム の 指 定 Array <1, Value3f >a ( 5 1 2 ) ; Array <1, Value3f >b ( 5 1 2 ) ; Array <1, Value3f >c ( 5 1 2 ) ; // カ ー ネ ル の 実 行 c = kfunc ( a , b ) ; return 0 ; } 図 9: RapidMind を用いたプログラムの例 計算量や並列度と,CPU と GPU の性能バランスによって,対象問題を CPU で実 行した方が高い性能が得られる場合と GPU で実行した方が高い性能が得られる場 合とがある.SPRAT の実行時環境はカーネルを CPU と GPU のどちらで実行した 方がより高い性能が得られるかを性能モデルや実測値から判断し,より高い性能が 得られるハードウェアを選択して実行するという機構を有している.SPRAT のプ ログラム記述方法は BrookGPU に近いものとなっている (図 10). OpenCL OpenCL Working Group が策定を行っている OpenCL[62] は,C 言語をベースと した並列処理向けのプログラミング環境である.OpenCL は GPU だけではなくや マルチコア CPU,Cell,DSP (Digital Signal Processor) など様々なハードウェアに おける並列処理を統一的に記述可能とすることを目指している. OpenCL は新しいプログラミング環境であり本論文執筆時点では対応するハード ウェアがまだ存在していないが,主な GPU ベンダである NVIDIA 社と AMD 社が それぞれ CUDA と Stream による OpenCL への対応を表明している.そのためアプ 2.3 プログラミング環境に関する研究の動向 // カ ー ネ ル k e r n e l k f u n c ( i n stream<f l o a t > x , i n stream<f l o a t > y , out stream<f l o a t > z ) { z = x + y; } int main ( ) { stream<f l o a t > s a ( 1 0 0 ) , sb ( 1 0 0 ) , s c ( 1 0 0 ) ; float a [100] , b [100] , c [ 1 0 0 ] ; // 入 力 ス ト リ ー ム の 指 定 init array ( a , b); streamRead ( sa , a ) ; streamRead ( sb , b ) ; // カ ー ネ ル の 実 行 k f u n c ( sa , sb , s c ) ; // 出 力 ス ト リ ー ム の 指 定 streamWrite ( sc , c ) ; return 0 ; } 図 10: SPRAT を用いたプログラムの例 24 2.3 プログラミング環境に関する研究の動向 25 リケーションプログラマは OpenCL を用いることにより様々な GPU 向けのプログ ラムを C 言語に近い単一のプログラム記述によって行うことが可能となり,習得や 利用の手間と難しさが削減されることが期待できる. コンピュータビジョンアプリケーション用のプログラミング環境 GPU の用途の 1 つとして,コンピュータビジョンアプリケーションにおける新 たな表現手法の実装や高速化 [63] が挙げられる.この分野のアプリケーションは GPU 本来の処理である画像描画に関する処理を多く含むが,処理内容が高度化して いるため,汎用演算と同様に習得や実装の手間や難しさが問題となっている.そこ で,コンピュータビジョンアプリケーションの開発を支援するシステムの研究開発 が行われている.研究開発されたシステムの例としては,北陸先端技術大学院大学 の EasyGPU[64] や,加 University of Toronto の OpenVIDIA[65],仏 University of Lyon の GPUCV[66] などが挙げられる.いずれのシステムも,フィルタ処理などコ ンピュータビジョンアプリケーションで利用される処理を容易に記述可能とするこ とで,アプリケーションプログラマに対する GPU プログラミングの習得や利用の 手間と難しさの削減を可能としている. 2.3.2 CPU 向けのプログラミング環境 近年ではマルチコア CPU の普及やマルチコア CPU に搭載されるコア数の増加 (メニーコア化) が進んでいる.そのためマルチコア CPU 上で高い性能を得られる プログラムの作成方法や,マルチコア CPU に適したプログラムを容易に作成する ためのプログラミング環境に関する研究が盛んに行われている. マルチコア CPU 向けの並列化プログラミング環境に関する研究の例は多く存在 するが,特に,計算機を提供するベンダーが策定や提供に影響力を持つ言語 (IBM の X10[67],Cray の Chapel[68],Sun の Fortress[69]) や広く普及している既存のプ ログラミング言語に対する拡張仕様など (C 言語に対する Unified Parallel C[70] や, Fortran に対する High Performance Fortran[71] や Co-Array Fortran[72]) は他の言語 と比べると多くの利用者を獲得し今後の並列化プログラミングにおける主流となる 可能性が高く,また並列化プログラミングのトレンドに影響を及ぼす可能性がある. 例えば,これらのマルチコア CPU 向け並列化プログラミング環境のいくつかは, スレッドとメモリとの対応付けをアプリケーションプログラマが明示的に記述する 2.3 プログラミング環境に関する研究の動向 26 Partitioned Global Address Space (PGAS) モデルを採用している.PGAS モデルを 採用したプログラミング環境では,変数や配列などのデータに対して,そのデータ をスレッド (プロセス) ごとに独立して持つものとして扱うべきか,スレッド間で共 有して持つものとして扱うかを,コンパイラに対する指示子や専用の変数宣言を用 いて指定する.これらの指定により,アプリケーションプログラマはデータの分散 配置や通信を容易に指示することが可能となり,またコンパイラや実行時環境によ る高度な最適化も可能となることが期待されている. さらに,メモリの分散配置を記述するプログラミング環境としては,共有メモリ 型並列計算機向けのプログラミング環境である OpenMP に対してメモリの分散配置 に関する記述が行えるように拡張を行った OpenMPD[73] なども挙げられる. 一方,対象問題の持つ並列性を容易に記述するための並列化プログラミング環境 についての研究も行われている. スケルトン並列プログラミングは,並列スケルトンと呼ばれる並列処理における 頻出計算パターンを抽象化したライブラリ関数の組み合わせによる並列化プログラ ミング手法である.スケルトン並列プログラミングの利点としては,アプリケーショ ンプログラマに対して低レベルの並列化実装を隠蔽することが可能であり,並列計 算の知識を持たなくても高性能な並列処理プログラムを作成できることなどが挙げ られている [74].スケルトン並列プログラミング環境の例としては,東京大学の助っ 人 (SkeTo) [75] などが挙げられる. 配列の各要素に対する処理や繰り返し処理を記述しやすい言語仕様を持つ並列化 プログラミング環境に関する研究も行われている.近年の研究例としては,東芝社 の配列切り出し演算子を備えた配列処理向け言語 [76] 等が挙げられる.これらのプ ログラミング環境の利点としては,ループ記述を行うことなく繰り返し処理を表現 できるため多重ループ処理の可読性が高いことや,最適化に用いる情報を抽出しや すく抽象度の高い言語仕様としているため最適化が行いやすいことなどが挙げられ ている. 2.4 SIMD 型アクセラレータやプログラミング環境に関する研究と本研究との関 係 27 2.4 SIMD 型アクセラレータやプログラミング環境に関する研究と 本研究との関係 本研究ではアプリケーションプログラマにとって GPGPU を容易に利用できるよ うにするため “並列計算ライブラリ” と “並列化プログラミング環境” の 2 つのアプ ローチを提案している. 本研究のアプローチ 1 (3 章) では,CPU と GPU による適切な問題分割・並列実 行を行うライブラリを提案し,最適な性能を得るための性能パラメタや実装につい て論じている. CSX は拡張バスを通して CPU と接続して利用されるアクセラレータカードであ ること,カード上にメインメモリとは別のメモリを搭載していることなどが GPU と共通している.CSX 上で動作する数値計算ライブラリが提供されているが,CSX に搭載されている演算器は GPU よりさらに低速なため,対象問題のデータ規模が 小さい場合などに単純に CSX 用のライブラリを利用しただけでは性能が低下してし まう可能性が高い.そのため,対象問題のデータ規模にあわせて CPU のみでの実行 と CPU と SIMD 型アクセラレータによる適切な問題分割・並列実行を切り替える 機構を持つライブラリという本研究で提案するアプローチは,CSX でも有効に活用 できると考えられる. なお,CSX に対して ClearSpeed 社が提供しているライブラリの中には,本アプ ローチのようにライブラリ内部で CPU と CSX で問題分割を行うライブラリも含ま れている.本アプローチは GPGPU において適切な問題分割・並列実行を行うライ ブラリの有効性を示すとともにライブラリを作成するための方法を示している.そ のため,GPU と CSX それぞれにおけるライブラリの実装方法や最適化方法の比較 を行い,CPU と SIMD 型アクセラレータにより適切な問題分割・並列実行を行うラ イブラリの作成方法や最適化方法の研究が進むことで,今後新たな SIMD 型アクセ ラレータが開発された際に同様のライブラリを作る場合に成果が活用可能となると 考えられる. Cell は,Cell 自体が汎用プロセッサとアクセラレータを含むハードウェアである ため,CSX と比べると GPU とは異なる部分が多いハードウェアアーキテクチャお よび実行モデルであるが,PPU と SPU での問題分割等に本アプローチで行った問 2.4 SIMD 型アクセラレータやプログラミング環境に関する研究と本研究との関 係 28 題分割・並列実行の実装方法や性能パラメタが利用できることが期待できる. 本研究のアプローチ 2 (4 章) では,既存の CPU 向け並列化プログラミング環境を 用いた GPGPU 向けのプログラミング環境を提案している. Cell については,本アプローチと同様に既存の並列化プログラミング環境を用いて プログラミングを行うためのコンパイラなどの研究が進んでいることを述べた.こ れは現在の SIMD 型アクセラレータ向けプログラミングがアプリケーションプログ ラマにとって難しく手間がかかること,既存の並列化プログラミング手法を用いた SIMD 型アクセラレータ向けプログラミングの需要・要求が高いことを示している. OpenMP を用いた Cell プログラムの開発を可能としている XL C/C++ for Multicore Acceleration for Linux の実装については,SPE は DMA によって Cell 上の大 容量メモリを任意のタイミングで送受信できるため実行時に動的なデータ転送を行 い共有メモリの管理を行っている.一方で OMPCUDA の実装では CPU-GPU 間で データ送受信を行うことが可能なタイミングが限定されていることから,コンパイ ル時に並列実行部で必要となるデータを確認して並列実行の前後に CPU-GPU 間で 送受信しており,実装が異なっている. 本アプローチによる OMPCUDA の実装は,CPU と Cell に加えて GPU において も共通の並列化プログラミング手法 (OpenMP) を用いた並列化プログラミングを 可能とするものである.様々な環境において共通のプログラム記述を用いられるこ とは,アプリケーションプログラマにとって習得の手間が削減できるため有意義で ある. ストリームプログラミング言語はいずれも GPU のアーキテクチャをストリーム 処理という概念で抽象化しているため,アプリケーションプログラマはストリーム プログラミング言語を利用することでハードウェアアーキテクチャに関する知識が なくても GPU 向けの並列処理プログラムを作成することができる.また言語仕様 については,多くのストリームプログラミング言語が C/C++言語を元に拡張を行っ たものであるため,C/C++言語に慣れ親しんだアプリケーションプログラマが比較 的容易に習得・利用できると述べられている. しかしながらストリームプログラミング言語の言語仕様や実行モデルは,C/C++ 言語と似てはいるものの同一ではないため,アプリケーションプログラマにとって は習得に手間がかかる.また共通化された言語仕様等があるわけではないため,い 2.4 SIMD 型アクセラレータやプログラミング環境に関する研究と本研究との関 係 29 ずれかの言語を習得すれば他の言語も利用できるわけではない.新しいプログラミ ング言語は,ユーザが少ないためマニュアルやノウハウの蓄積が難しく,マニュア ルやノウハウの蓄積が少ないとユーザが増えにくい可能性があり,ユーザ獲得にお ける悪循環となる可能性がある. 一方で本研究は,アプリケーションプログラマにとっての習得の手間や難しさを 重視し,既に普及している CPU 向けのプログラミング環境を用いた GPGPU プロ グラミングに注目していることから,ストリームプログラミング言語とは立場が異 なっている. OpenCL は,OpenCL を策定している Working Group に多くの企業,特にそれぞれ が独自の GPGPU プログラミング環境を提供していた主要な GPU ベンダ (NVIDIA 社と AMD 社) が対応を表明していることなどから,今後の GPGPU プログラミング の主流となることが期待されている.また OpenCL は GPU のみならず様々なハード ウェアにおける並列処理を記述できるため,アプリケーションプログラマは OpenCL さえ習得すれば様々なハードウェア向けのプログラムが作成可能となることが期待 できる. 一方で OpenCL は様々なハードウェアにおいて利用できるようにするため,特徴 的な実行モデルやメモリモデルを定義している.これらのモデルは既存の CPU 向け プログラミング環境と比べて複雑であるため,多くのアプリケーションプログラマ にとって習得や利用の手間と難しさが削減されるとは言い難い.そのため,OpenCL が実際に多くのシステムで利用可能になった後も,多くのアプリケーションプログ ラマが容易に利用可能なプログラミング環境への要求がなくなることは考えにくい. むしろ OpenCL が普及した場合には,OpenCL による様々なハードウェアへの対応 とアプリケーションプログラマに対する習得や実装の容易さを両立させるために,既 存の CPU 向け並列化プログラミング環境を用いて記述されたプログラムを OpenCL 向けのプログラムに変換する機構が有用となることが考えられる. コンピュータビジョンアプリケーション用のプログラミング環境など特定用途向 けのプログラミング環境は,GPU のハードウェアアーキテクチャに関する知識の習 得を不要としたり,対象とする特定のアプリケーションを容易に作成しやすくする など,それぞれ独自の視点でアプリケーションプログラマにとっての手間の削減を 行っている. 2.4 SIMD 型アクセラレータやプログラミング環境に関する研究と本研究との関 係 30 しかしながらこれらのライブラリやプログラミング環境は新たなプログラミング モデルや新たな言語仕様を作成するものであり,アプリケーションプログラマにとっ て新しい知識や技術を習得する手間の増加を問題視している本研究とは立場が異なっ ている. マルチコア CPU の普及により CPU 向けの新たな並列化プログラミング環境に関 する研究が盛んとなっているが,本研究は既存の CPU 向け並列化プログラミング環 境を利用することでアプリケーションプログラマに対する習得の手間の削減を目指 す研究であるため,これらの新たな並列化プログラミング言語とは直接関係がない. しかしながら GPGPU プログラミングにおいては多数の演算器を活用することが 重要であることから,多数のコアを搭載した CPU を活用するために提案された新 たな並列化プログラミング環境は,既存の CPU 向けプログラミング環境と比べて GPGPU プログラミングに適していると考えられる.また PGAS モデルのプログラ ミング環境などにおけるメモリの分散配置の記述は,GPGPU プログラムにおける メインメモリと GPU 上のメモリとの分散配置の記述や,GPU 上の複数種類のメモ リに対するデータの分散配置の記述に利用することで,容易に高性能な GPGPU プ ログラムを記述できるようになることが期待できる. 一方で,これまでにもアセンブラを用いて手動最適化されたプログラムと高級言 語で記述されコンパイラにより最適化されたプログラムに対して盛んに議論が行わ れてきたように,プログラミングの難しさと得られる性能についてはトレードオフ となる部分もある.本研究ではアプリケーションプログラマにとっての手間や難し さを削減することを重視し,既存の CPU 向け並列化プログラミング環境を用いた GPGPU プログラミングを提案して研究を行った.しかし本研究の目的やアプロー チとは立場が異なるものの,CPU 向けの新たな並列化プログラミング環境を用いた GPGPU プログラミングについて検討することや,GPGPU 向けの新たなプログラ ミング環境を提案することは,アプリケーションプログラマが GPU の性能をより 容易に活用できるようにするうえでは重要であると言える. 31 並列計算ライブラリによるアプローチ 3 本章では,GPU を用いて計算を行う並列計算ライブラリを提供することでアプリ ケーションプログラマに対して並列化プログラミングそのものを隠蔽するアプロー チを提案する.はじめに本提案の着眼点である CPU と GPU を用いて問題分割・並 列実行を行うライブラリの概要を述べ,次にライブラリの実装方法について述べる. さらに,提案を元に作成したライブラリ “GPUPC GEMM Library” の設計と実装に ついて述べ,テストプログラムやベンチマークプログラムを用いて評価を行う. 3.1 CPU と GPU を用いて問題分割・並列実行を行うライブラリの 提案 本節では,“CPU 単体で実行されるライブラリと同様の API を持ちながら CPU と GPU による適切な問題分割・並列実行を行う機構を持つ” ライブラリを提案する. 2.1 節で述べたように,GPGPU プログラミングを行うためには GPU のアーキテ クチャや GPGPU プログラミング環境に関する知識と理解が必要であり,アプリケー ションプログラマにとって大きな手間となっている. 一方で,プログラムの再利用を容易にするとともに習得が難しく手間のかかる最 適化プログラミングを隠蔽可能な計算ライブラリが広く利用されている.特にアプ リケーションプログラマにとっての計算ライブラリは,ライブラリインターフェイ ス (アプリケーションプログラミングインターフェイス:API) さえ理解していれば 対象アプリケーションで用いるアルゴリズムに関する理解がなくてもライブラリの 提供する機能を利用することで正しく動作するプログラムを作成可能であることや, 様々な環境向けに最適化された同一の API を持つライブラリがあれば実行環境の違 いについて気にすることなく同じ機能と高い性能を得られることが,アプリケーショ ンの実装における手間を大きく削減するのに役立っている. そこで,GPGPU プログラミングの手間を削減し,アプリケーションプログラマ が GPU を容易に利用できるようにする方法として,CPU 向けの既存の計算ライブ ラリと同様の API を持つ GPU 向けの計算ライブラリを提供することを考える.こ れによりアプリケーションプログラマはリンクするライブラリを切り替えるのみで 3.1 CPU と GPU を用いて問題分割・並列実行を行うライブラリの提案 32 GPU の持つ高い演算性能を利用可能となることが期待できる. 典型的な GPGPU プログラムにおいて GPU を使用する際には,初めに GPU の 初期化や GPU 上で実行されるプログラムの準備を行い,次に CPU から GPU への データ転送を行い,さらに CPU から GPU に対して演算開始を指示し,最後に GPU の演算終了を待って GPU から CPU へ演算結果を転送するという手順で処理を行う 必要がある (図 11). 図 11: 典型的な GPGPU プログラムの処理手順 しかしながら,単純にこれらの処理をライブラリとしてまとめて既存の CPU 向 けのライブラリと同様に利用する場合,次の 2 つの課題を解決しなくては高い性能 が得られないという問題が生じてしまう. 3.1 CPU と GPU を用いて問題分割・並列実行を行うライブラリの提案 33 問題 1. GPU 上での実行に適さない問題設定に関する課題 GPU は既存の CPU と比べて多数の演算器を搭載しているために並列性が高い問 題を高速に実行できる一方,GPU に搭載されている各演算器単体と CPU との性能 を比較すると,CPU の方がクロック周波数が高く演算性能も高い.そのため,対象 問題の並列性があまり高くない場合には GPU より CPU の方が短い実行時間で対象 問題を解くことができる. また,GPU を用いて演算を行うには CPU を用いて GPU を制御する必要があり, CPU-GPU 間のデータ転送を行う必要もある.そのため,対象問題の並列性が高く ても演算対象のデータ規模が小さいなどの理由で対象問題の絶対的な処理時間が短 い場合には,GPU を制御するオーバヘッドや CPU-GPU 間でのデータ送受信によ るオーバヘッドが実行時間全体に占める割合が大きくなり,GPU は CPU と比べて あまり高い性能を得ることができないことや CPU より低い性能となることがある. そのため,実行環境の CPU と GPU の性能バランスや演算対象のデータ規模に応 じて性能向上が期待できる場合にのみ GPU を利用する機構を持つライブラリが有 用であることが考えられる. 問題 2. CPU-GPU 間での負荷分散に関する課題 CPU と GPU は独立した計算ハードウェアであり,適切なプログラム記述を行え ば CPU と GPU で同時に演算を行うことができる.そのため対象問題が CPU でも GPU でも高速に処理できる場合は,対象問題を分割し CPU と GPU で並列に実行 すれば,さらに高い性能を得られることが期待できる.また対象問題の計算量が十 分に大きく実行時間が長い場合には,CPU と GPU の性能に差がある場合でも対象 問題を適切に分割し並列実行することで CPU のみや GPU のみよりも高い性能を得 られることが期待できる. しかしながら,単に CPU-GPU 間のデータ送受信や GPU での演算をまとめたラ イブラリが提供されている場合,ライブラリを利用するアプリケーションプログラ マ自身が CPU と GPU で問題分割・並列実行するプログラムを作成する必要がある. そのようなプログラムを作成するにはマルチスレッドプログラミングなどアプリケー ションプログラマにとって手間のかかるプログラミングを行う必要が生じ,API に 3.1 CPU と GPU を用いて問題分割・並列実行を行うライブラリの提案 34 より隠蔽されているため利用が容易であるというライブラリの利点が損なわれてし まう. そのため,対象問題を適切な割合で分割し CPU と GPU で並列実行する機構を持 つライブラリが有用であることが考えられる. そこで本アプローチでは,“CPU 単体で実行されるライブラリと同様の API を持 ちながら,対象問題のデータ規模が小さい場合には CPU のみで演算を行い,データ 規模が大きい場合には CPU と GPU の性能バランスにあわせて CPU と GPU で適 切な問題分割・並列実行を行う機構を持つ並列計算ライブラリ” を提案する.アプ リケーションプログラマにとってこの提案は,GPGPU 環境を容易に利用できるこ とと,常に高い性能を得られることの両方が達成できる提案である. 3.2 CPU と GPU を用いて問題分割・並列実行を行うライブラリの実装 3.2 35 CPU と GPU を用いて問題分割・並列実行を行うライブラリの 実装 本節では,前節で提案したライブラリの実装についての検討を行う. 本節におけるライブラリの実装では,グラフィックス API とシェーダ言語,具体 的には “DirectX 9 (以下 DirectX) と HLSL” もしくは “OpenGL と GLSL” を用いる こととする.グラフィックス API とシェーダ言語を用いてプログラムを作成する理 由は,作成したプログラムが多くの GPU で利用可能であることと,本アプローチ に基づく提案と実装を行った時点では CUDA や CTM など GPGPU 向けの低レイヤ なプログラミング環境が存在していなかったことによるものである. また本ライブラリは,GPU を搭載した計算機システムの最も基本的な構成であ る,1 個つのシングルコア CPU を搭載した計算機に 1 枚の GPU を搭載した 1 台の 計算機からなる計算機システムを基本的な対象計算機システムとする.しかしなが ら,今日ではマルチコア CPU を搭載した計算機システムや複数の GPU を搭載可能 な計算機システムの普及が進みつつあることから,複数の CPU ないしマルチコア CPU や複数の GPU を搭載した計算機システムについても発展的な対象計算機シス テムとする. 以下本節では,提案したライブラリに必要な,CPU と GPU を用いた並列処理の 実装方法と,CPU と GPU による適切な問題分割を行うための仕組みについて述べ る.さらに発展的な対象計算機システムである複数の CPU や複数の GPU を搭載し た計算機システム向けの実装について述べる. 3.2.1 CPU と GPU を用いた並列処理の実装 CPU と GPU を用いて並列処理を行うための基本的な考え方は,GPU が描画 (演 算) を行っている間に CPU でも演算を行うというものである. DirectX や OpenGL を用いて GPU に対する描画開始指示や演算データの送受信指 示を行うには,各グラフィックス API が提供する API 関数を利用して対応する処理 を記述する必要がある.これらの処理の多くは非同期に実行される関数によって記 述することが可能であり,DirectX・OpenGL ともに GPU に対する描画開始処理を 行う関数は非同期関数である.そのため描画開始処理に続いて描画終了処理を待た 3.2 CPU と GPU を用いて問題分割・並列実行を行うライブラリの実装 36 ずに CPU による演算を記述すれば CPU と GPU による並列処理を行う事ができる. またプログラム記述に関しては,CPU による演算と GPU による描画 (演算) を別の スレッドとして記述すれば,CPU による演算に関する記述と GPU による演算に関 する記述が明確に分離された可読性の高いプログラムが作成できると考えられる. しかしながら,スレッドによる記述を用いて CPU と GPU による並列処理を記述 する際に,以下のような問題が発生した. CPU が GPU から演算結果を取得する際には,CPU は GPU の描画終了を待つ必 要がある.しかし,OpenGL を利用した GPU プログラムにおいて CPU が GPU の 描画結果を取得する際に実行する必要がある API 関数の 1 つは,GPU の描画が終 了する前に CPU によって呼び出された場合に GPU の描画が終了するまで CPU へ 制御を戻さないばかりか,GPU の描画が終了するのを待つ間は常に CPU の利用率 を 100%にしてしまうことが判明した.そのため,CPU による演算と GPU に関す る演算を別のスレッドとして記述した場合に,CPU による演算を行っているスレッ ドと GPU が演算を終えるのを待っているスレッドの 2 スレッドが同時に CPU を利 用しようとしてしまうため,CPU による演算の性能が低下するという問題が発生し た (図 12). このような問題を避ける方法は,マルチスレッドプログラムを作成するのではな く,CPU による演算が終了してから GPU の演算終了を待つよう明示的に記述され たシングルスレッドプログラムを作成することである. 以上の検討に基づき,本章では図 11 に対して CPU が行うべき処理がない部分に CPU による演算を加えた図 13 に示す構造のライブラリを実装することにした.演 算結果受信から “反復計算が必要な場合など” の矢印が 2 本出ているのは,対象問題 によっては再度演算を行うことや再度問題分割し直してから演算を行うことも考え られるためである. 3.2.2 CPU と GPU による適切な問題分割を行うための仕組み 対象問題のデータ規模がどの程度大きければ問題分割・並列実行の効果によって 良い性能が得られるかや,CPU と GPU に対する最適な問題分割割合はどの程度か といった性能パラメタは,対象問題のアルゴリズムだけではなく実行環境の CPU と GPU の性能バランスにも大きく依存する.そのため本アプローチに基づいて作成し 3.2 CPU と GPU を用いて問題分割・並列実行を行うライブラリの実装 図 12: スレッドを用いた並列実行の失敗例 37 3.2 CPU と GPU を用いて問題分割・並列実行を行うライブラリの実装 図 13: 提案するライブラリの構造 38 3.2 CPU と GPU を用いて問題分割・並列実行を行うライブラリの実装 39 たライブラリは,対象環境毎に異なる CPU と GPU の性能バランスに合わせた適切 な問題分割・並列実行を行わなくては良い性能を得ることができない. このような性能パラメタの確認 (性能チューニング) は,アプリケーションプロ グラマにとって大きな手間となる可能性が高い.特に,アプリケーションプログラ マが GPU のアーキテクチャなどライブラリにより隠蔽されるはずであった知識を 習得しなくては性能チューニングが行えないようでは,ライブラリによってアプリ ケーションプログラマに対して実行環境を隠蔽するというメリットが失われてしま う.そのため,GPU のアーキテクチャなどに関する知識がなくても性能パラメタを 求めることのできる機構が望まれる. 例えば CPU 向けにベクトルや行列に関する演算を提供するライブラリ ATLAS[77] では,ライブラリをインストールする際にチューニングを行う機構 (自動チューニ ング機構 [78]) を備えている.ATLAS の備えるチューニング機構は,CPU アーキテ クチャや利用するコンパイラ等いくつかの簡単なパラメタを指定すると,キャッシュ サイズなどの演算性能に影響を与えるハードウェア情報を自動的に収集し,また単 純に収集できない情報についてはベンチマークを行い特定したりする機能を持って いる.こうして得られたハードウェア情報を反映したライブラリがインストールさ れるため,アプリケーションプログラマは利用しているハードウェア (CPU やメモ リ) に関する深い知識がなくても常に最適な性能を得ることができる. 本アプローチにおいては,対象問題のデータ規模が小さい場合には CPU のみで 演算を行うこと,データ規模が大きい場合には CPU と GPU の性能バランスにあわ せて CPU と GPU で適切な問題分割・並列実行を行うこと,の 2 点が重要である. そのため,ライブラリを利用する計算機システムに搭載された CPU と GPU の性能 バランスではどのようなデータ規模の問題を CPU のみで実行し,またどのような データ規模の問題をどのような割合で CPU と GPU に分割すれば高い性能が得られ るのかを判断する機構と,判断結果に基づいて実行する機構を作成することで,ア プリケーションプログラマがチューニングを行う手間が削減できると考えられる. そこで,様々な問題サイズの対象問題に対して様々な問題分割割合で性能を測定 し CPU のみで実行した方が高い性能が得られるデータ規模や適切な問題分割割合 を求める “チューニングスクリプト” と,チューニングスクリプトによって求められ たパラメタを用いて CPU のみでの実行・GPU のみでの実行・CPU と GPU による 3.2 CPU と GPU を用いて問題分割・並列実行を行うライブラリの実装 40 並列実行から最も高い性能が得られるものを選択する “問題分割機構” によって適切 な問題分割を行うこととする.これによりアプリケーションプログラマは,ライブ ラリのインストール時にチューニングスクリプトを実行しておくことで,ライブラ リ利用時にはチューニングスクリプトによって得られたパラメタに基づき常に高い 演算性能を得ることが可能となる. 実際にどのようなチューニングスクリプトを作成するべきかは対象問題による部 分が大きいため,3.3 節にて改めてチューニングの内容を述べる. 3.2.3 複数の CPU や複数の GPU を搭載した計算機システム向けの実装 現在では多くの計算機環境で複数のコアを搭載した CPU や複数の CPU を搭載し た計算機システムが利用されていることは既に述べた通りであるが,複数の GPU を搭載した計算機システムの構築も可能である.GPU は主に PCI-Express で CPU (マザーボード) と接続して利用されており,マザーボード上に GPU に対応した PCI-Express バスが複数本搭載されていれば複数の GPU を利用することができる. (PCI-Express x1 などレーン数の少ない PCI-Express バスではほとんどの GPU を利 用することができない.) そこで,ここでは複数の CPU (マルチコア CPU) や複数 の GPU を搭載した計算機システムへの対応についても検討を行うことにする. GeForce や Radeon には SLI[79] や CrossFire[80] といった複数の GPU を用いて描 画性能を向上させる機構も存在する.これらの機構を用いるとソフトウェアからは あたかも複数の GPU が統合されて 1 台の高性能な GPU が搭載されているかのよう に見えるようになり,複数の GPU が搭載されていることを考慮していないアプリ ケーションでも複数の GPU の性能を足しあわせた性能で動作 (描画) させることが 可能となる.しかしながら,これらの機能を用いても本アプローチにおける性能評 価では全く性能が向上しなかったため,ここでは扱わないものとする. 複数の CPU が搭載された計算機環境で GPU を利用する方法としては,いくつか の実装が考えられる. 例えば,マルチスレッドプログラムを作成し,1 つのスレッドは 1CPU+1GPU の 時と同様に GPU の制御と CPU による演算を行い,他のスレッドでは演算のみを行 うという実装が考えられる (図 14). 3.2 CPU と GPU を用いて問題分割・並列実行を行うライブラリの実装 41 また別の実装例としては,CPU による計算を複数の CPU に対応した外部の計算 ライブラリに行わせるという実装が考えられる.この場合,問題分割の際に CPU が 複数あることを踏まえた割合で分割を行い,複数 CPU による演算自体は外部の計 算ライブラリに行わせるというのは,複数の CPU を活用しつつ GPU も利用できる 比較的容易な実装である (図 15).例えば 1CPU+1GPU では CPU 1 : GPU 1 に等 分割していたものを,2CPU+1GPU では CPU 2 : GPU 1 の割合に分割すればある 程度高い性能が得られると期待できる. 一方グラフィックス API を用いて複数の GPU を利用する方法については以下の 通りである. DirectX では,各種 API を利用する際に各 GPU に対応するクラスインスタンス を指定する.GPU 数分のクラスインスタンスを生成し,適切にパラメタ設定をして おくことで,複数の GPU を利用することができる.そのため,API の呼び出しを GPU の数だけ増やし,問題分割時の割合等を複数 GPU にあわせて変更すれば,複 数 GPU に対応することができる. 一方 OpenGL では,1 プロセスあたり 1 つの GPU しか利用することができない. 1 つのプログラムで複数の GPU を扱うにはマルチプロセスプログラムを作成する 必要があり,問題分割・並列実行するためにはプロセス間でのデータ共有が必要で ある. しかしながら,例えば 2CPU+2GPU の環境において,GPU を制御するためのプ ロセスを 2 つ,CPU で演算を行うためのプロセスを 2 つの合計 4 プロセスを用いて 並列処理を行ったとする.この場合,図 16 に示すように CPU が演算を終える前に GPU への演算結果要求が行われてしまい,GPU を待つプロセスが CPU に負荷をか けることで CPU の演算が遅くなり,全体として実行時間が延びてしまう可能性が 高い. この問題に対しては次に述べるような実装を行うことで解決可能であることを確 認した. GPU に関する処理は GPU 数分の子プロセスを生成してそれぞれの子プロセスに 行わせ,CPU による演算は親プロセス上で CPU 数 (コア数) と同じだけのスレッド を生成しマルチスレッド実行する.この際,プロセス間通信を用いるなどして実行 順序の制御を行い CPU による演算と CPU から GPU への演算結果要求が同時に起 3.2 CPU と GPU を用いて問題分割・並列実行を行うライブラリの実装 図 14: 複数 CPU を用いた実装の例 1 42 3.2 CPU と GPU を用いて問題分割・並列実行を行うライブラリの実装 図 15: 複数 CPU を用いた実装の例 2 43 3.2 CPU と GPU を用いて問題分割・並列実行を行うライブラリの実装 44 こらないようにする.プロセス間のデータ共有に共有メモリを利用し,共有メモリ のデータ更新を通知するために unix socket を用いた場合の処理手順を図 17 に示す. プロセス間のデータ共有については,GPU に関する処理を行う子プロセスと CPU によるマルチスレッド演算を行う親プロセスとでデータのやりとりができれば良い ため,共有メモリを利用せずにプロセス間通信で代用しても良い. 次節で述べる複数 CPU および複数 GPU 向けの実装では,以上の検討結果に基づ く実装を行う. 3.2 CPU と GPU を用いて問題分割・並列実行を行うライブラリの実装 図 16: 複数 CPU と複数 GPU を用いた実装の例 1 45 3.2 CPU と GPU を用いて問題分割・並列実行を行うライブラリの実装 図 17: 複数 CPU と複数 GPU を用いた実装の例 2 46 3.3 GPUPC GEMM Library : CPU と GPU を用いて問題分割・並列実行を行う 行列計算ライブラリ の設計と実装 47 3.3 GPUPC GEMM Library : CPU と GPU を用いて問題分 割・並列実行を行う行列計算ライブラリ の設計と実装 本節では,本アプローチに基づき CPU と GPU を用いて問題分割・並列実行を行 う行列計算ライブラリ “GPUPC GEMM Library” の提案と実装について述べる. 3.3.1 ライブラリが対象とする範囲 “GPUPC GEMM Library” は行列積和計算を対象とした並列計算ライブラリで ある. 行列積和計算は,行列 A,B,C およびスカラー α,β に対して C = α ∗ A ∗ B + β ∗ C と いう演算を行い行列 C を更新する計算であり,多くのアプリケーションで利用され ている基本的な計算の 1 つである.行列やベクトルに関する関数インターフェイスを まとめたライブラリ BLAS (Basic Linear Algebra Subprograms) [81, 82] の GEMM 関数 (図 18) として知られており,科学技術計算アプリケーションをはじめとした多 くのプログラムで利用されている.世界中の計算機の性能を順位付けする TOP500 [83] で用いられている HPL (High-Performance Linpack) ベンチマーク [84] に用い られている計算としても知られている. CPU 向けの高速な行列積和計算の実装としては,GPUPC GEMM Library でも 利用されている ATLAS や,GotoBLAS[85] が広く用いられている. GPGPU においても行列積和計算 (行列積) はしばしば取り上げられている.プロ グラマブルシェーダが登場する前の GPU においては描画機能を用いた数値計算の 例として [20],またプログラマブルシェーダが普及し GPGPU への注目が高まるに つれてプログラマブルシェーダを用いた数値計算の高速化の例や GPU の性能評価 の題材として数多く取り上げられてきた [86, 87, 88] .行列積和計算はデータ量に対 して演算量が多く,並列性も高いため,GPU による高速化が期待できる問題である と言える. 行列積和計算は反復計算等のない単純な問題であるものの,問題のデータ規模が 大きくなるにともない実行時間が増加しやすいため高速化の要求が大きく,並列性 が高いため GPU を用いることで比較的単純な実装でも高速化の効果が得やすく,さ 3.3 GPUPC GEMM Library : CPU と GPU を用いて問題分割・並列実行を行う 行列計算ライブラリ の設計と実装 48 ¶ ³ void cblas ♦gemm const enum CBLAS ORDER Order const enum CBLAS TRANSPOSE TransA const enum CBLAS TRANSPOSE TransB const int M const int N const int K const SCALAR alpha const TYPE *A const int lda const TYPE *B const int ldb const SCALAR beta TYPE *C const int ldc ただし,♦ には TYPE と SCALAR の型を規定する1文字が,TYPE および SCALAR には ♦ によって定められたデータ型が使われる.これらの対応は下 記のとおりである. 文字 TYPE SCALAR 意味 s float float d double double 倍精度浮動小数に対する演算 c void void* 単精度複素数に対する演算 g void void* 倍精度複素数に対する演算 単精度浮動小数に対する演算 µ ´ 図 18: BLAS における GEMM の関数定義 3.3 GPUPC GEMM Library : CPU と GPU を用いて問題分割・並列実行を行う 行列計算ライブラリ の設計と実装 49 らに次項で述べるように問題分割が容易であるため,本アプローチを用いたライブ ラリの対象問題とした. なお GPUPC GEMM Library は CPU や GPU 単体での性能を追求するのが目的 ではないため,CPU 上での行列積和計算は既存のライブラリ ATLAS を用いて実行 することとし,GPU 上での行列積和計算については後述するようなある程度の高速 化手法を適用したグラフィックスプログラミングを用いて実装している. 3.3.2 ライブラリの設計と実装 本項ではライブラリの設計と実装について,以下のことを述べる. 1. GPU を用いた行列積和計算の実装方法 2. CPU と GPU による問題分割・並列実行の実装方法 3. チューニングスクリプト 4. 複数 CPU や複数 GPU を搭載した計算機システム向けの実装 5. 倍精度浮動小数点演算への対応 6. メモリ容量に基づく問題サイズの制限 7. 行列データの転置や ORDER といった BLAS のパラメタへの対応 なお,実装には OpenGL と GLSL を用い,実行環境は Linux とした.これは評価 に用いる HPL ベンチマークの実行環境として Linux が適していることおよび Linux 向けのグラフィックスプログラミングには OpenGL と GLSL が適していることによ る選択である. GPU を用いた行列積和計算の実装方法 GPUPC GEMM Library における GPU を用いた行列積和計算については,Fatahalian らによる行列積の実装 [86] を用いた. この実装は行列 C の縦横サイズに対応した大きさの描画先テクスチャを用意し, ピクセル毎にシェーダプログラムを用いて行列積和計算を行うものである.図 19 に 示すように長さ 4 のベクトルをまとめて処理する高速化手法を取り入れた実装では 3.3 GPUPC GEMM Library : CPU と GPU を用いて問題分割・並列実行を行う 行列計算ライブラリ の設計と実装 50 あるものの,図 20 のように対象行列の転置状態によっては手法が有効に機能せず高 い性能が得られない.そのためシェーダによるベクトル演算が行いにくい問題につ いては,転置してから GPU へ転送し,計算結果を取得後に転置を戻すという実装 を行った.また行列の縦横サイズが 4 の倍数でない場合はパディングも行っている. なおこれらの処理は計算時間に影響を及ぼさない程度の十分に短い時間で行うこと が可能であり,性能に有意な影響を及ぼすことがないことが確認できている. CPU と GPU による問題分割・並列実行の実装方法 行列積和計算はデータの参照パターンが単純なため,問題分割も容易に行う事が できる.GPUPC GEMM Library では,CPU-GPU 間でのデータ転送量が増えない ようにすることと,CPU と GPU での問題担当割合を容易に変更できることを考慮 し,図 21 に示すような方法で問題分割を行うことにした. この問題分割方法では分割割合 “m” を変更することで CPU と GPU の問題担当 割合を容易に変更することができるため,CPU と GPU の性能バランスに合わせて 問題分割割合を容易に調整することができる. 行列積和計算は反復計算等を必要としない単純な問題であるため,3.2 節を踏まえ て図 22 に示すような設計とした. ライブラリ関数を実行する際のライブラリ内における処理の順序は以下の通りで ある. 1. 初回の実行時のみ GPU の初期化とシェーダプログラムの読み込みを行う. 2. 引数として与えられた問題サイズを元に,CPU のみで計算を行うか CPU と GPU を用いて並列計算を行うかの判定を行う.CPU のみで計算を行う場合は 3 へ,並列計算を行う場合は 4 へ. 3. ATLAS の行列積和関数を実行して値を返す (関数終了). 4. 問題分割割合を決めたうえで GPU に対するデータ転送と描画指示を行う. 5. GPU が描画処理を行っている間に ATLAS を用いて CPU による計算を行う. 6. GPU の計算結果を取得し,CPU と GPU の計算結果を統合して返す (関数 終了). 3.3 GPUPC GEMM Library : CPU と GPU を用いて問題分割・並列実行を行う 行列計算ライブラリ の設計と実装 51 図 19: ベクトル演算を利用した行列積の例 3.3 GPUPC GEMM Library : CPU と GPU を用いて問題分割・並列実行を行う 行列計算ライブラリ の設計と実装 52 図 20: ベクトル演算が利用できない行列積の例 3.3 GPUPC GEMM Library : CPU と GPU を用いて問題分割・並列実行を行う 行列計算ライブラリ の設計と実装 53 図 21: 問題分割方法 ここで問題となるのは,CPU のみで計算を行うか,CPU と GPU を用いて問題分 割・並列実行を行うかの判定基準である.既に述べたように,対象問題のデータ規 模が小さい場合には CPU 単体で実行した方が高い性能が得られる可能性がある.そ こで GPUPC GEMM Library では,問題分割の際には関数の引数として与えられた 問題サイズを確認し,問題サイズが閾値より小さい場合には全てを CPU に割り当 て,それ以外の場合に問題分割・並列実行を行うこととした. チューニングスクリプト CPU のみで計算を行うか CPU と GPU で問題分割・並列実行するかの閾値につい ては,CPU と GPU の性能バランスに依存することが考えられる.そこで GPUPC GEMM Library では,閾値となる問題サイズや CPU と GPU での問題分割割合を外 部ファイルで指定し問題分割機構のふるまいを指定できるようにした.また,閾値 と適切な問題分割割合を求めるためのチューニングスクリプトを作成した. ここで作成したチューニングスクリプトは,以下のような手順で適切な閾値と問 題分割割合を求めるものである. 1. 適当な問題サイズ (初期値では 1024) の正方行列に対して,CPU と GPU によ る問題分割割合を 10%ずつ変更しながら行列積和計算を行い実行時間を測定 する. 2. 1 で最も高い性能を得られた問題分割割合の前後において,更に細かく分割割 3.3 GPUPC GEMM Library : CPU と GPU を用いて問題分割・並列実行を行う 行列計算ライブラリ の設計と実装 54 図 22: ライブラリの設計 3.3 GPUPC GEMM Library : CPU と GPU を用いて問題分割・並列実行を行う 行列計算ライブラリ の設計と実装 55 合を指定し直して実行時間を測定する.(初期値では-20%から+20%まで 5%刻 みで測定.) 3. 2 で最も高い性能を得られた問題分割割合を最適な問題分割割合と見なす. 4. 問題サイズを変更しながら (初期値では 256 から 3072 まで 256 刻み),3 で求 めた問題分割割合を用いた場合と CPU のみでの実行時間を比較する. 5. CPU のみより高い性能を得られる問題サイズの下限を閾値と見なす. この方法では問題サイズが閾値を超えたものは全て同じ問題分割割合となってしま う.しかしながら,本章の実験環境を含むいくつかの実験環境を用いて性能評価を 行ったところ,閾値以上の問題サイズにおける最適な問題分割割合はほとんどがプ ラスマイナス 10%以内に収まっており常に良い性能が得られたため,このような方 法を採用した.今後様々な実験環境で性能確認を行い,チューニング方法を改良す る余地はある. なお,実行時間が 0.01 秒未満の問題については,仮に並列実行による高速化が得 られるという出力が得られた場合でも絶対的な実行時間が短すぎて問題分割・並列 実行の効果が期待できないと考えられるため,CPU のみで実行するべきであると判 断している. 複数 CPU や複数 GPU を搭載した計算機システム向けの実装 前項で述べたように,複数 CPU や複数 GPU 向けの実装にはいくつかの方法が考 えられる.ここではマルチスレッド対応の CPU 向け並列計算ライブラリと,共有メ モリ (shm, mmap) および unix socket を用いた GPU の制御による複数 CPU や複数 GPU 向けの実装を行った. 複数 CPU (マルチコア CPU) への対応はマルチスレッドに対応した ATLAS に行 わせることにした.これは,ATLAS のマルチスレッド実行への対応は古くから行 われており,手動で問題分割を行うよりも良い性能が得られる可能性が高いためで ある. 複数 GPU への対応については,fork を用いたマルチプロセスプログラミングに よって複数 GPU の制御を行うこととした.プロセス間で行列データを共有する必 3.3 GPUPC GEMM Library : CPU と GPU を用いて問題分割・並列実行を行う 行列計算ライブラリ の設計と実装 56 要があるため,shm と mmap を用いた共有メモリを利用することとした.さらに, unix socket を用いたプロセス間の通信も行っている.プロセス間の通信は,問題分 割終了時に共有メモリの更新完了および描画開始を指示する際に利用している.ま た,CPU の計算が終わる前に GPU の結果取得処理が始まり CPU がブロックされ て CPU の計算時間が伸びてしまうのを避けるため,計算結果取得のタイミングを 指示するのにも利用している. 以上を元に作成した複数 CPU・複数 GPU に対応した GPUPC GEMM Library の 構造を図 23 に示す. 倍精度浮動小数点演算への対応 2008 年末の時点では最新の一部のモデルを除いた多くの GPU は倍精度浮動小数 点演算に対応しておらず,倍精度浮動小数点演算に対応している GPU もその性能 は単精度浮動小数点演算と比べると著しく低い.またグラフィックス API やシェー ダ言語も倍精度浮動小数点演算に対応していない.その一方で数値計算アプリケー ションなど行列積和関数を利用するアプリケーションには高い演算精度を求めるも のが少なくはない. そこで本研究では,単精度浮動小数点向けの行列積和関数 SGEMM だけではなく, 倍精度浮動小数点向けの行列積和関数 DGEMM も作成した.この DGEMM は API と CPU が担当する部分のみ倍精度で計算し,GPU が担当する部分は単精度に精度 を落として実行するという,形式的な DGEMM である.そのため演算精度に問題が あるものの,既存の DGEMM を用いたアプリケーションに対して形式的な適用実験 を行うことが可能となっている. 演算精度を改善し演算精度確認をパスするための方法としては,複数の単精度演 算を行うことで倍精度演算と同等の演算精度の演算を行う方法が挙げられる.これ は本アプローチの提案とは直接関係のない問題であるため,ここでは扱わない.演 算精度に問題がある性能評価でも,本アプローチの中心である GPGPU 環境を容易 に利用できることと常に高い性能を得られることを否定することにはならず,意味 があると考えられる. 3.3 GPUPC GEMM Library : CPU と GPU を用いて問題分割・並列実行を行う 行列計算ライブラリ の設計と実装 57 図 23: 複数 CPU・複数 GPU 対応版 GPUPC GEMM Library の構造 3.3 GPUPC GEMM Library : CPU と GPU を用いて問題分割・並列実行を行う 行列計算ライブラリ の設計と実装 58 メモリ容量に基づく問題サイズの制限 GPU に対して GPU の搭載メモリ容量を超える処理を行わせることは不可能であ り,また GPU はグラフィックス API の仕様により一辺の長さが 4096 を超える大き さのテクスチャを利用することができない.また一辺の長さが 4096 に達していない 場合でも,4000 程度の大きさになると正しい実行結果が得られないことがあること を確認した.そのため,全体の問題サイズが大きな場合でも GPU が担当する問題 サイズ (正確にはテクスチャの一辺の長さ) の上限が 4000 未満となるような調整機 構を入れている. 行列データの転置や ORDER といった BLAS のパラメタへの対応 CPU-GPU 間のデータ転送時に行列の転置を行う必要がある場合など,対象問題 のデータ配置によっては CPU-GPU 間の転送前後でデータを並び替えるための一時 的なメモリが必要となる.対象問題の問題サイズや GPU の担当割合が大きな場合 に一度に必要な全てのデータを並び替えようとするとメインメモリに大きな一時領 域が必要となるため,分割して並び替え・送受信できるような機構を実装した. データの並び替えの際の分割サイズを適当に変えて実験した結果,分割サイズが 著しく大きな場合や小さな場合にのみ CPU-GPU 間のデータ送受信やデータ再配置 にかかる時間が長くなりプログラム全体の大きな性能低下に繋がることが確認でき た.次項の性能評価ではいずれも問題がない程度の分割サイズを設定している. さらに BLAS の行列積和関数 API に正しく対応するため,行列の ORDER (Row- Major/ColMajor,行列の並びが縦方向であるか横方向であるかを意味する) や転置 設定などについても適切な実装を行った.GPUPC GEMM Library は GEMM の各 種パラメタに全て対応した cblas sgemm 関数および cblas dgemm 関数相当の関数, gpupc sgemm 関数および gpupc dgemm 関数を提供するライブラリである. 3.4 GPUPC GEMM Library の評価 3.4 59 GPUPC GEMM Library の評価 本節では GPUPC GEMM Library について,アプリケーションプログラマが容易 に利用できるか (ライブラリ利用の手間に関する評価) および CPU 単体や GPU 単 体と比べて高い性能を得られるか (ライブラリの性能に関する評価) についての評価 を行う. 評価は以下の 3 点について行う. 1. 単純な行列積和計算を用いた性能確認 2. HPL を用いた性能確認 3. 利用の手間に関する評価 評価環境は表 2 に示す通りである. 表 2: 評価環境 1 環境 1 CPU 環境 2 Pentium4 3.0GHz 環境 3 Athlon64X2 4600+ 2.4GHz メインメモリ 1.0GB GPU GeForce7800GTX GeForce7600GT GeForce7950GT ビデオメモリ容量 256MB GPU 接続バス PCI-Express x16 (Gen 1) OS CentOS 5.0 (kernel 2.6.18) コンパイラ GCC 4.1.2 3.4.1 4.0GB 256MB 512MB 単純な行列積和計算を用いた性能確認 GPUPC GEMM Library は,問題サイズ (行列の一辺の長さ) が小さすぎる場合 に CPU のみで計算を行い CPU と GPU による問題分割・並列実行によって高い性 能が得られる場合にのみ並列実行するという機能を持つ (ただし CPU のみで計算を 行う問題サイズの閾値や適切な問題分割割合はチューニングスクリプトで事前に求 3.4 GPUPC GEMM Library の評価 60 めておく必要がある) ため,問題サイズに関係なく “CPU のみによる実行”,“GPU のみによる実行”,“CPU と GPU による問題分割・並列実行” の中から最も高速な ものを選択し実行することができる. そこで第 1 の評価として,いくつかの問題サイズの行列積和計算に対して,CPU と GPU の問題分割割合にいくつかの値を設定して CPU と GPU による問題分割・並 列実行の実行時間を測定する.測定結果を CPU のみによる実行や GPU のみによる 実行の実行時間と比較し,CPU と GPU による問題分割・並列実行により CPU のみ や GPU のみよりも高い性能が得られること,また環境によっては問題サイズが小さ すぎる場合に CPU のみの方が性能が高いことを確認し,GPUPC GEMM Library の 機能,すなわち問題サイズが小さすぎる場合に CPU のみで計算を行い CPU と GPU による問題分割・並列実行によって高い性能が得られる場合にのみ並列実行する機 能が有用であることを示す. 以下,SGEMM を用いた性能確認,DGEMM を用いた性能確認,複数の CPU と 複数の GPU を搭載した計算機システムでの性能確認,の順で評価を行う. SGEMM を用いた性能確認 ここでは SGEMM を用いた性能確認を行い,GPUPC GEMM Library の有用性 を確認する. 図 24 から図 26 は各実行環境に対して,CPU のみによる実行 (CPU)・GPU のみ による実行 (GPU)・CPU と GPU を用いた並列実行 (PARALLEL) の各実行時間 (a) と,GPU のみによる実行および並列実行についての CPU に対する実行時間比 (b),さらに並列実行において最適な実行時間となった問題分割割合 (c) を示すグラ フである.並列実行の実行時間は CPU と GPU の問題分割割合を CPU 5% : GPU 95%から CPU 95% : GPU 5%まで 5%刻みで変化させた際の最も高速な場合をとっ ている.各実行時間には GPU を初期化する時間は含まれていないが,CPU-GPU 間 の通信時間は含まれている. グラフからわかるように,実行時間が 0.01 秒未満と著しく短いもの (横軸の問題 サイズに*をつけたもの) を除外して見てみると,環境 1 と環境 3 は問題サイズ 512 において CPU のみや GPU のによりも並列実行の実行時間が最も短いのに対して, 環境 2 では GPU の性能が低いため並列実行の実行時間が最も短くなるのは問題サ 3.4 GPUPC GEMM Library の評価 図 24: 各問題サイズに対する実行時間と CPU に対する実行時間比 (環境 1) 61 3.4 GPUPC GEMM Library の評価 図 25: 各問題サイズに対する実行時間と CPU に対する実行時間比 (環境 2) 62 3.4 GPUPC GEMM Library の評価 図 26: 各問題サイズに対する実行時間と CPU に対する実行時間比 (環境 3) 63 3.4 GPUPC GEMM Library の評価 64 イズ 768 からである.またいずれの環境においても問題サイズがある程度大きい場 合には並列実行の実行時間が最も短くなっている.各問題サイズにおいて最も実行 時間が短くなった際の問題分割割合をみると,それぞれ 10%以内の範囲に収まって いることがわかる. DGEMM を用いた性能確認 DGEMM についても SGEMM と同様の性能確認を行った. CPU のみによる実行 (CPU)・GPU のみによる実行 (GPU)・CPU と GPU を用い た並列実行 (PARALLEL) の各実行時間と,GPU のみによる実行および並列実行に ついての CPU に対する実行時間比,さらに並列実行において最適な実行時間となっ た問題分割割合を示すグラフを図 27 から図 29 に示す. グラフからわかるように,CPU と GPU で問題分割・並列実行するよりも CPU の みで実行した方が高い性能となる閾値や問題分割・並列実行における適切な問題分 割割合などの具体的な値は異なるものの,SGEMM と同様の傾向が見て取れる.い ずれの環境においても SGEMM より多くの問題を GPU が担当したときに高い性能 が得られているのは,CPU の演算が DGEMM となり実行時間が長くなった一方で GPU の演算は SGEMM のままであるため,相対的に GPU の性能が高くなり,より 多くの問題を GPU に割り当てた方が高い性能が得られたことによるものであると 考えられる. 複数の CPU と複数の GPU を搭載した計算機システムでの性能確認 環境 2 に対して,搭載されている GPU と同じ GPU をもう 1 台搭載して 2CPU (デュアルコア CPU×1) + 2GPU の環境を作り,複数の CPU と複数の GPU を用い た場合の性能についても性能確認を行った.以下,元の環境 2 を “1CPU+1GPU 環 境”,GPU を追加した環境を “2CPU+2GPU 環境” と呼ぶことにする. 今回の実験環境 (2CPU+2GPU 環境) では CPU に搭載された 2 つのコアは同じ性 能を持ち,また 2 台の GPU もそれぞれ同じ性能を持つ.そのため,2CPU+2GPU の問題分割では 1CPU+1GPU 環境における問題分割を利用し,CPU A% : GPU B%の問題分割割合だったものを CPU0 (A/2)% : CPU1 (A/2)% : GPU0 (B/2)% 3.4 GPUPC GEMM Library の評価 65 図 27: 各問題サイズに対する実行時間と CPU に対する実行時間比 (環境 1:DGEMM) 3.4 GPUPC GEMM Library の評価 66 図 28: 各問題サイズに対する実行時間と CPU に対する実行時間比 (環境 2:DGEMM) 3.4 GPUPC GEMM Library の評価 67 図 29: 各問題サイズに対する実行時間と CPU に対する実行時間比 (環境 3:DGEMM) 3.4 GPUPC GEMM Library の評価 68 : GPU1 (B/2)%という割り当てにすることである程度高い性能が得られると期待で きる. “SGEMM を用いた性能確認” からわかるように 1CPU+1GPU 環境における最適 な問題分割割合が CPU 50% : GPU 50%であったことから,2CPU+2GPU 環境では 2CPU (ATLAS によるマルチスレッド処理) に 50%を割り当て,残りの 50%を 2GPU で均等に分割して実行時間を測定した.図 30 は,CPU のみによる実行 (CPU)・ GPU のみによる実行 (GPU)・1CPU+1GPU 環境での並列実行 (1CPU+1GPU)・ 2CPU+2GPU 環境での並列実行 (2CPU+2GPU) の 4 環境についての実行時間と, それぞれ CPU のみによる実行に対する実行時間比を示したグラフである.グラフ からわかるように,2CPU+2GPU 環境では 1CPU+1GPU 環境と比較してさらに実 行時間を短縮することができている. まとめ 以上のように,CPU と GPU による問題分割・並列実行は CPU のみや GPU のみ と比べて高い性能を得られる可能性がある一方で,問題サイズが小さすぎる場合に は CPU のみで計算を行う方が問題分割・並列実行するよりも高い性能が得られ,ま た問題サイズが大きい場合には CPU の GPU の性能バランスに対応した一定の割合 で問題分割・並列実行を行うことで高い性能を得られることが確認できた. GPUPC GEMM Library では並列実行により実行時間が短くなる問題サイズの閾 値や最適な問題分割割合をチューニングスクリプトを用いて調査し,また調査した 結果を用いて常に高い演算性能を発揮することができる.アプリケーションプログ ラマは本ライブラリを用いない場合,自ら手間のかかる CPU と GPU による並列処 理を実装しなくてはならないうえに,対象問題の問題サイズによって CPU のみで の実行,GPU のみでの実行,CPU と GPU による問題分割・並列実行の中から適切 な実行方法を選択しなくてはならない.GPUPC GEMM Library はこうしたアプリ ケーションプログラマにとっての手間を削減することができるため有用であると言 える. 3.4 GPUPC GEMM Library の評価 図 30: 2CPU+2GPU での性能評価 (SGEMM) 69 3.4 GPUPC GEMM Library の評価 3.4.2 70 HPL ベンチマークを用いた性能確認 第 2 の評価として,環境 1 に対して HPL ベンチマークを用いた性能確認を行った. 本項では,HPL ベンチマークは単一 CPU 上で実行する際にも性能チューニングを 行わなくては良い性能が得られないことから,はじめに CPU による HPL の実行と 解析および性能チューニングを行い,その結果を踏まえて GPUPC GEMM Library を用いた HPL ベンチマークを行うこととする. CPU による HPL の実行と解析および性能チューニング HPL ベンチマークは,計算機の性能指標として用いられているベンチマークの 1 つであり,世界中の計算機の性能を競う TOP500 に用いられているベンチマークと して広く知られている.並列計算機の性能評価によく用いられるベンチマークであ るが,1 ノードの PC でも問題なく動作する. HPL の実行時間の多くは行列積和計算によって占められており,その計算には ATLAS などの数値計算ライブラリを利用するように設定することができる.ATLAS を利用する場合には,cblas dgemm 関数によって演算が行われる. HPL は図 31 に示す 16 の性能パラメタによるチューニングを行うことができる [89].これらのパラメタのうち,1 ノードでの実行において性能を大きく左右するの は問題サイズとブロックサイズの 2 つのパラメタである. 問題サイズについては,基本的には問題サイズが大きな方が高い性能が得られる. しかしながら,使用可能な物理メモリサイズを超える大きさになると性能が著しく 低下する.つまり,この値は実行環境の物理メモリ搭載量によって左右される.ブ ロックサイズについては,CPU のキャッシュサイズに応じた値を指定することで良 い性能を得ることができる.ATLAS のインストールログの値を参考にすると良い とされており,本実験環境におけるインストールログからは 72 の倍数が適切である ことが確認できた. そこで,以下の 2 つの実験を行った. 第 1 の実験として,ブロックサイズを 72 としたうえで問題サイズを 1000 ずつ変更 しながら HPL を実行した.その結果,問題サイズ 11000 までは性能が向上するが, 問題サイズ 12000 になると性能が急激に低下するという結果が得られた (図 32). 3.4 GPUPC GEMM Library の評価 71 第 2 の実験として,問題サイズを 11000 に固定しブロックサイズを 2 ずつ変更し ながら HPL を実行したところ,72 の倍数のときに良い性能が得られることが確認 できた (図 33). 以上から,実験環境 1 においては,問題サイズ 11000,ブロックサイズ 72 におい て,最大性能 FLOPS 値 4.04GFLOPS を得ることができた. − 問 題 サ イ ズ (29 ,30 ,34 ,35) − ブ ロ ッ ク サ イ ズ (1 ,2 ,3 ,4) − プ ロ セ ス グ リ ッ ド の サ イ ズ ( 2 x2 , 1 x4 , 4 x1 ) − 解 の チ ェ ッ ク に お け る 残 差 の 境 界 線 (16.0) − Panel F a c t o r i z a t i o n の ア ル ゴ リ ズ ム ( l e f t , Crout , Right ) − 再 帰 的 Panel F a c t o r i z a t i o n の ア ル ゴ リ ズ ム ( l e f t , Crout , Right ) − 再 帰 的 F a c t o r i z a t i o n に お け る subpanel 数 (2) − 再 帰 的 F a c t o r i z a t i o n に お け る subpanel 幅 の 最 小 値 (2) − Panel B r o a d c a s t の ト ポ ロ ジ ( 1 r g ) − Look−ahead の 深 さ ( 1 ) − Update に お け る 通 信 ト ポ ロ ジ ( mix ) − long に お け る U の 平 衡 化 処 理 の 有 無 ( 有 ) − mix に お け る 行 数 の 境 界 値 ( 6 4 ) − L1 パ ネ ル の 保 持 の 仕 方 ( t r a n s p o s e d ) − U パ ネ ル の 保 持 の 仕 方 ( transposed ) − メ モ リ の alignment (8) 図 31: HPL の性能パラメタ (括弧内は初期値) GPUPC GEMM Library を用いた HPL ベンチマーク GPUPC GEMM Library を用いて HPL ベンチマークを実行する前に,CPU 向け の HPL ベンチマーク結果を参考にして GPUPC GEMM Library を用いた HPL ベン チマークの問題設定を検討する. GPUPC GEMM Library では CPU から GPU へのデータ転送において一定のメイ ンメモリが必要となることから,HPL の問題サイズを CPU による HPL ベンチマー クで高い性能が得られる範囲における最大の問題サイズではなく,ある程度小さい 値で行う必要がある. 3.4 GPUPC GEMM Library の評価 図 32: CPU による HPL の性能調査:問題サイズと性能 (環境 1) 図 33: CPU による HPL の性能調査:ブロックサイズと性能 (環境 1) 72 3.4 GPUPC GEMM Library の評価 73 また第 1 の評価の結果から,問題分割・並列実行によって高い性能を発揮するには DGEMM の問題サイズがある程度大きい必要があることが判明している.そのため, 仮に HPL 内で実行される DGEMM の問題サイズが全て小さい場合は,分割実行に より良い性能を得ることが困難であると言える.そこで,HPL における DGEMM の実行について確認した.その結果,次のようなパターンとなっていることが確認 できた.なお,文中の問題サイズ MNK は図 21 に対応している. 1. HPL 内では DGEMM を繰り返し実行している. 2. DGEMM の問題サイズ M は,HPL の問題サイズから次第に小さくなっていく. 3. DGEMM の問題サイズ N と K は,次項 (4) の場合を除いてブロックサイズ未 満の小さな値である. 4. “一定の周期” で,問題サイズ N が問題サイズ M+1,問題サイズ K がブロック サイズ,という “比較的大きな DGEMM” が実行される. 5. ブロックサイズが大きいほど,“一定の周期” は長い周期になり,HPL 全体に おいて “比較的大きな DGEMM” が実行される回数も減少する. 実行パターンから,GPUPC GEMM Library は “比較的大きな DGEMM” のみを適 切に問題分割・並列実行することで高い性能が得られることが期待できる. 既に述べたように,CPU 単体での HPL ベンチマークにおいてはブロックサイズ が 72 の倍数の時に良い性能が得られる.並列実行では問題サイズが大きなときに良 い性能が得られることから,これらの数の倍数の中から適当な値を選択することで 高い性能が得られると考えられる. 以上の検討結果から,問題サイズは 8000 に固定し,ブロックサイズは 72 の倍数 をいくつか試すことで良いベンチマーク結果が得られると考えられる.なお,問題 サイズ 8000,ブロックサイズ 72 における CPU のみを用いた HPL ベンチマークの 性能は 3.90GFLOPS であった. 検討結果に基づき環境 1 にて HPL ベンチマークを行った結果を図 34 に示す.横 軸にはブロックサイズ,縦軸には性能 FLOPS 値をとっている. グラフからわかるように,本環境ではブロックサイズが 576 のときに最も高い性 能が得られており,その性能 FLOPS 値は 5.86GFLOPS であった.CPU による HPL 3.4 GPUPC GEMM Library の評価 74 図 34: GPUPC GEMM Library を用いた HPL の実行結果 (環境 1) の最大性能 FLOPS 値が 4.04GFLOPS であったことから,提案方式による速度向上 率は 45.0%となる. 以上の結果から,GPUPC GEMM Library を用いることで高い性能を得られるこ とが示された. ただし,演算精度には問題が残った.HPL は演算の途中と終了時に演算精度の確 認を行う機能を備えている.GPUPC GEMM Library を用いて HPL を実行した場 合,終了時の演算精度確認をパスすることができなかった.GPU による演算が単精 度であるために計算誤差が大きくなってしまったことが理由であると考えられる.既 に述べたように本アプローチでは演算精度の改善を行わない方針であり,性能評価 の結果から本アプローチにより高い演算性能を得られることが確認できたと見なす. なお,HPL 内の DGEMM 演算を全て GPU のみで実行することも可能である.し かしながら,問題サイズが小さいときに高い性能が得られないため,全体として低 い FLOPS 値が得られることが明らかである.実際に測定を行った結果,1GFLOPS にも満たない低い性能が得られた. 3.4 GPUPC GEMM Library の評価 3.4.3 75 利用の手間と得られる性能に関する評価 最後に,GPUPC GEMM Library の利用の手間と得られる性能に関する評価を 行う. GPUPC GEMM Library は既存の BLAS と同様の API をアプリケーションプロ グラマに提供する.そのためアプリケーションプログラマは,対象となる BLAS 関 数 (cblas sgemm,cblas dgemm) を利用しているプログラムに対して,関数名の変更 (およびリンクするライブラリの追加・変更) のみで GPUPC GEMM Library を適 用することができる. GPUPC GEMM Library が高い性能を得るためには,実行環境に依存する性能パ ラメタとして,CPU のみで計算するか CPU と GPU で問題分割・並列実行を行う かの閾値と,CPU と GPU での問題分割割合を適切に選択する必要がある.そこで, チューニングスクリプトを作成し,ライブラリインストール時にこれを用いること で適切な閾値と問題分割割合を自動的に求めて利用できるようにした. 以上により,HPL を用いた性能評価においてもプログラムの変更は関数名の変 更のみに抑えられた.GPUPC GEMM Library を正しくリンクするために HPL の Makefile を数カ所編集する必要はあったが,アプリケーションプログラマにとって 大きな手間とはなっていないと考えられ,手間をかけずに高い性能を得られたと言 える. 一方で GPUPC GEMM Library を用いた HPL の性能チューニングにおいては, 通常の HPL のチューニングに加えて,問題サイズをやや小さくすることとブロック サイズを大きめにするという,GPUPC GEMM Library を利用することを意識した HPL のチューニングが必要となった.しかしこれらのチューニングについては “ラ イブラリがメインメモリを多めに確保する” や “問題サイズが大きい方が高い性能が 得られる” といった GPU のアーキテクチャなど GPGPU 特有の情報が表面化しない 最適化パラメタに置き換えることができるため,大きな手間とはならないものと考 えられる. 以上のように,GPUPC GEMM Library はアプリケーションプログラマが大きな 手間をかけずに GPU の持つ高い性能を有効に活用できるようにすることができた と言える. 最後に参考値として,GPUPC GEMM Library にどの程度の行数のプログラム記 3.4 GPUPC GEMM Library の評価 76 述を行っているか,本アプローチに基づくライブラリが存在しない場合にはどの程 度の実装の手間がかかるのかを確認する. • 問題分割・並列実行に関する記述 (CPU 上で動作するプログラム) : 4000 行程 度.ただし SGEMM と DGEMM で似たような記述を繰り返している部分が多 いため,実質 2000 行程度. • シェーダプログラム (GPU 上で動作するプログラム) : 100 行程度.ただし行 列の ORDER と転置のパラメタに対応するため類似したプログラムが複数存 在する. • OpenGL やシェーダの初期化などに関する記述 (CPU 上で動作するプログラ ム) : 1000 行程度. • 複数 CPU や複数 GPU 向けの記述 (CPU 上で動作するプログラム) : 3000 行 程度. GPUPC GEMM Library は合計 6000 行程度 (複数 CPU や複数 GPU 向けの実装で は合計 10000 行程度) で書かれたプログラムである.このうち問題分割・並列実行 に関する記述が本アプローチの中心となる部分であり,アプリケーションプログラ マにとっては,この行数分の手間が削減されていると言える. 77 並列化プログラミング環境によるアプローチ 4 本章では,既存の CPU 向け並列化プログラミング環境を用いて GPGPU プログ ラムを作成できるようにすることでアプリケーションプログラマに対して GPGPU プログラムに関する知識や技術を習得する手間を削減するアプローチを提案する. はじめに本提案の着眼点である既存の CPU 向け並列化プログラミング環境を用い た GPGPU プログラミングの概要を述べ,次に既存の CPU 向け並列化プログラミ ング環境と GPGPU および CUDA との対応付けについて述べる.さらに提案を元 に作成した処理系 “OMPCUDA” の設計と実装について述べ,テストプログラムを 用いて評価を行う. 4.1 既存の CPU 向け並列化プログラミング環境を用いた GPGPU プログラミングの提案 GPU は内部の演算器にハードウェアレベルでの高い並列性を備えた並列処理によ る高い演算性能を持つハードウェアである.そのため GPU は並列性の高いプログ ラムに対する性能向上が期待されている.しかしながら GPU プログラミングには GPU プログラミング独自の並列化プログラミング環境を用いる必要があるため,ま た GPU のアーキテクチャについての知識が必要なため,アプリケーションプログ ラマにとって GPU プログラミングは難しく手間がかかるものとなっている. 一方で CPU を対象とした並列化プログラミングに関する研究はこれまでに数多く 行われてきた.現在では単純なループの並列化など一部のプログラムについては自 動並列化コンパイラによる並列化でも高い性能を得ることが可能となっているもの の,一般的な多くのプログラムではアプリケーションプログラマによる並列化記述 が必要である.そのため様々な並列化プログラミングのためのプログラミング環境 が提案されており,いくつかの並列化プログラミング環境は多くのアプリケーショ ンプログラマに利用されている.したがって,GPGPU プログラミングにもこれら の並列化プログラミング環境が利用できれば,アプリケーションプログラマにとっ て GPU のアーキテクチャに関する理解や GPGPU プログラミング独自の並列化手 法,並列化プログラミング言語の習得といった手間が削減され,GPGPU を容易に 4.1 既存の CPU 向け並列化プログラミング環境を用いた GPGPU プログラミング の提案 78 利用可能になると考えられる. そこで,既存の CPU 向け並列化プログラミング環境を用いた GPU プログラミン グを提案する.以下本節では,既存の CPU 向け並列化プログラミング環境のいくつ かについて,現在の一般的な GPU との対応付けを考える.さらに GPU アーキテク チャの 1 つである CUDA を対象として,既存の CPU 向け並列化プログラミング環 境と GPU プログラミングとのより具体的な対応付けの検討を行う. 4.1.1 既存の CPU 向け並列化プログラミング環境と GPGPU 本項では既存の CPU 向け並列化プログラミング環境を用いた GPU プログラミン グについての検討を行う.具体的には,現在普及している GPU のアーキテクチャを 元に典型的な GPU のハードウェア構成を想定し,既存の CPU 向け並列化プログラ ミング環境との対応付けを考える. 2008 年の時点で普及している GPU,GeForce シリーズ [90, 40] と Radeon シリー ズ [91] のアーキテクチャを元に典型的な GPU のハードウェア構成を想定し,想定 したハードウェア構成と既存の CPU 向け並列化プログラミング環境との対応付け を検討する. 現在の GPU に搭載されている各演算器は同時期の CPU コアと比べると単純な構 造で演算性能も低いものの,多数の演算器を搭載することで GPU 全体での演算性 能を高めている.また,GPU 上には CPU(マザーボード上) のメインメモリとは独 立に比較的大容量 (最大で数 GB) かつ GPU 内部の各演算器から読み書き可能なメ モリ (DRAM) が搭載されている. さらに GPU 上の演算器は数個ごとに演算器群を構成しており,GPU 上には同一 演算器群の演算器のみが読み書き可能な高速・小容量のオンチップメモリも搭載さ れている.このように演算器とメモリに階層性を持つ Device(GPU) が PCI-Express などのバスによって Host(CPU やメインメモリが搭載されたマザーボード) に接続 されている.GPU は CPU によって演算開始などの指示を受ける必要があるものの, CPU と同時に演算を行うことができる. 以上を元に想定した GPU のハードウェア構成を図 35 に示す. vvGPGPU における典型的な GPU の活用方法は,対象アプリケーションの中か ら並列性が高いタスクを抽出して GPU に実行させることである.この場合におけ 4.1 既存の CPU 向け並列化プログラミング環境を用いた GPGPU プログラミング の提案 79 図 35: 典型的な GPU のハードウェア構成 4.1 既存の CPU 向け並列化プログラミング環境を用いた GPGPU プログラミング の提案 80 る CPU-GPU 間での通信と演算の流れは,CPU がメインメモリ上のデータ (変数・ 配列) を GPU 上のメモリへ転送し,GPU が (もしくは CPU と GPU がそれぞれ) 演 算を行い,CPU から GPU への指示によって GPU 上のメモリからメインメモリへ 演算結果などのデータが転送されるというものである. こうした一連の処理を行うには GPU の実行制御やメインメモリと GPU 上のメモ リの間での通信が必要である.通信や制御を既存の CPU 向け並列化プログラミン グ環境を用いて記述することができれば,GPU プログラミングが容易に行えるよう になると考えられる. さらに GPU の持つ高い並列実行性能を活用するには,GPU 内部の並列性を利用 する必要がある.ただし GPU にどのようなメモリが搭載されているかや搭載され ているメモリが CPU 側からどのようにアクセスできるかは対象とする GPU のアー キテクチャやドライバなどに依存する. GPU 上の演算器やメモリを用いた並列処理を既存の CPU 向け並列化プログラミ ング環境を用いて記述することができれば,GPGPU プログラミングが容易に行え るようになると考えられる. 一方で CPU 向けの並列化プログラミングについては,CPU 内の SIMD 演算器, SMP (共有メモリ型並列計算機,Symmetric Multiple Processor/Shared Memory Multiprocessor),マルチコア CPU,PC クラスタなど既に様々な環境に向けて数多 くの研究が行われている.またアプリケーションプログラマが明示的に並列性を記述 する際に用いられている手法やライブラリとしては,SIMD 関数,pthread (POSIX Threads) などのスレッドライブラリ,OpenMP,MPI をはじめとした通信ライブラ リなどが広く利用されている.そこで,GPGPU における並列処理の記述に対する これらの並列化プログラミング環境の適用可能性を考えることにする. SIMD プログラミング 複数のデータに対して同時に同じ演算を行う SIMD 演算は,マルチメディア処理 をはじめとした様々な処理の高速化に有効である.SIMD 化についてはコンパイラ による自動 SIMD 化によってもある程度の性能が得られることが知られている [92] が,これを利用するにはコンパイラの SIMD 化変換パターンに適したコードを書く 4.1 既存の CPU 向け並列化プログラミング環境を用いた GPGPU プログラミング の提案 81 必要があることから扱いやすいプログラミング環境であるとは言い難く [93],イン ラインアセンブラや SIMD 関数を用いたプログラミングが行われている [94, 95]. SIMD 演算は細粒度のデータ並列処理に適している.そこで,GPU 内部の各演算 器を SIMD 演算ユニットと見なしてデータ並列演算と対応付けることで,GPU 上 の演算器による並列処理を SIMD 関数などを用いて記述できるようになると考えら れる. スレッドライブラリを用いたマルチスレッドプログラミング 近年普及が進んでいるマルチコア CPU を含めた共有メモリ型並列計算機では,ス レッドを用いた並列化が広く行われている.特に共通化されたスレッドライブラリ pthread は多くの計算機環境 (OS) に対応しているため広く普及している. スレッドプログラミングでは複数のスレッドが共有メモリを利用して並列処理を 行うことから,GPU 上の演算器間の並列性や演算器群間の並列性の記述との適用性 が高いと考えられる. 一方で,CPU から GPU に対する演算の指示をスレッドプログラミングの手法で 記述することも考えられる.スレッドプログラミングでは一般的に関数単位でのス レッド割り当てを行う.そこで,スレッドプログラミングにおけるスレッド化対象の 関数を GPGPU プログラムにおいては GPU に実行させる,といったプログラミン グモデルの対応付けが考えられる.ただし対応付けを行うには,CPU と GPU は独 立したメモリ空間を持つため,スレッド内部で利用するデータを CPU-GPU 間で送 受信する必要がある.そのためにはコンパイラによる静的なデータ参照の解析を行 うか,可能であるならば SDSM[96, 97] のようにメモリアクセスのたびに CPU-GPU 間でデータを送受信する機構を提供する必要があると考えられる. OpenMP を用いた並列化プログラミング pthread などのスレッドライブラリを用いた並列化をより容易に記述する方法と して,OpenMP[98] を用いた並列化が利用されている.OpenMP による並列化プロ グラミングは逐次プログラムに指示子を追加することによって行われ,特にループ の並列化など共有メモリを用いた典型的な並列処理を容易に記述することができる. 4.1 既存の CPU 向け並列化プログラミング環境を用いた GPGPU プログラミング の提案 82 OpenMP の典型的な対象問題である共有メモリを用いたループの並列化を GPGPU と対応付ける場合,GPU 上には階層的な共有メモリが存在するため,演算器間で の並列処理を OpenMP と対応付けて記述することや,演算器群間での並列処理を OpenMP と対応付けて記述することが考えられる.またマルチスレッドプログラミ ングと同様に,実行前や実行時に並列処理部で利用するデータを特定し CPU-GPU 間で送受信することができれば,逐次実行部を CPU で実行し並列実行部を GPU で 実行するような OpenMP と GPU プログラミングとの対応付けが可能になると考え られる. 通信ライブラリを用いたマルチプロセスプログラミング 分散メモリ型並列計算機や PC クラスタなどの共有メモリを持たない環境におい て,また共有メモリ型並列計算機においてもきめ細かい通信制御によって高い性能 を得るために,通信ライブラリを用いたマルチプロセスプログラミングによる並列 化が行われている.特に MPI[99, 100] は様々な実行環境向けの実装が行われており 広く普及している. 通信ライブラリを用いた並列化は SIMD 演算やマルチスレッドプログラミングと 比べてやや粒度の大きな並列化に用いられることが多いため,GPGPU においては GPU 上の演算器群間における並列性の記述に利用することで GPGPU とマルチプ ロセスプログラミングの適切な対応付けが行えると考えられる.一方で GPU 上に は比較的大容量の共有メモリが存在している.既存の共有メモリ型並列計算機にお いては,共有メモリが利用可能であっても MPI を用いて細かい通信制御を行うこと で並列化オーバヘッドが削減でき (OpenMP と比べて) 高い性能が得られることが知 られており,GPGPU においても CPU と同様に共有メモリと通信ライブラリを用い た並列化記述を利用する価値があると考えられる. さらに,CPU-GPU 間でのデータ送受信に通信関数を利用することも考えられる. CPU と GPU はそれぞれ独立したメモリを持つため,GPU を計算ノードと見なした うえで分散メモリ型並列計算機向けの通信ライブラリと同様のインターフェイスを 用いて CPU-GPU 間のデータ通信を記述し,CPU と GPU 上の演算器群での通信を 行いながら処理を行うプログラムが作成できる可能性がある.しかしながら,GPU は CPU と並列に演算を行う事ができるものの,演算の開始や CPU-GPU 間でデー 4.1 既存の CPU 向け並列化プログラミング環境を用いた GPGPU プログラミング の提案 83 タの送受信を行うは CPU による制御が必要なため,既存の CPU 向けプログラムと 同様の記述や動作が行えない可能性もある. 以上のように,GPGPU の持つ並列性は既存の CPU 向け並列化プログラミング 環境を利用して記述できることが期待できる. さらに,CPU-GPU 間での通信を MPI で記述し,GPU 上の演算器群間での並列 処理を OpenMP で記述し,演算器群内の演算器間での並列処理を SIMD 関数で記述 するなど,既存の CPU 向け並列化プログラミング環境を複数組み合わせて利用す ることも考えられる.これにより GPU の持つ並列性を適切かつ容易に記述できる 可能性がある一方,複数の並列化プログラミング環境を組み合わせたプログラミン グはアプリケーションプログラマにとっての実装の手間を増加させてしまうこと考 えられる. 4.1.2 既存の CPU 向け並列化プログラミング環境と CUDA 前項では典型的な GPU を想定し既存の CPU 向け並列化プログラミング環境との 対応付けを検討した.一方で演算器やメモリなどのハードウェア構成とは有効に対 応付けられると期待できる CPU 向けの並列化プログラミング環境であっても,提 供されている GPU プログラミング環境で利用可能な API 等の都合により現実的に は実装することができない可能性や,高い性能が得られない可能性がある. そこで本項では,GPGPU 環境の 1 つである CUDA を対象として,既存の CPU 向け並列化プログラミング環境と GPGPU とのより具体的な対応付けを検討する. 実行対象として CUDA を選択した理由は,CUDA ではシェーダ言語を用いたグラ フィックスプログラミングと比べて GPU に対するプリミティブな操作が可能である こと,シェーダ言語を用いたグラフィックスプログラミングでは 1 度の描画パス中 におけるテクスチャデータの更新ができない (GPU 上の比較的大容量な共有メモリ に対して書き込んだ値は,同じ描画パスで読み込むことができない) ためにプログ ラム変換の手間が増加すると考えられること,そして CUDA を用いたプログラムと C 言語を用いたプログラムとの記述の差はグラフィックス API とシェーダ言語を用 いたプログラムと C 言語を用いたプログラムとの記述の差と比べて小さく処理系を 実装する際の手間をある程度抑えられると考えたことによるものである. 4.1 既存の CPU 向け並列化プログラミング環境を用いた GPGPU プログラミング の提案 84 CUDA CUDA は GPU をデータ並列計算機として活用するためのハードウェアとソフト ウェアのアーキテクチャであり,アプリケーションプログラマに対して C/C++を 拡張した言語仕様のプログラミング言語による GPGPU プログラム開発環境を提供 している.CPU 上で実行される実行ファイルについては CUDA の提供するライブ ラリをリンクする必要がある以外は既存の CPU 向けプログラムと同様に (gcc など を用いて) 作成することが可能であり,GPU 上で実行される実行ファイルは専用の コンパイラ (nvcc) を用いて生成する必要がある. ここでは CUDA と既存の CPU 向け並列化プログラミング環境との対応付けの検 討に向けて,CUDA の実行モデルと演算器やメモリの配置および標準的な C/C++ とのプログラム記述の違いを確認する. CUDA における GPU のハードウェアモデルを図 36 に示す.GPU は Streaming Multiprocessor(以下 SM) と呼ばれる演算ユニット (演算器群) を複数個 (GPU によっ て異なるが,現在は GPU1 台あたり 1 から 30 個) 搭載しており,さらに SM 内には Scalar Processor(以下 SP) と呼ばれる演算器を 8 個搭載している. これに対して並列実行の単位としては Grid,Block,Thread がある. Grid は CPU が GPU に演算を実行させる際の単位である.GPU への演算の指定 は関数単位で行う必要があるため,GPU に対する 1 関数呼び出しを 1Grid と考えれ ば良い. Grid は複数の Block(以下 CUDA Block と呼ぶ) から構成され,さらに CUDA Block は複数の Thread(以下 CUDA Thread と呼ぶ) から構成される.CPU から GPU に 処理を行わせる際には,1Grid の実行において使用する CUDA Block の数と CUDA Block あたりの CUDA Thread の数 (各 CUDA Block で異なる数とすることは不可能) を指定する.これにより CU DABlock 数 × CU DAT hread 数 個のタスクが生成され, CUDA Block 単位で SM に割り当てられる.各 CUDA Block 内の CUDA Thread は 同一 SM 内の SP によって並列実行される.なお,CUDA Block 数や CUDA Thread 数は Grid 内で変更することはできない.Grid 実行時には CUDA Block ごとおよび CUDA Thread ごとに一意に割り当てられた ID を取得することができるため,この ID を利用してデータ並列処理を行うのが CUDA における並列プログラムの基本と なる. 4.1 既存の CPU 向け並列化プログラミング環境を用いた GPGPU プログラミング の提案 85 図 36: CUDA のハードウェアモデル 4.1 既存の CPU 向け並列化プログラミング環境を用いた GPGPU プログラミング の提案 86 物理的な SM や SP の数以上の CUDA Block や CUDA Thread が割り当てられた 場合は時分割実行される.CUDA におけるタスクスイッチのコストは小さいため, SM には SP 数を上回る CUDA Thread 数を割り当て,時間のかかるメモリアクセス が起きた際にタスクスイッチが行われメモリアクセスのレイテンシが隠蔽されるよ うに実装するのが良いとされている.適切な 1CUDA Block あたりの CUDA Thread 数の目安としては 256 程度が良いとされているが,対象プログラムに含まれる命令 の数やメモリアクセスの種類と頻度等により最適な値は上下する. GPU 内の各 SM は独立に処理を行う事ができる一方,同一 SM 内の SP は同時に 同種の演算しか行う事ができない.そのため同一 SM 内の SP が異なる分岐パスを 辿るようなプログラムを記述した場合は,正しい実行結果を返すことは可能である もの,条件が成立しない命令についてはマスク処理を行うため性能が低下する. 一方,CUDA における GPU を用いた計算モデルは以下の処理を繰り返すモデル である. 1. CPU がメインメモリ上のデータを GPU 上のメモリへと転送する 2. CPU から GPU に対して関数 (Grid) 実行を指示し,GPU が演算を開始する 3. GPU の演算が終了した後に,CPU から GPU への指示によって GPU 上のメ モリからメインメモリへ演算結果などのデータが転送される メインメモリと GPU 上のメモリの間におけるデータの送受信については,CPU 上 のプログラムから GPU 上のメモリのアドレスを直接参照することはできず,メモ リの確保や転送を行う API 関数を介して行う必要がある.また GPU 上には複数種 類の異なる特徴を持つメモリが存在し,全てのメモリを CPU から操作できるわけ ではない. GPU 上のメモリは図 37 のように分類され,各メモリはそれぞれ以下のような特 徴を持っている. 1. GlobalMemory:全 CUDA Block および全 CUDA Thread から共有メモリとし て読み書き可能.(高レイテンシ・低速・大容量) 2. ConstantMemory:全 CUDA Block および全 CUDA Thread から読み取り専用 のメモリとして扱うことができる.(高レイテンシ・キャッシュされる・GPU 全体で 64KB) 4.1 既存の CPU 向け並列化プログラミング環境を用いた GPGPU プログラミング の提案 87 3. TextureMemory:全 CUDA Block および全 CUDA Thread から読み取り専用 のメモリとして扱うことができる.(高レイテンシ・キャッシュされる・大容量) 4. SharedMemory:各 CUDA Block が独立に持ち同一 CUDA Block 内の CUDA Thread からは共有メモリとして読み書き可能. (オンチップ・低レイテンシ・ 高速・SM ごとに 16KB) 5. 各 CUDA Thread が独立に持つ Register( .低レイテンシ・高速・SM ごとに 8192 本または 16384 本) 6. 各 CUDA Thread が独立に持つ LocalMemory. (GlobalMemory と同等) GlobalMemory,ConstantMemory,TextureMemory については,専用のメモリ操作 関数を用いることで CPU から Grid を実行する前後に読み書きすることができるが, その他のメモリについては CPU からアクセスすることはできない. CUDA におけるプログラム記述では変数宣言時に接頭語を付加することでその変数 がどのメモリとして扱われるかを指定する. device をつけることで GlobalMemoy, constant で ConstantMemory, shared で SharedMemory として扱われる.TextureMemory は専用の関数と構造体を用いて利用する.接頭語をつけずに関数内で 宣言された変数は Register として扱われ,Register の数を超えた分は自動的に Lo- calMemory として扱われる. 変数と同様に,関数についても接頭語を利用して振る舞いを指定する. global をつけた関数 (Global 関数) は CPU から呼び出されて GPU 上で実行さ れる関数として, device をつけた関数 (Device 関数) は GPU 上で実行される関数 ( global 関数もしくは device 関数 ) から呼び出されて GPU 上で実行される関数 として扱われる.これらの関数は GPU 上で実行可能なバイナリのみが生成される. host をつけた関数 (Host 関数) は CPU 上で実行される関数から呼び出されて CPU 上で実行される関数として扱われ,接頭語のない関数もこれと同じ扱いとなる. host と device を同時につけた場合は, device をつけた関数と同様に GPU 上 で実行可能なバイナリが生成されるとともに, host をつけた関数と同様に CPU 上でも実行可能となる. CPU から行う Global 関数の呼び出しは,関数の終了を待たずに制御が戻る非同 期呼び出しである.そのためマルチスレッド化など手間のかかるプログラム記述を 4.1 既存の CPU 向け並列化プログラミング環境を用いた GPGPU プログラミング の提案 88 図 37: CUDA のメモリモデル 4.1 既存の CPU 向け並列化プログラミング環境を用いた GPGPU プログラミング の提案 89 行うことなく CPU と GPU による並列処理を記述することができる.CPU 上で専 用の関数を実行することで,Global 関数の終了を確認する (待つ) ことができる. GPU 上で実行される関数については,C/C++言語と比べて再帰呼び出しや static 変数が使えないといった制限がある.また CUDA 特有の処理として,同一 CUDA Block 内の全 CUDA Thread で同期をとる関数や,GPU 全体でのアトミック実行を 保証する atomic 関数が提供されている. このように,CUDA を用いてプログラムを作成するには,GPU のアーキテクチャ や実行モデル,プログラムの記述方法を把握し,手間のかかるプログラミングを行 わなくてはならずアプリケーションプログラマにとっては手間が大きい.特に GPU を最大限に活用して高い性能を得るためには,GPU 上に搭載されている多数の演算 器と様々なメモリを活用する必要があるため,アプリケーションプログラマにとっ てのプログラミングの手間は非常に大きなものとなる. なお本研究では複数の GPU を搭載した環境向けの実装を行っていないため詳細 については触れないことにするが,CUDA は複数の GPU にも対応している. 以下,CUDA と既存の CPU 向け並列化プログラミング環境との対応付けを検討 する. SIMD プログラミング SIMD 処理は多数のデータに同じ演算を行うものである (図 38-1) ことから,同時 に同じ種類の演算しか行うことができない同一 SM 内の SP による CUDA Thread レ ベルの並列処理にも,CUDA Block レベルの並列処理にも対応付けることができる と考えられる. 特に SIMD 化は細粒度の並列化に適していることから,SIMD 演算を多数の CUDA Thread による SharedMemory を用いた並列計算へと対応付けることで,高速な SharedMemory を有効に活用した高速処理による高い性能が期待できる (図 38-2). 一方で,GlobalMemory を共有メモリと見なして CUDA Block レベルの並列性を 記述し,SIMD 関数へのデータセットを CPU から GPU へのデータ転送,SIMD 関 数の実行を GPU 上での演算とみなし,GPU 全体で SIMD 演算を行うことも考えら れる (図 38-3).この対応付けでは,アプリケーションプログラマに対して CUDA プ 4.1 既存の CPU 向け並列化プログラミング環境を用いた GPGPU プログラミング の提案 90 図 38: SIMD プログラミングと CUDA との対応付け 4.1 既存の CPU 向け並列化プログラミング環境を用いた GPGPU プログラミング の提案 91 ログラミングそのものを隠蔽することが可能となり,習得や実装の手間が大きく削 減できる可能性がある. スレッドライブラリを用いたマルチスレッドプログラミング CPU 向けの pthread による並列プログラミングでは,各スレッドの行う処理を関 数単位でそれぞれ記述し,スレッドごとに任意のタイミングでの実行制御を行う (図 39-1).一方で CUDA において pthread のスレッドのように独立して処理を行うこと ができる実行単位としては,CUDA Block レベルでの並列処理が考えられる.しか しながら CUDA では全 CUDA Block・全 CUDA Thread が同時に演算を開始し,ま た CPU が GPU の演算終了を待つ場合には全 CUDA Block・全 CUDA Thread の演 算終了を待つという実行モデルとなっている.そのため,pthread のように任意の タイミングで個別のスレッドを生成・破棄することができず,実行モデルを合わせ ることができない (図 39-2). 別の対応付けとしては,CUDA では CPU から GPU に対する処理の呼び出しを関 数単位で行うことから,GPU 全体の処理を 1 スレッドとして記述し GPU の数をス レッドプログラミングにおけるスレッド数に対応付けることによるマルチスレッド プログラムと CUDA との対応付けが考えられる.しかしながらこの対応付けでは, CPU と各 GPU では共通のメモリ空間を持つことができないため,スレッド間で共 有メモリを利用するスレッドプログラミングの基本的な動作を対応付けることがで きない (図 39-3). 以上から,実行モデルやメモリモデルの対応付けが難しいため pthread などのス レッドライブラリを用いたマルチスレッドプログラミングの手法は CUDA プログラ ミングに適しているとは言い難い. OpenMP を用いた並列化プログラミング CPU 向けの OpenMP を用いた並列化プログラミングでは,複数のスレッドが共有 メモリを用いた並列処理を行う (図 40-1).OpenMP の典型的な並列化対象問題であ るループの並列化と CUDA の対応付けを考えた場合,CUDA では GlobalMemory を GPU 上の全 CUDA Block・全 CUDA Thread が,また SharedMemory を各 CUDA 4.1 既存の CPU 向け並列化プログラミング環境を用いた GPGPU プログラミング の提案 92 図 39: スレッドライブラリを用いたマルチスレッドプログラミングと CUDA との対 応付け 4.1 既存の CPU 向け並列化プログラミング環境を用いた GPGPU プログラミング の提案 93 Block 内の全 CUDA Thread が共有しているため,GlobalMemory を共有メモリと見 なした GPU 全体での大規模な並列化,もしくは SharedMemory を共有メモリと見 なした局所的な並列化が行えると考えられる (図 40-2). また CUDA Block 単位では同時に異なる種類の演算を行うことができるため,sec- tions 並列の各 section を CUDA Block に対応付けることも考えられる.さらに階層 的な並列性を持つ OpenMP プログラムについても,上位の階層を CUDA Block に, 下位の階層を CUDA Thread に対応付けることで適切な対応付けが行えると考えら れる. OpenMP を用いた並列化では,アプリケーションプログラマが指示子を用いて明 示的に指定した部分のみが並列実行され,その他の部分は逐次実行される.そのた め逐次実行部と並列実行部の境界が明確である.一方 CUDA でも GPU による並列 処理は global 関数および device 関数として CPU 上で実行される関数とは明確 に区別して記述される.プログラム全体の中から並列化による高速化を行いやすい 部分のみを選択的に並列実行するという考え方は CUDA と OpenMP で共通してい るため,並列実行部を GPU 上で,逐次実行部を CPU 上で実行するという対応付け は,アプリケーションプログラマにも理解しやすく記述しやすいと考えられる. 一方で,既存の OpenMP では逐次実行部と並列実行部とで同じメモリ空間を共有 するためデータを送受信する必要はないが,CUDA では CPU と GPU は互いに独立 したメモリを持つため,逐次実行部と並列実行部とで使用するデータを送受信する 必要がある.ただし,OpenMP の実行モデルでは逐次実行部と並列実行部が同時に 実行されることはないため,逐次処理部分と並列処理部分の境界で必要なデータを 全て送受信すれば正しい実行結果が得られると考えられる (図 40-3).複雑なポイン タ参照を含むプログラムの場合は必要なデータを全て送受信すること自体が容易で はないが,これは既存の OpenMP でも間接ポインタ参照を含むプログラムの場合に データの依存関係の問題で並列高速化が行えないのと同様の問題であり,CUDA と 対応付ける場合にのみ問題となるわけではない. CPU を搭載した計算機システムにおいて並列実行部をより高速に実行するには, アプローチ 1 で行ったように並列実行部を CPU と GPU で分割し並列実行すること が有効であると考えられる.しかし,CPU-GPU 間での適切なデータの送受信が必 要になるため,実装が難しくなることや逆に性能が低下してしまうことが予想され 4.1 既存の CPU 向け並列化プログラミング環境を用いた GPGPU プログラミング の提案 94 図 40: OpenMP を用いた並列化プログラミングと CUDA との対応付け 4.1 既存の CPU 向け並列化プログラミング環境を用いた GPGPU プログラミング の提案 95 る.また CPU と GPU による並列実行部の分割並列実行は難しいとしても,SPRAT のように並列実行部を CPU で実行するか GPU で実行するかを選択する機構を実装 すれば,対象問題のデータ規模が小さい場合にも高速に実行できると考えられる. 通信ライブラリを用いたマルチプロセスプログラミング MPI は複数のプロセスが並列処理を行う際にプロセス間の通信を行うために利用 されている (図 41-1).そのため CUDA において GPU 上の並列処理に MPI を利用 するには,同時に異なる種類の演算を行う事ができない CUDA Thread 間の並列処 理ではなく,CUDA Block 間の並列処理,もしくは CPU と GPU での並列処理に対 応付けるべきであると考えられる. MPI を GPU 上の CUDA Block 間での通信に割り当てるうえでは,CUDA Block 間の同期とメモリ割り当てが課題となる. MPI の最も基本的な処理としてプロセス間の同期通信やバリア処理が考えられる が,CUDA には CUDA Block 間での同期をとる機構が提供されていない.しかし, atomic 関数があるため CUDA Block 間で同期をとることは可能であり,同期通信や バリア処理を行うことは不可能ではない. メモリ割り当てについては,MPI ではプロセス毎のローカル変数やノード毎のロー カルメモリを通信しながら並列処理を行う.これに対して CUDA では,CUDA Block 毎にプライベートなメモリとして SharedMemory があるものの,その容量は CUDA Block あたり 16KB と小さいため CPU 向けの MPI におけるプロセス毎のローカル変 数のように使うと実行可能な問題の規模に厳しい制限がかかることになる.そのた め,容量を超えて GlobalMemory に配置されることを前提で Register にデータを配 置するか,GlobalMemory を分割して利用するなどの方法によって MPI に対応した 動作が可能となると考えられる.しかしながらこの場合は,アプリケーションプログ ラマにとっては CUDA Thread レベルの並列化や SharedMemory と GobalMemory の使い分けなどを意識して記述する必要が生じるため,習得や実装の手間が増加し てしまうことが問題となる. さらに,CUDA では物理的な CUDA Block 数を超える並列度の並列処理でも十分 に高い性能を得ることができる.そのため GPU 上に比較的大容量の共有メモリを 備えているものの,CPU 向けの MPI の用に各 CUDA Block が共有メモリをそれぞ 4.1 既存の CPU 向け並列化プログラミング環境を用いた GPGPU プログラミング の提案 96 図 41: 通信ライブラリを用いたマルチプロセスプログラミングと CUDA との対応 付け 4.1 既存の CPU 向け並列化プログラミング環境を用いた GPGPU プログラミング の提案 97 れ占有し,また通信用に共有メモリを確保してしまっては,CUDA Block 単位で利 用可能なメモリの容量がが小さくなり小規模な問題しか解けなくなってしまう (図 41-2). そのため CPU 向けの MPI のように CUDA Block 間でデータの送受信を行うより は,各 CUDA Block が CUDA Block 同士で通信関数を用いて通知を行いつつ共有 メモリを用いて並列処理を行う方が,メモリを有効活用できると考えられる.しか しこれでは一般的な MPI のモデルとは異なるものとなってしまう. 一方,CPU と GPU での通信を MPI の通信関数のように記述し,CPU と GPU による並列計算を行うことも考えられる.しかしながら CUDA の実行モデルでは, CPU から GPU へデータを送信し,GPU 上で並列処理を行い,GPU から CPU へ のデータ書き戻しを行うという一連の動作を実行単位としている.そのため,CPU 向けの MPI では独立した複数のプロセスが任意のタイミングで互いにデータの送受 信を行いながら並列処理を行うのに対して,CUDA では関数 (Grid) 実行の前後にし か CPU-GPU 間のデータ送受信が行えないため,CPU 向けの MPI と CUDA を適切 に対応付けることは困難である (図 41-3). まとめ 以上から,SIMD 化プログラミングは並列処理の粒度から主に CUDA Thread レ ベルでの並列処理の記述に,MPI は同時に実行可能な処理やデータ通信タイミング の制約から CUDA Block レベルでの並列処理の記述に,OpenMP は CUDA Thread レベル・CUDA Block レベル・CPU と GPU での並列処理の記述のいずれにも対応 付けることができると考えられる.さらに,これらの各プログラミング環境を組み 合わせて利用することも考えられる.複数の CPU 向け並列化プログラミング環境を 組み合わせて用する場合は複数のプログラミング環境を使いこなす必要があるため プログラミングが難しくなる可能性があるものの,既にそれぞれの手法を習得して いるアプリケーションプログラマにとっては利用しやすい可能性がある.また,対 象アプリケーションに階層的な並列性があるなどアルゴリズムとの親和性が高い場 合には,複数の CPU 向け並列化プログラミング環境を組み合わせて利用すること も有効であると考えられる. 4.2 OMPCUDA : CUDA 向け OpenMP の提案と実装 4.2 98 OMPCUDA : CUDA 向け OpenMP の提案と実装 本節では前節に基づく具体的な実装として,CUDA 向けの OpenMP 処理系 “OM- PCUDA” を提案し,設計と実装を行う. アプリケーションプログラマに対して,GPU(CUDA) のアーキテクチャを隠蔽し容 易にプログラミング可能とするには CPU-GPU 間の通信や GPU の制御を隠蔽する必 要があり,また GPU 内部の演算器が持つ並列性を利用した性能向上を得るには GPU 内の並列性を記述する必要がある.これに対して前節での検討の結果,OpenMP を 用いることで CPU-GPU 間の通信や GPU の制御と GPU 内の並列性の両方を記述 できると考えられる.そこで,CUDA 向けの OpenMP 処理系 “OMPCUDA” を提案 する.以下本項では OMPCUDA の具体的な実装について述べる. OpenMP を用いた典型的な並列プログラムは,C 向け OpenMP における “for” 指 示子および Fortran 向け OpenMP における “DO” 指示子を用いたループ並列プログ ラムである.これは,OpenMP 向けのベンチマークプログラムとして広く用いられ ている SPEComp2001[101] において半数以上のベンチマークプログラムで利用され ている指示子が,“for” 指示子および “DO” 指示子,並列実行部で利用される各変 数をスレッド間で共有するか否かを指定する “shared” 指示子および “private” 指示 子,そして並列実行部を実行する際に並列実行の最後で全スレッドの持つ変数の総 和を求めるなどの処理に利用される “reduction” 指示子のみであることから明らか である. そこで OMPCUDA は,OpenMP を用いた典型的な並列プログラムであるループ 並列プログラムに対して,GPU の特徴である高い並列性を有効に活用し効果的に並 列化・高速実行できるようにすることを主眼に置いて実装した. 以下 OMPCUDA の実装について,OMPCUDA 全体の構成,OMPCUDA を構成 するプログラム変換機構の構成,実行時ライブラリの構成の順に述べる. 4.2.1 全体の構成 本項では OpenMP と CUDA の並列実行モデルおよびメモリモデルのより具体的 な対応付けを検討する. 前節で述べたように,既存の OpenMP は指示子によって指定された並列実行部 4.2 OMPCUDA : CUDA 向け OpenMP の提案と実装 99 のみを複数のスレッドで並列実行し,それ以外の部分は逐次実行する.逐次実行部 と並列実行部では,主記憶上に確保した共有メモリをスレッド間で共有する.そこ で OMPCUDA では,並列実行部のみを GPU で実行し,他の部分は CPU で実行す ることとする.つまり,既存の OpenMP がスレッド単位で並列実行を行うのに対 して,OMPCUDA では CUDA Thread 単位で並列実行を行うこととなる.この際, GlobalMemory を共有メモリと見なし,多数の CUDA Thread を用いて並列計算を 行う.CUDA を用いて高い性能を得るには SharedMemory を活用することが重要と されているものの,OpenMP に適した高い並列性を持つ対象問題であれば並列実行 によりある程度高い性能を得られ,OMPCUDA の有用性が確認できるものと考え られる. 以上に基づく OpenMP と OMPCUDA の実行モデルとメモリモデルの対応付けを 図 42 に示す. OMPCUDA の実装は,既存の OpenMP 処理系 Omni OpenMP Compiler version 1.6[102] (以下 Omni) をベースに行った.これにより OpenMP 指示子の解釈など CPU 向けの OpenMP と共通の処理の再実装を避けており,プログラム変換機構および新 しい実行時ライブラリを実装することで OpenMP プログラムの並列実行部を CUDA 対応 GPU 上で実行可能としている. Omni と OMPCUDA の関係および OMPCUDA の構成を図 43 に示す. Omni が OpenMP 指示子の挿入されたソースコードから並列化された実行ファイ ルを生成するための手順は以下の通りである. 1. OpenMP 指示子の挿入されたソースコードを入力として受け取り,各言語に 対応した Frontend によって OpenMP 指示子の入った中間コードへと変換する. 2. OpenMP 指示子の挿入された中間コードに対して,OpenMP モジュールを用 いて OpenMP 指示子の解釈を行い,Omni の実行時ライブラリ呼び出しを含 む中間コードを生成する.この際,OpenMP における並列実行部の指定はブ ロック単位で行われるのに対して,Omni の中間コードにおける並列実行部は 関数として分離させられ,並列実行部関数をスレッドに割り当てる Omni の実 行時ライブラリ関数によって呼び出されるように書き換えられる. 3. 中間コードを C 言語プログラムに変換 (デコンパイル) し,バックエンドコンパ 4.2 OMPCUDA : CUDA 向け OpenMP の提案と実装 図 42: OpenMP と OMPCUDA の実行モデルとの対応付け 100 4.2 OMPCUDA : CUDA 向け OpenMP の提案と実装 図 43: Omni と OMPCUDA の関係および OMPCUDA の構成 101 4.2 OMPCUDA : CUDA 向け OpenMP の提案と実装 102 イラを用いてコンパイルし,Omni の実行時ライブラリとリンクして実行ファ イルを生成する. このように,Omni によって分離させられた並列実行関数は,実行時ライブラリ の並列実行開始関数によってスレッドに割り当てられて並列実行されることとなる. 一方で CUDA における GPU 上での並列処理も関数単位であり,CPU からの指示に 従い GPU 上の多数の演算器で同時に同じプログラムを実行する.ただし,演算の 前に CPU から GPU へ必要なデータを送信し,また演算の後には GPU から CPU へ 結果を送信する必要がある. そこで OMPCUDA では,“Omni の並列実行開始関数呼び出し” を “CPU から GPU へのデータ送信,GPU への演算実行開始指示,GPU から CPU へのデータ書き戻 し” の一連の処理に置き換えるプログラム変換機構を実装した.このプログラム変 換機構は,プログラムを調査し CPU-GPU 間で送受信する必要があるデータを自動 的に送受信する機能を持つ.ただし,ポインタを含む構造体など単純に送受信でき ないデータを利用しているプログラムには対応していない. OMPCUDA では,処理の対象を OpenMP 指示子の挿入されたソースコードでは なく,Omni によって指示子の解釈が行われ実行時ライブラリの呼び出しに変換さ れた中間コードとした.Omni の中間コードは Xcode と呼ばれる専用の中間表現に よって記述されており,Omni に含まれる Exc Java tool kit によって解析・書き換 え・C 言語コードとの相互変換を行うことができる.OpenMP 指示子の解析や実行 時ライブラリへの変換を行う OpenMP モジュールも Exc Java tool kit の一部として 実装されている.OMPCUDA のプログラム変換機能もその機能の多くを Exc Java tool kit の追加モジュールとして実装しているが,CPU 向けのコードと GPU 向けの コードを別々にコンパイルするための処理や CPU-GPU 間のデータ転送に向けたプ ログラム解析のために,元々の Omni に組み込まれている各種モジュール (Java の クラス) に対する機能追加や変更も行っている. CUDA 用実行時ライブラリは,Omni の実行時ライブラリが持つ機能を CUDA 向 けに再実装したものである. 4.2 OMPCUDA : CUDA 向け OpenMP の提案と実装 4.2.2 103 プログラム変換機構の実装 OMPCUDA のプログラム変換機構が行う,実行時ライブラリの呼び出しを含む Omni の中間表現を CUDA に対応したプログラムへと変換する手順を以下に示す. この手順は図 44 と対応している.なお,Omni の中間コードは C 言語で記述された プログラムと相互変換が可能であることから,図 44 では Omni の出力する中間コー ドを C 言語で記述されたプログラムに置き換えたうえで,主要な部分以外を簡略化 して記述している. 1. 中間表現で書かれたプログラム全体から実行時ライブラリの並列実行開始関 1 . 数が呼び出されている部分を探し出す (図 44-°) 2. 並列実行部の内部で利用されている変数を確認し,関数内ローカルでない変 数,すなわち CPU-GPU 間で送受信を行う必要がある変数を特定する.また Omni の並列実行開始関数は並列実行部で利用する呼び出し元のローカル変数 も引数として受け取る仕様のため,引数を確認して送受信を行う必要がある 2 . ローカル変数を特定しておく (図 44-°) 3 . 3. 並列実行部を別ファイルに書き出し,元のソースコードから削除する (図 44-°) 並列実行部に関数呼び出しが存在する場合は,その関数内で利用している変数 についても同様に確認し,まとめて書き出す.ただし,並列実行部で呼ばれて いる関数は逐次実行部からも呼び出される可能性があるため,元のソースコー ドにも残したままとする. 以下,別ファイルに書き出したソースコードを GPU コード,残されたソース コードを CPU コードと呼ぶことにする.GPU コードは並列実行部の数だけ 存在することとなる. 4. CPU コードについては既に述べた通り,Omni の並列実行開始関数呼び出し を CPU-GPU 間のデータ送受信および GPU への演算実行開始指示に書き換え る.これをバックエンドコンパイラでコンパイルし,CUDA の実行時ライブ 4 . ラリとリンクして CPU 用の実行ファイルを生成する (図 44-°) 5. GPU コードには,CUDA の記法に従い関数や変数に指示子を付加する.さら に,関数の引数を調整し,CPU-GPU 間で変数の送受信が行えるようにしたう 4.2 OMPCUDA : CUDA 向け OpenMP の提案と実装 図 44: プログラム変換機構の処理手順 104 4.2 OMPCUDA : CUDA 向け OpenMP の提案と実装 105 えで,CUDA コンパイラ (nvcc) を利用して CUDA 用の実行ファイルを生成す 5 . る (図 44-°) 現在の実装では実行時に並列実行部の数だけ CUDA 用の実行ファイルが必要だ が,これは CPU 用の実行ファイルと結合するなどの手段で不要とすることができる と考えられる.また,現在の実装では並列実行部で参照するデータは全て送受信の 対象としている.4.3 節の評価で示すように全てのデータを送受信することが直接致 命的な性能低下にはならないと考えられるが,GPU 上で変更されることのないデー タは CPU へ書き戻さないようにするなど送受信する容量を削減することで性能が さらに向上すると考えられる.いずれも今後 OMPCUDA をより実用的なツールと していくうえでは解決する意味がある課題であるため,今後の発展課題とする. 4.2.3 実行時ライブラリの実装 Omni の実行時ライブラリは,スレッドの生成および割り当てやループのスケジュー リング,スレッド間の同期処理,リダクション演算などの機能を提供している. OMPCUDA の実行時ライブラリは,Omni において逐次実行部で行っている処 理は CPU で行い,並列実行部で行っている処理は GPU で行う,という方針で実装 した. 単純な for ループの並列化に最低限必要な関数として,GPU 上で実行される for ループのスケジューリングを行う関数を実装した.さらに,for ループの並列化と ともに利用されることの多いリダクション演算に必要な,GPU 上で実行されるリ ダクション関数を実装した.Omni では CPU 上で実行されるスレッド割り当ておよ び並列実行開始関数も提供しているが,これについてはプログラム変換機構による CUDA 実行時ライブラリ関数の呼び出しへの書き換えが役割を果たしているため, 実行時ライブラリでは特に処理を行わない. for ループのスケジューリング Omni における for ループの並列化は,実行時ライブラリが提供する,各スレッド が自らのスレッド ID を元に新たな部分ループを作成するための関数 (スケジューリ ング関数) を用いて行われている.CUDA の実行時ライブラリにも一意の ID を得る 4.2 OMPCUDA : CUDA 向け OpenMP の提案と実装 106 機能が備わっているため,OMPCUDA はこれを用いて Omni と同様に部分ループを 作成するための関数を提供することとした. CUDA における並列実行は既存の CPU におけるスレッド実行と異なり,CUDA Block と CUDA Thread の 2 階層によって構成されている.GPU は CPU からの並 列実行開始指示を受けると,多数の CUDA Thread が同時に演算を開始する.同一 CUDA Block 内の CUDA Thread は同時に異なる演算を行うことができず,また, 各 CUDA Block を構成する CUDA Thread の数は全 CUDA Block で同一である.し かし各 CUDA Thread は固有の ID を持つため,この ID を用いて共有メモリ上の異 なるデータに対して同時に演算を行うことができる. そのため CUDA における並列処理については,1CUDA Block 内の複数 CUDA Thread を用いた並列処理,複数 CUDA Block を用いるが各 CUDA Block 内では 1CUDA Thread のみを利用する並列処理,複数 CUDA Block・複数 CUDA Thread を用いた並列処理,以上の 3 種類の並列処理が考えられる.複数 CUDA Block・複 数 CUDA Thread を用いた並列処理が最も多くの演算を同時実行できるものの,同 一 CUDA Block 内の各 CUDA Thread は同時に異なる演算を行えないため,対象問 題によっては複数の CUDA Thread を用いても性能向上が得られない可能性がある. これに対して,単純な for ループの並列化では各スレッドが同時に同じ演算を行 うことが多い.そのため for ループの並列化を CUDA に割り当てるうえでは,複数 の CUDA Thread による並列処理でも性能向上が可能であり,上記 3 種類の並列処 理のいずれにも対応付けることができると考えられる. Omni はループ並列化におけるスケジューリング方法を複数提供しておりアプリ ケーションプログラマが選択することができる.OMPCUDA では最も単純なスケ ジューリングである,ループのイタレーションを等分割したスタティックスケジュー リングのみを提供し,他のスケジューリング方法については検討を行うのみとする. 現在提供している OMPCUDA における for ループのスケジューリング (割り当て) 例を図 45 に示す. CUDA 向けにおける最適な CUDA Block 使用数・CUDA Thread 使用数は,対 象プログラムの並列性や対象プログラム内の命令の構成,対象 GPU の性能 (主に 搭載している SM の数) により左右される.現在は CUDA Thread 使用数のデフォ ルト値として (CUDA Thread 使用数については 1CUDA Block あたり 256 程度の 4.2 OMPCUDA : CUDA 向け OpenMP の提案と実装 図 45: OMPCUDA における for ループのスケジューリング例 107 4.2 OMPCUDA : CUDA 向け OpenMP の提案と実装 108 CUDA Thread を利用するべきであるという最適化指標が示されているため) 256 を, CUDA Block 使用数については for ループの並列度を CUDA Thread で割った値 (た だし CUDA の仕様に定められている利用可能な CUDA Block 数の上限を超えない ように調整する) としている. なお Omni の実行時ライブラリは環境変数や実行時の関数呼び出しにより利用す るスレッドの数を変更することが可能となっている.OMPCUDA も最適な CUDA Block 使用数・CUDA Thread 使用数は対象問題に依存することから,実行時に関数 や環境変数を用いて CUDA Block 使用数・CUDA Thread 使用数を変更できるよう にした. ただし,一般的に既存の OpenMP においてスレッド数として指定する意味がある のは実行環境に存在する CPU(コア) 数程度の値であるのに対して,CUDA において 最も高い性能が得られる CUDA Block 数・CUDA Thread 数は数百から数千である. そのためアプリケーションプログラマが自ら CUDA Block 数・CUDA Thread 数を指 定する場合は,CUDA における適切な並列度の指定に関する知識がなくては適切な 値を指定できない.これはアプリケーションプログラマに対して実行環境に関する知 識を習得する手間を削減するという本アプローチの趣旨に反している.OMPCUDA が自動的に常に適切な CUDA Block 数・CUDA Thread 数を求められるようにする ためにも,今後より多くの GPU 環境や対象プログラムに対して適用実験を行う必 要がある. なお,Omni が提供している for ループのスケジューリング方法の例としては,以下 のものが挙げられる.いずれも並列実行部において各スレッドが実行するスケジュー リング関数として実装されている. 1. 指定されたチャンクサイズを単位としたスタティックなラウンドロビンスケ ジューリング 2. 指定サイズのチャンクサイズを単位としたダイナミックスケジューリング 3. 指定されたチャンクサイズを最初の割り当て単位とした Guided Self Scheduling OMPCUDA でもこれらの各スケジューリングアルゴリズムを実装することは可 能であると考えられる.しかしダイナミックなスケジューリングを行う場合には, チャンクの再割り当てを行う際に多重割り当て等が起きないよう CUDA Block 内の 4.2 OMPCUDA : CUDA 向け OpenMP の提案と実装 109 CUDA Thread 同士または CUDA Block 間の CUDA Thread 同士の待ち合わせや排 他制御が必要となる可能性がある.OMPCUDA では GPU 全体で合計数千の CUDA Thread を同時に実行することが予想されるため,待ち合わせにより性能が低下する 可能性のあるダイナミックスケジューリングよりもスタティックスケジューリング の方が適していると考え,今回の実装を選択した. リダクション演算 “for” 指示子や “DO” 指示子といったループ並列化指示子とともに多くの OpenMP プログラムで利用されている指示子に “reduction” 指示子がある.“reduction” 指示 子は並列実行部を実行する際に並列実行の最後で全スレッドの持つ変数を足し込ん だり,全スレッドの持つ同名の変数の中で最も大きな値のみを並列実行部が終了し た後も残したりするために利用される指示子である.Omni では “reduction” 指示 子を実行時ライブラリのリダクション関数として実装している.OMPCUDA では “reduction” 指示子を用いた処理の中でも最も典型的な処理である “全スレッドの持 つ同名な変数の総和を求める処理” を実行時ライブラリ関数として実装した.以下 この “全スレッドの持つ同名な変数の総和を求める処理” を単にリダクション演算と 呼ぶことにする. GPU や CUDA を用いたリダクション演算については,既にいくつかの実装 [103, 104] が知られている.OMPCUDA では Owens らの手法 [105] をベースに SharedMemory を用いた並列リダクション関数を実装して利用することにした.ただし Owens らの手法は CUDA Block 内のリダクション演算のみを扱っている.CUDA Block 内 のリダクション演算は SharedMemory を用いることで高速に行うことができる一方, 問題全体,すなわち CUDA Block 間でのリダクション演算については,atomic 演算 を用いた CUDA Block 間での排他制御や CUDA Block 間での待ち合わせを行いな がら GlobalMemory に対して処理を行う必要があるため実行時間が長くなる可能性 がある.むしろ CUDA Block 単位でリダクション演算を行った結果を CPU に返し, CPU 上で最終的なリダクション演算を行った方が良い性能が得られることが考えら れる. OMPCUDA では CUDA Block 毎にリダクション演算を行った後,各 CUDA Block 内の 1CUDA Thread が atomic 演算によって最終的なリダクションを行うという実 装を行った.そのため利用する CUDA Block 数が増えると CUDA Block 間のリダク 4.2 OMPCUDA : CUDA 向け OpenMP の提案と実装 110 ション時間が増大し,性能に悪影響を及ぼすと考えられる.この影響については次 節の性能評価で確認する. OMPCUDA の実行モデルでは,OpenMP プログラムの共有メモリに対応する CUDA の共有メモリとしては GlobalMemory のみを利用しているが,リダクショ ン演算では SharedMemory を利用している.このように実行時ライブラリ関数の中 で SharedMemory を用いることで,アプリケーションプログラマには SharedMem- ory を意識させずに SharedMemory を活用した高速化が行えると考えられる.例え ば OMPCUDA の発展的な実装の案として,ループ並列部の内部にさらなる並列性が 見られる場合はループの並列化を GlobalMemory を用いた CUDA Block レベルでの 並列処理に対応付けたうえでループ内部の並列性を SharedMemory を用いた CUDA Thread レベルでの並列処理に対応付けることなどが考えられる. 4.3 OMPCUDA の評価 4.3 111 OMPCUDA の評価 本節では OMPCUDA について,並列実行の効果が得られるかの性能確認と並列 プログラムが容易に作成できるかの評価を行う. 実験対象プログラムとしては,OpenMP による並列化に適した理想的な並列性を 持つプログラムが OMPCUDA によって容易に並列高速化できることを確認するた め,並列化が容易な問題である行列積と円周率の求解 (グレゴリ級数) を用いる.各 評価においては,CPU を用いた場合や,OMPCUDA を用いずに直接 CUDA を用い た場合との性能や記述の容易性の比較を行う.また円周率の求解ではリダクション 演算を利用しているため,リダクション演算の実装についての評価も行う. 評価環境は表 3 に示す通りである. 表 3: 評価環境 2 CPU Xeon E5345 2.33GHz (4 コア) メインメモリ 4.0GB (32bitOS につき 3.2GB 使用可) GPU GeForce GTX 280 (コアクロック 602MHz, SP クロック 1296MHz) ビデオメモリ 1.0GB GPU 接続バス PCI-Express x16 (Gen 2) OS CentOS 5.0 (kernel 2.6.18) コンパイラ GCC 3.4.6 Omni OpenMP Compiler version 1.6 nvcc 2.0 v0.2.1221 以下,行列積を用いた性能確認,円周率の求解を用いた性能確認,実装の手間や 記述の容易性に関する評価という順番で OMPCUDA の評価について述べる. 4.3.1 行列積を用いた性能確認 アプローチ 1 で述べた通り,行列積はデータ量に対して計算量が多く並列性が高 い問題であり,GPU を用いて高速実行できる問題としても知られている.本アプ 4.3 OMPCUDA の評価 112 ローチでは最大性能を得ることよりも単純な実装で容易に性能を得られることを重 視しているため,単純なループ処理による実装を用いて性能の比較を行った. 本評価における行列積は全て単精度浮動小数の転置なし正方行列に対する行列積 とし,行列の一辺の長さを問題サイズと呼ぶことにする. 評価では以下の実装についての性能比較を行った. 1. OMPCUDA-loop3 : OMPCUDA を用いた,単純な 3 重ループによる行列積の 実装 (図 46) 2. OMPCUDA-loop2 : OMPCUDA を用いた,loop3 における外側の 2 ループを 併合して 2 重ループとした実装 (図 47) 3. SimpleCUDA : SharedMemory は用いずに各 CUDA Thread が行列の各要素を 担当する,CUDA を用いた実装 (ソースコード概要を付録 1 に載せる) 4. UseSharedCUDA : CUDA のサンプルとして提供されている SharedMemory を 用いた実装 (CUDA SDK 2.0 付属のサンプル MatrixMul を利用) 5. OmniCPU-loop3 : Omni を用いたループ並列化 (図 46 を Omni でコンパイル したもの,CPU 上で実行,1 スレッドから 8 スレッド) 6. OmniCPU-loop2 : Omni を用いたループ並列化 (図 47 を Omni でコンパイル したもの,CPU 上で実行,1 スレッドから 8 スレッド) 7. AtlasCPU-nothread, AtlasCPU-pthread : ATLAS を用いたもの (非スレッド 対応版の AtlasCPU-nothread とスレッド対応版の AtlasCPU-pthread,いずれ も CPU 上で実行) 図 48 は,問題サイズ 1024 の行列積に対して,CUDA Thread 数を OMPCUDA の デフォルト値である 256 とした際の各実装の実行時間を示したグラフである.なお CUDA を用いた場合 (CUDA-loop3, CUDA-loop2, SimpleCUDA, UseSharedCUDA) の実行時間には CUDA を初期化するための時間は含まれておらず,CPU-GPU 間で のデータ通信時間は含まれている.CUDA の初期化には平均 900msec 程度,OM- PCUDA の初期化 (CUDA の初期化を含む) の初期化には 1600msec 程度の時間が必 要であることが確認できている. 4.3 OMPCUDA の評価 #define N 1024 f l o a t a [N∗N] , b [N∗N] , c [N∗N ] ; #pragma omp p a r a l l e l for p r i v a t e ( j , k ) f or ( i =0; i <N; i ++){ f o r ( j =0; j <N; j ++){ f l o a t tmp = 0 . 0 f ; fo r ( k=0; k<N; k++){ tmp += a [ i ∗N+k ] ∗ b [ k∗N+j ] ; } c [ i ∗N+j ] = tmp ; } } 図 46: 行列積のソースコード 1 (3 重ループ) #define N 1024 f l o a t a [N∗N] , b [N∗N] , c [N∗N ] ; #pragma omp p a r a l l e l for p r i v a t e ( j ) f or ( i =0; i <N∗N; i ++){ f l o a t tmp = 0 . 0 f ; f o r ( j =0; j <N; j ++){ tmp += a [ ( i /N) ∗N+j ] ∗ b [ j ∗N+( i%N ) ] ; } c [ i ] = tmp ; } 図 47: 行列積のソースコード 2 (2 重ループ) 113 4.3 OMPCUDA の評価 図 48: 行列積の実行時間 1 (問題サイズ 1024) 114 4.3 OMPCUDA の評価 115 結果を見ると,OMPCUDA は OMPCUDA-loop3 と OMPCUDA-loop2 で大きく 性能が異なっている.これは 3 重ループ (OMPCUDA-loop3) の場合には並列度が外側 ループのループ回数である 1024 であり,CUDA Thread 数が 256 のため CUDA Block 数が 1024/256=4 という低い並列度で実行されたのに対して,loop2 では並列度が 1024*1024,CUDA Thread 数が 256 のため CUDA Block 数は 1024*1024/256=4096 となり,高い並列度で実行されたことにより性能が向上したものと考えられる.ま た OmniCPU の実行時間を見ると,OmniCPU では CPU のコア数を超える数のス レッドを利用しても性能が向上しないのに対して,CUDA では物理的な演算器の数 が適切な並列度に直接対応していないことが確認できる. さらに CUDA-loop2 について,問題サイズを 1024 に保った状態で CUDA Thread 数と CUDA Block 数をいくつか変化させた際の実行時間を図 49 に示す.結果を見 ると,CUDA Thread 数は 256 または 512 のときに実行時間が短く,CUDA Block 数は多いほど良い性能が得られている.CUDA Block 単位での共有メモリである SharedMemory を用いていないため,並列度が性能を大きく左右するパラメタとなっ ていることがわかる. 以上の結果から,OMPCUDA は GPU の持つ高い並列性を活用したプログラムの 高速化を行えたと言える. 4.3.2 円周率の計算 (グレゴリ級数) を用いた性能確認 グレゴリ級数を用いた円周率の計算は,計算に必要なデータ量が少なく最後にリ ダクション演算が必要な以外は理想的な並列性を持つ,並列化による高速化が容易 な問題である.評価に用いたプログラムのソースコードを図 50 に示す.OMPCUDA のデフォルト設定では CUDA Thread 数を 256,CUDA Block 数を可能な限り大き くとることにしてあるため,この for ループは 1024*1024=1048576 個という非常に 多くの CUDA Block によって並列処理されることとなる.そのためリダクション演 算の実行時間が全体の実行時間に影響を及ぼす可能性があると考えられる. 評価では以下の実装についての性能比較を行った. 1. OMPCUDA : OMPCUDA を用いた実装 (図 50) 2. SimpleCUDA : OMPCUDA を用いず CUDA を直接利用した実装 4.3 OMPCUDA の評価 図 49: 行列積の実行時間 2 (問題サイズ 1024) f l o a t answer = 0 . 0 f ; int i , n = 0 x10000000 ; // 256∗1024∗1024=268435456=0 x10000000 #pragma omp p a r a l l e l for r e d u c t i o n (+: answer ) f or ( i = 0 ; i < n ; i ++){ answer += ( 4 . 0 / ( 4 ∗ i + 1 ) − 4 . 0 / ( 4 ∗ i + 3 ) ) ; } 図 50: 円周率計算のソースコード 116 4.3 OMPCUDA の評価 117 3. OmniCPU : Omni を用いたループ並列化 (図 50 を Omni でコンパイルしたも の,CPU 上で実行,1 スレッドから 8 スレッド) 4. CUDA-CPUreduction : SimpleCUDA に対して,リダクション演算の一部 (CUDA Block 間のリダクション演算) を CPU 側に移動した実装 5. CUDA-GLOBALreduction : SimpleCUDA に対して,全てのリダクション演 算を atomic 演算で行うようにした実装 評価 2 では評価 1 と異なり for ループ内部の計算において各 CUDA Thread が共通 に参照するデータはないため,SharedMemory を用いた実装との比較は意味をなさ ない.一方,前節で述べたようにリダクション演算が性能に影響を与える可能性が ある.特にデフォルトの CUDA Block 数・CUDA Thread 数では for ループのイタ レーション数が多いほど CUDA Block 数が多くなりリダクション演算が実行時間に 与える影響が大きくなると考えられる.そこで,SimpleCUDA のプログラムを書き 換え,CUDA Block 間のリダクション演算を CPU 側に移動したプログラム (CUDA- CPUreduction) と全てのリダクション演算を単純に atomic な加算命令で構成したプ ログラム (CUDA-GLOBALreduction) を作成し,性能を比較することにした. 各実装の実行時間を図 51 に示す.前項の行列積と同様,CUDA を用いた実装に ついては初期化の時間を含んでいない. グレゴリ級数は理想的な並列性を持つため,Omni ではスレッド数を 2,4 と増や すことで実行時間が 1/2,1/4 と短縮されており,同時実行可能なスレッド数を超え ると性能が頭打ちになっている.一方 OMPCUDA では,CPU と比べてコアクロッ クが低いにも関わらず実行時間が短くなっており,多数の演算器による並列処理の 効果が得られていることが見て取れる.OMPCUDA と SimpleCUDA を比較すると, この実験では OMPCUDA の生成するプログラムと SimpleCUDA の生成するプログ ラムは for ループの書き換えと OMPCUDA の初期化以外はほぼ同等のプログラム であり,実行時間の差として現れるのはループの書き換えによる時間のみである. OMPCUDA のスケジューリングは単純なスタティックスケジューリングであり複雑 な計算は行っていないため,実行時間に有意な差は見られなかった. 一方でリダクションの方法を変更した CUDA-CPUreduction では実行時間が 40%近 く短くなり,CUDA-GLOBALreduction は 100 倍以上長い実行時間となった.CUDA- 4.3 OMPCUDA の評価 図 51: 円周率の求解の実行時間 1 (問題サイズ 0x10000000) 118 4.3 OMPCUDA の評価 119 CPUreduction の実行時間内訳を確認したところ,CPU 上でのリダクション演算は 数ミリ秒で終了していることがわかった.OMPCUDA と比べて GPU から CPU へ転 送されるデータ量が増加してはいるものの,増加した容量はたかだか CUDA Block 数 (1024*1024) * float 変数の容量 (32bit) = 1MB であり,CPU-GPU 間の転送速度 が実測値 1GB/sec を超える今回の実験環境では実行時間に大きな影響を及ぼすと は考えにくい.そのため,CUDA-CPUreduction は GPU 上の CUDA Block 間での リダクションにかかる時間を大きく削減できたため実行時間が短く,また CUDA- GLOBALreduction では逆に GPU 上の CUDA Block 間でのリダクション時間が大 きくなったためにこのような結果が得られたと考えられる. ここで,OMPCUDA と CUDA-CPUreduction について CUDA Block 数と CUDA Thread 数を変更した場合の性能を図 52 に示す.OMPCUDA,CUDA-CPUreduction ともに CUDA Block 数・CUDA Thread 数が一定の範囲であれば性能に大きな差はな く,また行列積では OMPCUDA のデフォルト設定であるできる限り多くの CUDA Block・CUDA Thread を利用する割り当てが高い性能を得ていたのに対して,今回 の性能評価では CUDA Block 数を増やした場合に性能低下が見られている.この原 因として,CUDA が効率よくタスクスイッチ可能な CUDA Block 数を超えているこ とが考えられる. 図 53 は,OMPCUDA の実行時間を 1 とした場合の CUDA-CPUreduction の実行 時間比である.CUDA Block 数が少ない場合は実行時間にほとんど差がないものの, CUDA Block 数が多い場合には大きな実行時間の差が生じている.CUDA Block 数 が多く CUDA Thread 数が少ない場合に実行時間の差が生じていないように見える のは,計算時間が非常に長くリダクション演算の実行時間が表面化していないため である.なお,1CUDA Block あたりの CUDA Thread 数と CUDA Block 数の両方 が大きな場合の点がいくつか足りていないのは,CUDA Block 数*CUDA Thread 数 が問題サイズを超えており評価が意味をなさないためである. 以上から,対象問題の計算量やリダクション対象のデータ量によってはリダクショ ン演算を全て GPU 上で行うか一部を CPU で行うかによって性能に差が生じると考 えられる.ただし今回の問題設定では,OMPCUDA・CUDA-CPUreduction ともに CUDA Thread 数 256,CUDA Block 数 16384 の時に最も実行時間が短くなり,所要 時間はともに 285.5msec であった. 4.3 OMPCUDA の評価 図 52: 円周率の求解の実行時間 2 (問題サイズ 0x10000000) 120 4.3 OMPCUDA の評価 図 53: 円周率の求解の実行時間 3 (問題サイズ 0x10000000) 121 4.3 OMPCUDA の評価 122 今回の問題設定では,OMPCUDA デフォルトの CUDA Block 数・CUDA Thread 数設定よりも高い性能を得ることができる CUDA Block 数・CUDA Thread 数の設 定が存在した.常に最も高い性能を得られるようにするためには,デフォルトでよ り適した CUDA Block 数・CUDA Thread 数が選ばれるような仕組みが必要である. しかしながら評価 1 と同様に,OMPCUDA を用いることで GPU の持つ高い並列演 算性能を活用できることが確認できたと言える. 4.3.3 実装の手間や記述の容易性に関する評価 本項では行列積と円周率の求解の各プログラムについて,実装の手間や記述の容 易性についての定量的な評価を行う. 行列積を用いた性能評価で実装した各プログラムについて,プログラムの行数と GPU に関する知識の必要性および実行時間を表 4 に示す. 表 4: 行列積のプログラム行数と GPU に関する知識の必要性 実装 CPU 向け GPU 向け GPU に関する プログラム プログラム 知識の 実行時間 の行数 の行数 必要性 (msec) OMPCUDA-loop3 13 不要 800 OMPCUDA-loop2 11 不要 110 SimpleCUDA 80 行程度 5 要 90 UseSharedCUDA 80 行程度 20 要 24 OmniCPU-loop3 4 13 - - 7000 OmniCPU-loop2 4 11 - - 6900 AtlasCPU-nothread 1 - - 190 AtlasCPU-pthread - - 60 1 今回の実験において CUDA 向けの実装で最も高い性能が得られたのは Shared- Memory を用いた実装 UseSharedCUDA である.この実装はスレッド並列版の ATLAS (AtlasCPU-pthread) と比較しても実行時間が半分であり高い性能を得られてい 4.3 OMPCUDA の評価 123 る.一方で UseSharedCUDA プログラムの記述量を見てみると,GPU の制御に 80 行 程度および GPU 上で行う計算の記述に 20 行程度必要であり,さらに SharedMemory を用いた複数 CUDA Block・複数 CUDA Thread を用いる CUDA プログラミング手 法の習得が必要であるため,単純な 3 重ループ・2 重ループによる実装と比べると 明らかに実装の手間が大きいことがわかる. また同じく CUDA 向けだが SharedMemory を用いていない実装である Simple- CUDA と比較した場合,実行時間の面では OMPCUDA-loop2 が SimpleCUDA に 近い性能を得られている.OMPCUDA-loop2 と SimpleCUDA の実行時間の差は, OMPCUDA-loop2 が並列実行部で利用するデータを全て送受信しているのに対して SimpleCUDA では必要なデータのみを送受信していることと,OMPCUDA-loop2 で は並列実行部にループの書き換えのための計算が追加されていることによるもので ある.SimpleCUDA におけるプログラムの記述量については,GPU 上で行う計算 の記述は短い 1 重ループで記述できるものの,GPU の制御には UseSharedCUDA と 同様に 80 行程度必要であり,さらに複数 CUDA Block・複数 CUDA Thread を用い る CUDA プログラミング手法の習得が必要である. ATLAS を用いた実装は対象演算が関数として提供されているため,アプリケー ションプログラマが記述するソースコードの行数を比較する意味がない.ATLAS 自体は高度な職人芸によって作られており,一般のアプリケーションプログラマが ATLAS レベルの性能を持つプログラムを記述することは非常に困難である. 既存の CPU 向け OpenMP における適切な並列度はプログラムを実行する計算機 システムに搭載されている CPU の数 (コア数) によって決まる.一方 CUDA は CPU と比べて適切な並列度が大きいため,OMPCUDA では 3 重ループの OMPCUDA- loop3 と比べて 2 重ループの OMPCUDA-loop2 の方が明らかに性能が高かった.こ れは OMPCUDA を用いて GPU の性能を活用し高い性能を得るには,既存の CPU 向け OpenMP を用いる場合と比べてさらに並列性を得やすいようなプログラム記 述を行う必要があること,例えばこの実験で 3 重ループを 2 重ループに変更したよ うに,より高い並列度が得られるようなプログラム記述を行う必要があることを意 味する.この性能最適化指標は “並列度が高い記述を行った方が性能が出やすい” と いった単純な情報に変換できるため,大きな手間とはならないと考えられる. 行列積と同様に,円周率の求解を用いた性能評価で実装した各プログラムについ 4.3 OMPCUDA の評価 124 ても,プログラムの行数と GPU に関する知識の必要性および実行時間を表 5 に示す. 表 5: 円周率求解のプログラム行数と GPU に関する知識の必要性 実装 CPU 向け GPU 向け GPU に関する プログラム プログラム 知識の 実行時間 の行数 の行数 必要性 (msec) 不要 624 OMPCUDA 6 SimpleCUDA 80 行程度 5 + 60 † 要 620 OmniCPU 4 6 - - 2100 6 不要 375 GLOBALreduction 6 不要 130000 CUDACPUreduction CUDA- † 計算コアは 5 行だが,リダクション演算に 60 行程度必要. 今回用いた円周率の求解プログラムは極めて単純かつ高い並列性を持つな問題で あるため,リダクション演算以外に共有メモリを用いた並列高速化を行うべき場所 がない.そのため CUDA を直接用いた場合でも GPU の行う処理の記述は短いもの の,GPU を制御するための記述量は評価 1 と同様に 80 行程度必要であり,さらに 複数 CUDA Block・複数 CUDA Thread を用いる CUDA プログラミング手法の習得 も必要である. 以上から,行列積と円周率の求解のいずれの問題においても OMPCUDA を用い ることで,アーキテクチャを理解しなくてはならないうえに記述量が多く手間がか かる CUDA プログラミングを行うことなく,容易に高い性能が得られていることが わかる.そのため,OMPCUDA はアプリケーションプログラマに対する習得や実装 の手間と難しさを削減しつつ GPU の持つ高い演算性能を利用可能にしたと言える. 125 結論 5 5.1 研究成果の概要 本研究では,GPU の性能向上と普及が進むにともない GPU の性能を画像処理以 外の処理を含めた様々な用途に活用する GPGPU の普及が進み始めている一方で, さらに GPGPU が普及し広く活用されるには,アプリケーションプログラマにとっ ての習得や利用の手間と難しさが問題となっていることを指摘した.問題の原因と しては,GPU のアーキテクチャが既存の CPU とは大きく異なること,さらに既存 の GPGPU プログラミング環境は GPU のアーキテクチャと強く結びついているた め,GPGPU プログラミングのためには GPU のアーキテクチャや GPGPU 用のプ ログラミング環境について学習しまた手間のかかる GPGPU プログラムの実装を行 う必要があることを挙げた. 指摘した問題に対して本研究では,GPU が並列処理による高い演算性能を持つ ハードウェアであることから,現在 CPU 向けの並列化プログラミングに利用され ている汎用プログラミング環境が GPGPU プログラミングにも利用できればアプリ ケーションプログラマが GPGPU を容易に利用できると考えた.そこで,“並列計 算ライブラリ” と “並列化プログラミング環境” の 2 つのアプローチにより,アプリ ケーションプログラマに対して GPGPU を容易に利用可能とする機構の提案と実装 を行った. アプローチ 1 : 並列計算ライブラリ 第 1 のアプローチである “並列計算ライブラリ” では,計算カーネルのライブラリ 化はアプリケーションプログラマに対して詳細な実装方法や実行環境の差異を隠蔽 するのに効果があるものの,GPGPU においては GPU 上での実行に適さない問題 設定に関する課題や CPU-GPU 間での負荷分散に関する課題があるため,GPU を 用いた計算カーネルの実装を単純にライブラリとしてまとめただけでは高い性能が 得られない可能性があるという問題を指摘した. この問題に対して本アプローチでは,“CPU 向けのライブラリが持つ API と同様 の API を持ち,対象問題のデータ規模が小さい場合には CPU のみで演算を行い, 5.1 研究成果の概要 126 データ規模が大きい場合には CPU と GPU の性能バランスにあわせて CPU と GPU で問題分割・並列実行する機構を持つライブラリ” を提案した.また,提案に基づく ライブラリについてグラフィックス API とシェーダ言語を用いた実装を検討し,検 討に基づくライブラリの実装を行った. 実装の検討においては,CPU と GPU を用いて並列処理を行うための基本的な実 装方法を示した.OpenGL とマルチスレッドプログラミングを用いた実装における 性能低下の問題とその対策についても述べた.また CPU と GPU による適切な問題 分割を行うには実行環境に依存する性能チューニングが必要だが性能チューニング はアプリケーションプログラマにとって大きな手間となること,チューニングスク リプトと問題分割機構を実装・提供しチューニングを行う必要をなくすことでアプ リケーションプログラマの手間が削減できることを指摘した.さらに発展的な計算 機システム向けの検討として,複数の CPU や複数の GPU を搭載した計算機システ ム向けの実装についても検討を行った. アプローチに基づき,行列積和計算を対象としたライブラリ “GPUPC GEMM Library” を実装した.GPUPC GEMM Library は,実行環境に搭載されている CPU と GPU 両方の演算性能を活用して行列積和計算を行うライブラリである.対象問題 のデータ規模が小さい場合には CPU のみで演算を行い,問題サイズが大きく GPU による性能向上が望める場合にのみ CPU と GPU による問題分割・並列実行を行う ことで,CPU 向けのライブラリと同様の API を持ちながら GPU による性能向上を 得ることができる.さらに実行環境に依存する性能パラメタについては,自動的に 適切な値を求めることが可能なチューニングスクリプトと,スクリプトによって求 められた値を用いて問題分割・並列実行を行う問題分割機構を実装し,手間をかけ ずに常に高い性能が得られるようにした. また,テストプログラムやベンチマークプログラムを用いてプログラム作成の手 間と性能に関する評価を行った.性能については,HPL ベンチマークに対して CPU のみで HPL を実行したときに比べて最大 45.0% の性能向上を達成したことで本提 案が演算性能の面で有効性を持つことを確認した.また本ライブラリを利用するア プリケーションプログラマにとって,プログラムの変更を行うことなく GPU の持 つ高い並列演算性能を利用できることと,チューニングスクリプトと問題分割機構 によって実行対象である計算機システムに搭載されている CPU と GPU の性能バラ 5.1 研究成果の概要 127 ンスを気にすることなく GPU の持つ高い並列演算性能を利用できることから,本 提案がプログラム作成の手間の面で有効性を持つことを確認した. 以上から,“CPU 向けのライブラリと同様の API を持ち,対象問題のデータ規模 が小さい場合には CPU のみで演算を行い,データ規模が大きい場合には CPU と GPU の性能バランスにあわせて CPU と GPU で問題分割・並列実行する機構を持 つライブラリ” を提供することで,アプリケーションプログラマに対して GPU が持 つ演算性能の活用と利用の手間の削減の両方を達成できたことを示した. 本アプローチの発展的な課題としては以下の 2 点が挙げられる. 1. 様々なアプリケーションへの適用実験 本アプローチでは対象問題として行列積和計算のみを扱った.ライブラリの設 計においては行列積和計算やデータ並列アプリケーションに限定されない基礎 的な実装方法を示したものの,行列積和計算は CPU と GPU の性能バランス にあわせて容易に問題分割が行え性能が得やすい問題である.構造がより複雑 な対象問題では,CPU と GPU の性能バランスにあわせて容易に問題分割を 行えないなど,適切な問題分割を行うことが難しい可能性がある.そのため, 行列積和計算とは異なる種類のアプリケーション,例えばデータ並列性ではな く機能並列性を行う問題への適用や,反復計算が必要な問題への適用実験を行 う意義がある. なおこの課題に対しては,本アプローチに関する論文発表の後に東京工業大学 において FFT に対して問題分割・並列実行が行われ成果が得られている [106]. この研究では対象問題である FFT を機能分割し並列実行することで高い性能 を得ている.そのため,本アプローチが行列積和計算だけではなく様々な種 類のアプリケーションにも適用できる可能性の一端は既に示されていると言 える. 2. 複数の CPU・複数の GPU を搭載した計算機システムを対象とした性能チュー ニング 本アプローチにおける複数の CPU や複数の GPU に対応した実装では,CPU の処理をマルチスレッド並列化に対応したライブラリに任せており,また CPU と GPU の問題分割割合の最適化についても 1CPU+1GPU での性能に基づい 5.1 研究成果の概要 128 た単純な分割のみを行っている.本アプローチにおける評価では性能が同じコ アを 2 個搭載した CPU と性能が同じ 2 枚の GPU という環境を用いたために 単純なチューニングで容易に高い性能を得ることができたが,CPU や GPU を より多く搭載した計算機システムや,性能の異なるコアからなる CPU を搭載 した計算機システム,性能の異なる複数の GPU を搭載した計算機システムを 利用する場合には,並列処理のオーバヘッドを減らすために実装を工夫するこ とや,より適切な問題分割割合を求めるために性能のモデル化およびモデル化 に基づくチューニングアルゴリズムの考案などが必要になると考えられる. アプローチ 2 : 並列化プログラミング環境 第 2 のアプローチである “並列化プログラミング環境” では,GPU が並列処理に よる高い演算性能を持つハードウェアであることおよび CPU 向けの並列化プログ ラミングにおいてはいくつかの並列化プログラミング環境が普及し広く利用されて いることから,“既存の CPU 向け並列化プログラミング環境を用いた GPGPU プロ グラミング” を提案した. 本アプローチでは,既存の CPU 向け並列化プログラミング環境のいくつかを挙げ て,典型的な GPU のハードウェア構成,特に演算器やメモリの構成との対応付けを 検討した.ここでは,GPU 内部の演算器を用いて SIMD 演算を行うことや,GPU 上の共有メモリと演算器を OpenMP に関連づけて利用すること,GPU 上の演算器 間での通信や CPU-GPU 間の通信を通信ライブラリを用いて記述することなどを検 討した.さらに,GPGPU 環境の 1 つである CUDA を対象として既存の CPU 向け 並列化プログラミング環境との対応付けを検討した.ここでは演算器やメモリの対 応付けのみならず,実行モデルの対応付けや,対応付けの結果としてある程度高い 性能が得られそうであるかなど,より具体的な検討を行った. 対応付けを検討した結果,CUDA と OpenMP との対応付けを行うことでプログ ラミングの容易さと性能の両立が期待できると判断し,検討に基づいて CUDA 向け の OpenMP 処理系 “OMPCUDA” を実装した.OMPCUDA は,既存の CPU 向け OpenMP コンパイラである Omni OpenMP compiler を拡張して実装した “既存の CPU 向け OpenMP を用いて記述されたプログラムの並列実行部を GPU (CUDA) 上で実行可能とする処理系” である. 5.1 研究成果の概要 129 OMPCUDA は “プログラム変換機構” と “実行時ライブラリ” によって構成され る.プログラム変換機構は,Omni により OpenMP プラグマの解析および実行時ラ イブラリ関数呼び出しへの置き換えが行われた後の中間コードを対象としてプログ ラムの解析を行い,OpenMP プログラムの並列実行部を GPU 上で実行可能とする ための機構である.実行時ライブラリは GPU 上でのプログラム実行やスケジュー リングを行うための機構である. OMPCUDA の実装においては,OpenMP と CUDA がともに並列実行部を明示的 に指定する構造であることから,OpenMP 指示子で指定された並列実行部のみを GPU (CUDA) 上で実行可能にするという方針で実装した.プログラム変換機構は 並列実行部を GPU 上で実行できるようにプログラムを変換する際に,並列実行部 で参照するデータを確認し,自動的に送受信できるようにする機構を持つ.そのた めアプリケーションプログラマは既存の OpenMP プログラムと同様の記述のみを用 いて CUDA プログラムを作成することができる. さらに,テストプログラムを用いて OMPCUDA の性能と記述の容易性を評価し た.その結果 OMPCUDA は,アプリケーションプログラマに対して GPU (CUDA) に関する知識を必要としない GPGPU プログラミング環境を提供することが可能で あること,さらに OpenMP による性能向上が期待される典型的な問題であるループ の並列化に対して GPU の持つ高い並列性を活用した並列演算性能を得られること を確認した. 以上から,“既存の CPU 向け並列化プログラミング環境と同様の記述を用いて記 述されたプログラム (の並列実行部) を GPU 上で実行可能とする処理系” を提供す ることで,アプリケーションプログラマは GPU のアーキテクチャや GPU 用のプロ グラミング環境を習得するという大きな手間をかけることなく容易に GPGPU プロ グラミングを行えることおよび GPU の性能を容易に活用可能となることを示した. 本アプローチの発展的な課題としては以下の 2 点が挙げられる. 1. GPU 上のメモリの効率的な利用とループ並列化以外への対応 OMPCUDA を用いてより多くの OpenMP プログラムを GPU 上で容易にかつ 高速に実行可能とするためには,メモリ特性の利用やループ並列化以外への対 応などについてさらに検討・実装する必要がある. 5.1 研究成果の概要 130 CUDA の備えるメモリの特性を活用すればより高い性能を得られる可能性があ る.現在の OMPCUDA の実装では CUDA の共有メモリとして GlobalMemory のみを利用しているが,ShraedMemory や ConstantMemory などを利用可能 とすることでさらなる性能向上が行える可能性がある.例えば局所的に再利 用されるデータは SharedMemory に配置することや,書き込みが行われない データはキャッシュ効果が得られる ConstantMemory や TextureMemory に配 置することにより,さらなる性能向上が期待できる.そのためにはプログラム 変換機構を改良し,プログラムをより詳しく解析し GPU 上の各メモリとの適 切な対応付けを行えるようにする必要がある. また適切な対応付けを行うには CUDA プログラムの最適化に関する研究の成 果を取り入れることが重要であるが,CUDA は新しい GPGPU プログラミン グ環境でありプログラムの最適化に関する知見が十分に蓄積されているとは言 い難い.そのため,今後も CUDA プログラムの最適化に関する研究の動向を 注視し,その成果を OMPCUDA に取り入れていくことが必要であると言える. 現在の OMPCUDA はループの並列化のみを対象として実装されている.ルー プの並列化は OpenMP の典型的な対象問題であるため,ループの並列化のみ が対象であっても利用可能なアプリケーションは多いと考えられるが,他の指 示子を用いた並列化への対応を行うことでさらに多くのアプリケーションを容 易にかつ高速に実行可能となると考えられる.例えば sections 指示子に対して CUDA Block レベルでの並列性を割り当てることや,sections 指示子と for 指 示子による階層的な並列化に対しては sections 指示子を CUDA Block レベル での並列性に割り当てた上で for 指示子を CUDA Thread レベルでの並列性に 割り当てるといった割り当てを行うことが考えられる. 2. 様々なアプリケーションへの適用実験 本アプローチの評価では単純なテストプログラムを対象とした評価のみを行っ た.OMPCUDA が広く利用されるには,より様々なアプリケーションへの適 用実験を行い,性能評価や追加実装等を行う必要がある. OpenMP はアプリケーションプログラマが適切な並列化指示子を挿入するこ とを期待している.そのため実行タイミングによって正しい実行結果が得られ 5.1 研究成果の概要 131 るか否かが左右されるようなプログラムが入力された場合などは,アプリケー ションプログラマは正しくない実行結果が得られるまで記述ミスに気がつか ない.OMPCUDA を利用したプログラム実行においても,実行タイミングに よって正しい実行結果が得られるか否かが左右されるプログラムを作成した場 合には同様の状況が発生することが考えられる. しかし,GPU 上での実行と CPU 上での実行では異なるタイミングで実行さ れる可能性が高いため,同じ OpenMP プログラムを入力した場合でも,既存 の OpenMP 処理系と OMPCUDA では異なる傾向の正しくない実行結果が得 られることや,CPU のみまたは GPU のみでは常に正しい実行結果が得られる ことも考えられる.様々なアプリケーションに対して適用実験を行うことは, こうした問題が起きやすいプログラム記述のパターンを把握したり防止した りする上でも意味があると言える. まとめ 第 1 のアプローチは,並列化された計算カーネルを提供することでアプリケーショ ンプログラマに対して並列化プログラミング自体を隠蔽した.そのため,並列化に 関する知識を持たないアプリケーションプログラマでも,GPU の演算性能を有効に 利用することができる. また第 2 のアプローチは,既存の CPU 向け並列化プログラミング環境を用いて GPU 向けのプログラムを記述可能な並列化プログラミング環境の提供を行った.そ のため,GPU に関する知識を持たないアプリケーションプログラマでも,GPU の 演算性能を有効に利用することができる. 以上の 2 つのアプローチにより汎用プログラミング環境を用いて GPGPU を利用 可能とすることで,GPU のアーキテクチャや GPGPU 用の新たなプログラミング環 境を習得する手間や,GPU を制御するための記述の手間といった,アプリケーショ ンプログラマにとっての手間を削減し,GPGPU を容易に利用可能とした. 本研究の貢献は,GPGPU を多くのアプリケーションプログラマが容易に活用で きるようにするアプローチを提案し,提案に基づいてライブラリや処理系の実装を 行い有効性を実証した点にある.この成果は,今後さらに普及が広がると考えられ 5.2 今後の課題 132 る GPU を搭載した計算機システムにおけるアプリケーションプログラマにとって 使いやすい利用環境のあり方を示すものとして意義がある. 5.2 今後の課題 本研究によって明らかとなった今後の課題は以下の 2 点である. 第 1 の課題は,OMPCUDA の実装によって明らかになった,汎用プログラミング 環境を用いた GPGPU の限界に関するものである. アプローチ 2 では既存の CPU 向け並列化プログラミング環境を用いた GPGPU プログラミングについて検討を行い,GPGPU に適した既存の並列化プログラミン グ環境として OpenMP を選択し,CUDA と対応づけて高い演算性能を達成した.本 研究はアプリケーションプログラマにとっての習得や実装の手間を削減することを 重視した研究であるため,OpenMP に対する新たな指示子の追加等は行わないとい う方針で対応付けや実装を行った. 一方で,利用の手間や難しさが削減されることよりも高い性能が得られることを 重視するユーザ,高い性能が得られるのであれば習得や利用の手間と難しさが増加 してもかまわないというアプリケーションプログラマもいるものと考えられる. 例えば OMPCUDA の性能を向上させるための方法として以下のような 2 つの手 法が考えられる. 1. OpenMP と CUDA の対応付けについては GlobalMemory を共有メモリと見 なして GPU 上の全 SP (CUDA Thread) が並列処理を行うものとしたため, 高速な CUDA プログラムを作成する上で効果の大きな SharedMemory の活用 が行えていない.GlobalMemory と SharedMemory に (さらに可能であれば ConstantMemory や TextureMemory にも) 適切にデータを割り当てることが できれば,より高い性能を得ることができる可能性がある. 2. 現在の OMPCUDA は,OpenMP の並列実行部を GPU で実行するという OpenMP と CUDA との対応付けを行っている.しかし,アプローチ 1 において CPU と GPU による並列処理を行うことで CPU と GPU の性能を活用しさらに高い演 算性能を得られることを示したように,GPU による並列処理は問題のデータ 5.2 今後の課題 133 規模等によっては CPU よりも良い性能が得られないことがあり,また CPU と GPU による問題分割を行うことでさらに高い演算性能を得られることが期 待できる.そのためマルチコア CPU と GPU を搭載したような計算機システ ムにおいては,並列実行部ごとに CPU で実行するか GPU で実行するかを切 り替えることでより高い性能が得られる可能性があり,さらに 1 つの並列実行 部を CPU と GPU で分割して実行すればさらに高い性能が得られると考えら れる. これらの手法を実現するには,プログラム変換機構を改良し,OMPCUDA が GPU 上の複数種類のメモリをさらに有効に活用したり,CPU と GPU による問題分割・ 並列実行などを行えるようにする必要がある.一方で,OpenMP は単一の共有メモ リを持つ計算機システムにおいて利用されることを想定して仕様が決められており, また CUDA では CPU と GPU のメモリ空間が独立しているうえに任意のタイミン グで CPU-GPU 間のデータ送受信を行うことができない.そのため既存の OpenMP の指示子では,アプリケーションプログラマがプログラム変換機構が上記のような メモリの活用や問題分割・並列実行を含むプログラム変換を行うのに十分な情報を 記述できない可能性がある. このように,既存の汎用プログラミング環境は CPU を対象として提案・実装さ れてきたものであるため GPGPU に利用する場合にはどうしても適用できない・非 常に適用しにくいという問題が生じる可能性がある.これらの問題を解決して GPU を搭載した計算機システムの性能をさらに活用するためには,既存の汎用プログラ ミング環境に対してある程度の仕様変更や仕様追加を行わなくてはならない可能性 が考えられる. そのため,今後さらに高い性能への要求が高まった場合には,“既存の指示文の みでも正しく (GPU 上で並列に) 動作し,新たな指示文を用いるとさらに (CPU と GPU による問題分割を行い) 性能が向上する” など,既存の CPU 向け並列化プログ ラミング環境に対してアプリケーションプログラマにとっての習得の手間を大きく 増加させることなく GPU の性能を活用しやすいようにするにはどのような変更を 加えていくべきかが課題となると考えられる. 第 2 の課題は,GPU 以外の SIMD 型アクセラレータや OpenCL との比較である. Cell 向けの OpenMP 環境が開発されていることを 2 章で述べたが,CPU・Cell・ 5.2 今後の課題 134 GPU はそれぞれ異なる特徴を持つハードウェアであるため,同じ OpenMP を用い たプログラミングでも性能最適化のためのチューニング方法等が異なる可能性があ る.これらを比較することで,アプリケーションプログラマにとってさらに利用し やすく高い性能が得られる GPGPU 環境を提供できるようになることや,GPU だ けではなく他の SIMD 型アクセラレータも含めてアプリケーションプログラマに利 用しやすく高い性能が得られるプログラミング環境の提供につながるものと考えら れる. また OpenCL が普及し様々なハードウェア上で同じプログラムが利用できるよう になった際には,OpenCL さえ習得すれば汎用性の高いプログラムが記述できるよ うになりアプリケーションプログラマにとっての習得や利用の手間が削減されること が考えられる.一方で OpenCL そのものの習得や利用の手間が生じるため,OpenCL を用いてアプリケーションプログラマが 1 からプログラムを記述した場合と本研究 の各アプローチを用いた場合とで手間や性能にどのような差が生じるかを比較する ことや,OpenCL 上に既存の CPU 向け並列化プログラミング環境を実装すること で,さらにアプリケーションプログラマにとって利用しやすく高い性能が得られる プログラミング環境の提供につながるものと考えられる. 謝辞 135 謝辞 本研究を進めるにあたり,あたたかいご指導ご鞭撻を頂きました並列処理学講座 (現在高性能コンピューティング学講座) 本多弘樹教授に心から感謝の意を表します. 電気通信大学 弓場敏嗣名誉教授,電気通信大学 近藤正章准教授,東京大学 片桐 孝洋准教授,東京工業大学 吉瀬謙二講師,電気通信大学 平澤将一助教には,研究 内容についてのご助言のみならず,研究の進め方や研究者としての物事の見方・考 え方についても多くのご助言を頂きました.心からお礼申し上げます. 本研究の一部は独立行政法人 科学技術振興機構 (JST) 戦略的創造研究推進事業 (CREST) の支援を受けて行いました.日頃からご助言を頂いた本事業グループの 方々に感謝いたします. 本研究の一部は独立行政法人 情報処理推進機構 (IPA) 主催の未踏ソフトウェア創 造事業 (未踏ユース) の支援を受けて行いました.また,未踏ユースの関係者および 開発者の皆様には研究に対するご助言を頂いたのみならず,ソフトウェア開発者と しての情熱や心構えを学ばせていただきました.心から感謝いたします. GPGPU の研究を行うきっかけの一部となった,そして学生生活を支えてくれた 電気通信大学 X680x0 同好会の皆様に感謝いたします. 最後に,研究に関する議論や学生生活を支えて頂いた石原誠氏,田邊浩志氏,渡 邊啓正氏,ほか並列処理学講座・高性能コンピューティング学講座の皆様に感謝い たします. 参考文献 136 参考文献 [1] 佐久間弘文. 地球シミュレータ:2. 地球シミュレータの応用 2.1 大気・海洋の シミュレーション. 情報処理学会会誌, Vol. 45, No. 2, pp. 130–133, 2004. [2] 斎藤稔. 地球シミュレータによる蛋白質の大規模シミュレーション:ベクトル 化と並列化による加速性能. 情報処理学会論文誌 コンピューティングシステ ム, Vol. 46, No. SIG7(ACS10), pp. 9–17, 2005. [3] 朴泰祐, 佐藤三久, 宇川彰. 計算科学のための超並列クラスタ PACS-CS の概要 . 情報処理学会 研究報告 (HPC-103), pp. 133–138, 2005. [4] 谷啓二, 横川三津夫. 地球シミュレータ計画:<前編>地球(ガイア)との共 生の指針を求めて. 情報処理学会会誌, Vol. 41, No. 3, pp. 249–254, 2000. [5] 松岡聡. TSUBAME の飛翔: ペタスケールへ向けた「みんなのスパコン」の構 築. 情報処理学会 研究報告 (HPC-107), pp. 37–42, 2006. [6] Hiroshi Nakashima. T2K Open Supercomputer: Inter-university and Interdisciplinary Collaboration on the New Generation Supercomputer. Informatics Research for Development of Knowledge Society Infrastructure, International Conference on, Vol. 0, pp. 137–142, 2008. [7] 独 立 行 政 法 人 理 化 学 研 究 所. 立 地 地 点 を 神 戸 に 決 定. 次 世 代 ス ー パ ー コ ン ピュー タ 施 設 の プ レ ス リ リ ー ス, http://www.riken.go.jp/r- world/info/release/press/2007/070328/index.html, March 2007. [8] A. Gara, M. A. Blumrich, D. Chen, G. L.-T. Chiu, P. Coteus, M. E. Giampapa, R. A. Haring, P. Heidelberger, D. Hoenicke, G. V. Kopcsay, T. A. Liebsch, M. Ohmacht, B. D. Steinmacher-Burow, T. Takken, and P. Vranas. Overview of the Blue Gene/L system architecture. IBM Journal of Research and Development, pp. 195–212, 2005. [9] Intel. Intel(R) Pentium(R) 4 Processor 6xx Sequence and Intel(R) Pentium(R) 4 Processor Extreme Edition Datasheet, 2005. 参考文献 137 [10] IBM. IBM Unleashes World’s Fastest UNIX System, Offers Twice the Performance of HP Itanium System at Comparable Price. Press release, http://www03.ibm.com/press/us/en/pressrelease/23843.wss, April 2008. [11] Stephen L. Smith. Intel Roadmap Overview. Intel Developer Forum’s presentation, 2008. [12] Randy Allen. AMD Financial Analyst Day. AMD Financial Analyst Day’s presentation, 2008. [13] NVIDIA. the NVIDIA world’s first Tesla teraflop Computing parallel Solutions processor. now Press with release, http://www.nvidia.com/object/io 1213744368983.html, June 2008. [14] AMD. aflop AMD Barrier. Stream Processor Press release, First to Break 1 Ter- http://www.amd.com/us- en/Corporate/VirtualPressRoom/0,,51 104 543 15104˜126593,00.html, June 2008. [15] John D. Owens, David Luebke, Naga Govindaraju, Mark Harris, Jens Krüger, Aaron E. Lefohn, and Timothy J. Purcell. A Survey of General-Purpose Computation on Graphics Hardware. In Eurographics 2005, State of the Art Reports, pp. 21–51, August 2005. [16] gpgpu.org. General-Purpose computation on GPUs(GPGPU) website, http://gpgpu.org/. [17] Dinesh Manocha. General-Purpose Computations using Graphics Processors. In Computer, Vol.38, Num.8, pp. 85–88. IEEE Computer Society, 2005. [18] David Geer. Taking the Graphics Processor beyond Graphics. In Computer, Vol.38, Num.9, pp. 14–16. IEEE Computer Society, 2005. [19] T.Amada, M.Imura, Y.Yasumuro, Y.Manabe, and K.Chihara. Particle-Based Fluid Simulation on GPU. In ACM Workshop on General-Purpose Computing on Graphics Processors(Poster session), 2004. 参考文献 138 [20] E.Scott Larsen and David McAllister. Fast matrix multiplies using graphics hardware. In Proceedings of the 2001 ACM/IEEE conference on Supercomputing, p. CDROM, 2001. [21] 松井学, 伊野文彦, 萩原兼一. プログラマブル GPU における LU 分解の設計と 実装. 先進的計算基盤システムシンポジウム SACSIS2005, pp. 359–367, 2005. [22] Nico Galoppo, Naga K. Govindaraju, Michael Henson, and Dinesh Manocha. LU-GPU: Efficient Algorithms for Solving Dense Linear Systems on Graphics Hardware. In Proceedings of the ACM/IEEE SC—05 Conference, p. 3, 2005. [23] 小松原誠, 森眞一郎, 中島康彦, 富田眞治. 汎用グラフィクスカードを用いた格子 ボルツマン法による流体シミュレーション. 情報処理学会 研究報告 (ARC-163), pp. 37–42, 2005. [24] 森眞一郎, 五島正裕, 中島康彦, 富田眞治. 並列ベクトルプロセッサとしてのグ ラフィクスプロセッサ. 情報処理学会関西支部大会, pp. 179–182, 2004. [25] 丸山悠樹, 中田智史, 高山征大, 篠本雄樹, 五島正裕, 森眞一郎, 中島康彦, 富田 眞治. 汎用グラフィクスカードを用いた並列ボリュームレンダリングシステム . 情報処理学会論文誌, Vol.45, No.SIG11, ACS7, pp. 415–424, 2004. [26] 篠本雄基, 三輪忍, 嶋田創, 森眞一郎, 中島康彦, 富田眞治. 並列ボリュームレ ンダリングにおける投機的描画に関する考察. 情報処理学会 研究報告, 2005- ARC-164, pp. 145–150, 2005. [27] Mark Joselli, Esteban Clua, Anselmo Montenegro, Aura Conci, and Paulo Pagliosa. A new physics engine with automatic process distribution between cpu-gpu. In Sandbox ’08: Proceedings of the 2008 ACM SIGGRAPH symposium on Video games, pp. 149–156, 2008. [28] Mark Harris. Gpu physics. In SIGGRAPH ’07: ACM SIGGRAPH 2007 courses, p. 15, 2007. 参考文献 139 [29] K. Moreland and E. Angel. The FFT on a GPU. In Proc. SIGGRAPH/EUROGRAPHICS Workshop Graphics Hardware, pp. 112–119, 2003. [30] 額田彰, 尾形泰彦, 遠藤敏夫, 松岡聡. CUDA 環境における高性能 3 次元 FFT. 情報処理学会論文誌 コンピューティングシステム, Vol. 1, No. 2, pp. 231–239, 2008. [31] Chris J. Thompson, Sahngyun Hahn, and Mark Oskin. Using Modern Graphics Architectures for General-Purpose Computing: A Framework and Analysis. In Proceedings of the 35th annual ACM/IEEE International Symposium on Microarchitecture, pp. 306–317, 2002. [32] Jens Krüger and Rüdiger Westermann. Linear Algebra Operators for GPU Implementation of Numerical Algorithms. In Proceedings of ACM SIGGRAPH 2003, pp. 908–916, 2003. [33] Nolan Goodnight and Cliff Woolley and Gregory Lewin and David Luebke andGreg Humphreys. A multigrid solver for boundary value problems using programmable graphics hardware. In Proceedings of the ACM SIGGRAPH/EUROGRAPHICS conference on Graphics hardware, pp. 102–111, 2003. [34] Ádám Moravánszky. Dense Matrix Algebra on the GPU. In Wolfgang F. Engel, editor, ShaderX2: Shader Programiing Tips & Tricks With DirectX 9, pp. 352–380. Wordware, 2003. [35] Jeff Bolz, Ian Farmer, Eitan Grinspun, and Peter Scheróder. Sparse Matrix Solvers on the GPU: Conjugate Gradients and Multigrid. In Proceedings of ACM SIGGRAPH 2003, pp. 917–924, 2003. [36] Wesley De Neve, Dieter Van Rijsselbergen, Charles Hollemeersch, Jan De Cock, Stijn Notebaert, and Rik Van de Walle. GPU-assisted decoding of video samples represented in the YCoCg-R color space. In MULTIMEDIA ’05: Proceedings of the 13th annual ACM international conference on Multimedia, pp. 447–450, 2005. 参考文献 140 [37] 今給黎 隆. DirectX 9 シェーダプログラミングブック. 毎日コミュニケーショ ンズ, 2004. [38] OpenGL Architecture Review Board, Dave Shreiner, Mason Woo, Jackie Neider, and Tom Davis. OpenGL Programming Guide: The Official Guide to Learning OpenGL, Version 2.1 (OpenGL). Addison-Wesley, 2007. [39] Randima Fernando and Mark J. Kilgard. The Cg Tutorial: The Definitive Guide to Programmable Real-Time Graphics. Addison-Wesley, 2003. [40] NVIDIA. NVIDIA CUDA Compute Unified Device Archtecture Programming Guide version 2.0, 2008. [41] AMD. ATI CTM Guide Version 1.01, 2006. [42] AMD. Stream Computing User Guide rev1.3.0, 2008. [43] Dr James Irwin and Mr Simon McIntosh-Smith. Delivering aggregated performance for high performance math libraries in accelerated systems. In Inernational Supercomputing Conference ISC’07, 2007. [44] IBM. Cell Broadband Engine resource center website, http://www- 128.ibm.com/developerworks/power/cell/. [45] Intel. Intel(R) Xeon(R) Processor 5400 Series, Boost Performance and Energy Efficiency with New 45nm Multi-core Intel(R) Xeon(R) Processors, 2008. [46] NVIDIA. Technical Brief, NVIDIA GeForce(R) GTX 200 GPU Architectural Overview, Second-Generation Unified GPU Architecture for Visual Computing, 2008. [47] ClearSpeed.inc. CLEARSPEED ADVANCE(TM) e720 ACCELERATOR. PRODUCT BRIEF, 2008. [48] Fixstars. Gigaaccel 180 製品カタログ, 2008. 参考文献 141 [49] ClearSpeed.inc. CLEARSPEED WHITEPAPER: CSX PROCESSOR ARCHITECTURE. White Papers, 2007. [50] ClearSpeed.inc. CLEARSPEED CSX700 PROCESSOR. PRODUCT BRIEF, 2008. [51] ClearSpeed.inc. Cn Standard Library Reference Files for 3.1, 2008. [52] IBM. tional IBM-Built Lab No.1 Supercomputer in TOP500. at NNSA’s Press Los release, Alamos Na- http://www- 03.ibm.com/press/us/en/pressrelease/24480.wss, June 2008. [53] TOSHIBA. SE1000 Toshiba starts high-performance sample stream shipping processor. of SpursEngine(TM) Press release, http://www.toshiba.co.jp/about/press/2008 04/pr0801.htm, April 2008. [54] Alexandre E. Eichenberger, KathrynO ’Brien, KevinO ’Brien, Peng Wu, Tong Chen, Peter H. Oden, Daniel A. Prener, Janice C. Shepherd, Byoungro So, Zehra Sura, Amy Wang, Tao Zhang, Peng Zhao, Michael Gschwind. Optimizing Compiler for the CELL Processor. In Parallel Architectures and Compilation Techniques, 2005. PACT 2005. 14th International Conference on, pp. 17–21, 2005. [55] Rosa M. Badia Josep M. Perez, Pieter Bellens and Jesus Labarta. CellSs: Programming the Cell/B.E. made easier. IBM Journal of R&D, Vol. 51, No. 5, 2007. [56] 町田智志, 中西悠, 平澤将一, 本多弘樹. POSIX スレッドを用いた Cell プロ セッサ向け API の提案. 情報処理学会 研究報告 (ARC-175), pp. 71–76, 2007. [57] Ian Buck, Tim Foley, Daniel Horn, Jeremy Sugerman, Kayvon Fatahalian, Mike Houston, and Pat Hanrahan. Brook for GPUs: Stream Computing on Graphics Hardware. SIGGRAPH 2004, 2004. [58] AMD. Brook+. SC07 BOF Session presentation, November 2007. 参考文献 142 [59] Michael D. McCool. Data-Parallel Programming on the Cell BE and the GPU using the RapidMind Development Platform. In GSPx Multicore Applications Conference, 2006. [60] Michael McCool and Stefanus Du Toit. Metaprogramming GPUs with Sh. A K Peters Ltd, 2004. [61] 滝沢寛之, 白取寛貴, 佐藤功人, 小林広明. SPRAT:実行時自動チューニング機 能を備えるストリーム処理記述用言語. 情報処理学会論文誌 コンピューティ ングシステム, Vol. 1, No. 2, pp. 207–220, 2008. [62] Khronos OpenCL Working Group. the OpenCL Specification Version: 1.0, 2009. [63] 宮田一乗, 高橋誠史, 黒田篤. GPU コンピューティングの動向と将来像. 芸術 科学会論文誌, pp. 13–19, 2005. [64] 高橋誠史, 宮田一乗, 白井暁彦. EasyGPU : GPU を用いたコンピュータビジョ ン実験環境の開発 (メディア表現の創出を支えるハードウェア・プラットフォー ム技術). 情報処理学会 研究報告 (CG-120), pp. 19–24, 2005. [65] James Fung and Steve Mann. Openvidia: parallel gpu computer vision. In MULTIMEDIA ’05: Proceedings of the 13th annual ACM international conference on Multimedia, pp. 849–852, 2005. [66] J.P. Farrugia, P. Horain, E. Guehenneux, and Y. Allusse. GPUCV: A framework for image processing acceleration with graphics processors. CDROM proc.of the IEEE International Conference on Multimedia & Expo (ICME 2006), p. CDROM, 2006. [67] Philippe Charles, Christian Grothoff, Vijay Saraswat, Christopher Donawa, Allan Kielstra, Kemal Ebcioglu, Christoph von Praun, and Vivek Sarkar. X10: an object-oriented approach to non-uniform cluster computing. In OOPSLA ’05: Proceedings of the 20th annual ACM SIGPLAN conference on Object oriented programming, systems, languages, and applications, pp. 519–538, 2005. 参考文献 143 [68] David Callahan, Bradford L. Chamberlain, and Hans P. Zima. The cascade high productivity language. In In 9th International Workshop on High-Level Parallel Programming Models and Supportive Environments (HIPS 2004), pp. 52–60, April 2004. [69] Eric Allen, David Chase, Christine Flood, Victor Luchangco, Jan-Willem Maessen, Sukyoung Ryu, and Guy L. Steele Jr. Project fortress: A multicore language for multicore processors. Linux Magazine, September 2007, 2007. [70] W Carlson, J.M Draper, D.E Culler, K Yelick, E Brooks, and K Warren. Introduction to UPC and Language Specification, 1999. [71] 妹尾義樹. HPF 言語の動向:HPF 言語の現状と将来. 情報処理学会会誌, Vol. 38, No. 2, pp. 90–99, 1997. [72] Robert W. Numrich and John Reid. Co-array Fortran for parallel programming. SIGPLAN Fortran Forum, Vol. 17, No. 2, pp. 1–31, 1998. [73] 李珍泌, 佐藤三久, 朴泰祐. 分散メモリ向けデータ並列言語 OpenMPD の設計 と実装. 情報処理学会 研究報告 (ARC-172/HPC-109), pp. 49–54, 2007. [74] 岩崎英哉, 胡振江. マルチコアを活かすお手軽並列プログラミング:4. 並列計算 パターン (スケルトン) による並列プログラミング. 情報処理学会会誌, Vol. 49, No. 12, pp. 1385–1394, 2008. [75] Kiminori Matsuzaki and Hideya Iwasaki and Kento Emoto and Zhenjiang Hu. A library of constructive skeletons for sequential style of parallel programming. In InfoScale ’06: Proceedings of the 1st international conference on Scalable information systems, p. 13, 2006. [76] 金井達徳, 瀬川淳一, 武田奈穂美. 組み込みプロセッサのメモリアーキテクチャ に依存しない画像処理プログラムの記述と実行方式. 情報処理学会論文誌 コ ンピューティングシステム, Vol. 48, No. SIG13(ACS 19), pp. 287–301, 2007. 参考文献 144 [77] R. Clint Whaley, Antoine Petitet, and Jack J. Dongarra. Automated Empirical Optimization of Software and the ATLAS Project. Parallel Computing, Vol. 27, No. 1–2, pp. 3–35, 2001. [78] 片桐孝洋. ソフトウエア自動チューニング―数値計算ソフトウエアへの適用と その可能性. 慧文社, 2004. [79] NVIDIA. Performance Tools & SLI Programming. Iron Developer 2005 Presentations, 2005. [80] Jon Story. Harnessing the Performance of CrossFireX(TM) (August 2008). Radeon SDK Samples & Documents, 2008. [81] Nicholas J. Higham. Exploiting Fast Matrix Multiplication Within the Level 3 BLAS. ACM Transactions on Mathematical Software, Vol. 16, No. 4, pp. 352–368, 1990. [82] C. L. Lawson, R. J. Hanson, D. Kincaid, and F. T. Krogh. Basic Linear Algebra Subprograms for FORTRAN usage. ACM Trans. Math. Soft., Vol. 5, No. 3, pp. 308–323, 1979. [83] TOP500. TOP500 website, http://www.top500.org/. [84] HPL. pack A Portable Implementation of the High-Performance LinBenchmark for Distributed-Memory Computers website, http://www.netlib.org/benchmark/hpl/. [85] Kazushige Goto. Goto BLAS website, http://www.tacc.utexas.edu/resources/software/. [86] K.Fatahalian, J.Sugerman, and P.Hanrahan. Understanding the Efficiency of GPU Algorithms for Matrix-Matrix Multiplication. In Graphics Hardware 2004, pp. 133–137, 2004. 参考文献 145 [87] Jesse D. Hall, Nathan A. Carr, and John C. Hart. Cache and Bandwidth Aware Matrix Multiplication on the GPU. Technical report, University of Illinois Dept. of Computer Science, 2003. [88] Changhao Jiang and Marc Snir. Automatic Tuning Matrix Multiplication Performance on Graphics Hardware. In Proceedings of the 14th International Conference on Parallel Architectures and Compilation Techniques (PACT’05), pp. 185–196, 2005. [89] 笹生健, 松岡聡. HPL のパラメータチューニングの解析. 情報処理学会 研究報 告 (HPC-091), pp. 125–130, 2002. [90] Erik Lindholm, John Nickolls, Stuart Oberman, and John Montrym. NVIDIA Tesla: A Unified Graphics and Computing Architecture. IEEE MICRO 2008, Vol.28, Issue.2, 2008. [91] AMD. AMD Tech Day UK: ATI Radeon(TM) HD 2000 SeriesTechnology Overview, 2007. [92] Aart J. C. Bik and Milind Girkar and Paul M. Grey and Xinmin Tian. Automatic intra-register vectorization for the Intel architecture. In International Journal of Parallel Programming, Vol. 30, pp. 65–98, 2002. [93] 中西悠, 渡邊啓正, 平澤将一, 本多弘樹. コードの性能可搬性を提供する SIMD 向け共通記述方式. 情報処理学会論文誌 コンピューティングシステム, Vol. 48, No. SIG13(ACS 19), pp. 95–105, 2007. [94] Intel. Intel C++ Compiler website, http://www.intel.com/cd/software/ products/asmo-na/eng/compilers/index.htm. [95] Apple. Velocity Engine website, http://developer.apple.com/hardwaredrivers/ve/. [96] C. Amza, A.L. Cox, S. Dwarkadas, P. Keleher, H. Lu, R. Rajamony, W. Yu, and W. Zwaenepoel. TreadMarks: Shared Memory Computing on Networks of Workstations. IEEE Computer, Vol. 29, No. 2, pp. 18–28, 1996. 参考文献 146 [97] 吉瀬謙二, 田邊浩志, 多忠行, 片桐孝洋, 本多弘樹, 弓場敏嗣. S-DSM システム におけるページ要求時の受信通知を削減する方式. 情報処理学会論文誌 コン ピューティングシステム, Vol. 46, No. SIG12(ACS 11), pp. 170–180, 2005. [98] OpenMP.org. OpenMP : Simple, Portable, Scalable SMP Programming website, http://www.openmp.org/. [99] Greg Burns, Raja Daoud, and James Vaigl. LAM: An Open Cluster Environment for MPI. In Proceedings of Supercomputing Symposium, pp. 379–386, 1994. [100] Jeffrey M. Squyres and Andrew Lumsdaine. A Component Architecture for LAM/MPI. In Proceedings, 10th European PVM/MPI Users’ Group Meeting, No. 2840 in Lecture Notes in Computer Science, pp. 379–387, Venice, Italy, September / October 2003. Springer-Verlag. [101] Vishal Aslot, Max Domeika, Rudolf Eigenmann, Greg Gaertner, Wesley B. Jones, and Bodo Parady. SPEComp: A New Benchmark Suite for Measuring Parallel Computer Performance. In WOMPAT 2001 Workshop on OpenMP Applications and Tools, pp. 1–10, 2001. [102] M.Sato, S.Satoh, K.Kusano, and Y.Tanaka. Design of OpenMP Compiler for an SMP Cluster. In EWOMP ’99, pp. 32–39, 1999. [103] Daniel Horn. Stream Reduction Operations for GPGPU Applications. In GPU Gems2, chapter 36. Addison-Wesley, 2005. [104] David Roger, Ulf Assarsson, and Nicolas Holzschuch. Efficient Stream Reduction on the GPU. In Workshop on General Purpose Processing on Graphics Processing Units, oct 2007. [105] John Owens and UC Davis. Data-parallel algorithms and data structures. In SUPERCOMPUTING 2007 Tutorial: Hight Performance Computing with CUDA, 2007. 参考文献 147 [106] 尾形泰彦, 遠藤敏夫, 丸山直也, 松岡聡. 性能モデルに基づく CPU 及び GPU を 併用する効率的な FFT ライブラリ. 情報処理学会論文誌 コンピューティング システム, Vol. 1, No. 1, pp. 40–50, 2008. A 付録 1: CUDA を用いた実装のソースコード 148 A 付録 1: CUDA を用いた実装のソースコード アプローチ 2 での評価 (4.3 節) に用いた SimpleCUDA プログラム (行列積) のソー スコードのうち,CUDA の初期化などを除外した主な部分を以下に示す. // GPU 向けプログラム (関数宣言を除いて 5 行) extern "C" __global__ void mm_reference (float data_c[N*N], float data_a[N*N], float data_b[N*N]){ int i; float tmp = 0.0f; for(i=0; i<N; i++){ tmp += data_a[N*blockIdx.x + i] * data_b[N*i + threadIdx.x]; } data_c[blockDim.x*blockIdx.x+threadIdx.x] = tmp; } // CPU 向けプログラム ここに示した主な部分は // コメントを除いて 16 行,初期化等を含めると合計 80 行程度 CU_SAFE_CALL(cuFuncSetBlockShape( func1, _THREADSx, _THREADSy, 1 )); CU_SAFE_CALL(cuFuncSetSharedSize( func1, sizeof(float)*_THREADSxy )); CUdeviceptr d_data_c; CU_SAFE_CALL(cuMemAlloc(&d_data_c, sizeof(float)*N*N)); CU_SAFE_CALL(cuParamSeti(func1, 0, d_data_c)); CUdeviceptr d_data_a; CU_SAFE_CALL(cuMemAlloc(&d_data_a, sizeof(float)*N*N)); // 次の行が CPU から GPU に対する行列 A の送信 CU_SAFE_CALL(cuMemcpyHtoD(d_data_a, data_a, sizeof(float)*N*N)); CU_SAFE_CALL(cuParamSeti(func1, 4, d_data_a)); CUdeviceptr d_data_b; CU_SAFE_CALL(cuMemAlloc(&d_data_b, sizeof(float)*N*N)); // 次の行が CPU から GPU に対する行列 B の送信 CU_SAFE_CALL(cuMemcpyHtoD(d_data_b, data_b, sizeof(float)*N*N)); CU_SAFE_CALL(cuParamSeti(func1, 8, d_data_b)); CU_SAFE_CALL(cuParamSetSize(func1, 12)); // 次の行が GPU に対する実行開始指示 CU_SAFE_CALL(cuLaunchGrid(func1, _BLOCKSx, _BLOCKSy)); // 次の行が GPU から CPU に対する行列 C の書き戻し CU_SAFE_CALL(cuMemcpyDtoH(data_c, d_data_c, sizeof(float)*N*N)); 149 関連論文の印刷公表の方法および時期 1. 全著者名: 大島 聡史, 吉瀬 謙二, 片桐 孝洋, 弓場 敏嗣 論文題目: GPU による高速な行列積の実装 印刷公表の方法および時期: 情報処理学会第 67 回全国大会, No. 3ZB-3, pp.159– 160, 2005 年 3 月 2 日 (本文との関連: 第 3 章に関連) 2. 全著者名: 大島 聡史, 吉瀬 謙二, 片桐 孝洋, 弓場 敏嗣 論文題目: GPU による BLAS 演算の性能評価 印刷公表の方法および時期: 先進的計算基盤システムシンポジウム SACSIS2005 論文集, pp. 247–248, 2005 年 5 月 18 日 (本文との関連: 第 3 章に関連) 3. 全著者名: 大島 聡史, 吉瀬 謙二, 片桐 孝洋, 弓場 敏嗣 論文題目: CPU と GPU の並列処理による行列積和演算方式の提案 印刷公表の方法および時期: 情報処理学会 研究報告 (ARC-164), pp.139–144, 2005 年 8 月 4 日 (本文との関連: 第 3 章に関連) 4. 全著者名: 大島 聡史 論文題目: CPU と GPU を用いた効率的な並列数値計算方式の提案と実装 印刷公表の方法および時期: 修士論文, 電気通信大学大学院情報システム学研 究科, 2006 年 3 月 5. 全著者名: 大島 聡史, 吉瀬 謙二, 片桐 孝洋, 弓場 敏嗣 論文題目: CPU と GPU を用いた並列 GEMM 演算の提案と実装 印刷公表の方法および時期: SACSIS2006 -先進的計算基盤システムシンポジ ウム, pp. 41–50, 2006 年 5 月 22 日 (本文との関連: 第 3 章に関連) 6. 全著者名: 大島 聡史, 吉瀬 謙二, 片桐 孝洋, 本多 弘樹, 弓場 敏嗣 論文題目: CPU と GPU を複数用いた並列数値計算環境の検討 印刷公表の方法および時期: SACSIS2006 -先進的計算基盤システムシンポジ 150 ウム, pp. 252–253, 2006 年 5 月 22 日 (本文との関連: 第 3 章に関連) 7. 全著者名: Satoshi Ohshima, Kenji Kise, Takahiro Katagiri, Toshitsugu Yuba 論文題目: Parallel Processing of Matrix Multiplication in a CPU and GPU Heterogeneous Environment 印刷公表の方法および時期: Proceedings of VECPAR’2006, pp.34 (14 pages, CD-ROM), 2006 年 7 月 10 日 (本文との関連: 第 3 章に関連) 8. 全著者名: 大島 聡史, 片桐 孝洋, 本多 弘樹 論文題目: CPU と GPU を用いた数値計算環境の提案 印刷公表の方法および時期: 日本応用数理学会 2006 年度年会, pp.328–329, 2006 年 9 月 16 日 (本文との関連: 第 3 章に関連) 9. 全著者名: 大島 聡史, 吉瀬 謙二, 片桐 孝洋, 弓場 敏嗣 論文題目: CPU と GPU を用いた並列 GEMM 演算の提案と実装 印刷公表の方法および時期: 情報処理学会論文誌 コンピューティングシステ ム, SIG12(ARC-15), pp.317–328, 2006 年 9 月 15 日 (本文との関連: 第 3 章に関連) 10. 全著者名: 大島 聡史, 片桐 孝洋, 弓場 敏嗣, 平澤 将一, 本多 弘樹 論文題目: CPU と GPU を用いた基本行列計算ライブラリ 印刷公表の方法および時期: HPCS2007 2007 年ハイパフォーマンスコンピュー ティングと計算科学シンポジウム, pp.66, 2007 年 1 月 17 日 (本文との関連: 第 3 章に関連) 11. 全著者名: Satoshi Ohshima, Kenji Kise, Takahiro Katagiri, Toshitugu Yuba 論文題目: Parallel Processing of Matrix Multiplication in a CPU and GPU Heterogeneous Environment 印刷公表の方法および時期: Selected Paper of VECPAR’2006, Springer LNCS 4395, pp.305–318, 2007 年 5 月 30 日 (本文との関連: 第 3 章に関連) 151 12. 全著者名: 大島 聡史, 平澤 将一, 本多 弘樹 論文題目: 既存の並列化手法を用いた GPGPU プログラミングの提案 印刷公表の方法および時期: 情報処理学会 研究報告 (ARC-175), pp.7–10, 2007 年 11 月 20 日 (本文との関連: 第 4 章に関連) 13. 全著者名: 大島 聡史, 平澤 将一, 本多 弘樹 論文題目: 既存の並列化手法を用いた GPGPU プログラミング 印刷公表の方法および時期: 第 49 回プログラミング・シンポジウム 予稿集, pp.81–88, 2008 年 1 月 8 日 (本文との関連: 第 4 章に関連) 14. 全著者名: 大島 聡史, 平澤 将一, 本多 弘樹 論文題目: メッセージ通信型 GPGPU プログラミング 印刷公表の方法および時期: 情報処理学会 研究報告 (ARC-177/HPC-114), pp.109–114, 2008 年 3 月 5 日 (本文との関連: 第 4 章に関連) 15. 全著者名: 大島 聡史, 平澤 将一, 本多 弘樹 論文題目: OMPCUDA : GPU 向け OpenMP の実装 印刷公表の方法および時期: 情報処理学会 研究報告 (HPC-118), pp.121-126, 2008 年 12 月 17 日 (本文との関連: 第 4 章に関連) 16. 全著者名: 大島 聡史, 平澤 将一, 本多 弘樹 論文題目: OMPCUDA : GPU 向け OpenMP の実装 印刷公表の方法および時期: HPCS2009 2009 年ハイパフォーマンスコンピュー ティングと計算科学シンポジウム, pp.131–138, 2009 年 1 月 22 日 (本文との関連: 第 4 章に関連) 152 参考論文の印刷公表の方法および時期 1. 全著者名: 大島 聡史, 檜田 敏克, 吉瀬 謙二, 片桐 孝洋, 本多 弘樹, 弓場 敏嗣 論文題目: 命令レベル並列性を利用した OpenMP によるプロセッサシミュレー タの並列実行 印刷公表の方法および時期: 情報処理学会第 66 回全国大会, No. 5T-8, pp.121– 123, 2004 年 3 月 9 日 2. 全著者名: 坂口 朋也, 鈴木 祥, 今村 昌之, 大島 聡史, 片桐 孝洋, 吉瀬 謙二, 弓 場 敏嗣 論文題目: 相乗り通信を利用したソフトウェアDSMの通信回数削減手法 印刷公表の方法および時期: 情報処理学会 研究報告 (ARC-169), pp.151–156, 2006 年 7 月 31 日 3. 全著者名: 今村 昌之, 鈴木 祥, 坂口 朋也, 大島 聡史, 片桐 孝洋, 吉瀬 謙二, 弓 場 敏嗣 論文題目: ソフトウェア DSM Mocha と MPI の並列ベンチマークを用いた性 能評価 印刷公表の方法および時期: 情報処理学会 研究報告 (ARC-172/HPC-109), pp.103–108, 2007 年 3 月 1 日 4. 全著者名: 今村 昌之, 鈴木 祥, 坂口 朋也, 大島 聡史, 片桐 孝洋, 吉瀬 謙二, 弓 場 敏嗣 論文題目: MPIとの比較によるソフトウェアDSMの性能評価 印刷公表の方法および時期: 情報処理学会 研究報告 (ARC-169), pp.157–162, 2007 年 7 月 31 日 153 著者略歴 大島 聡史 (おおしま さとし) 1982 年 2 月 16 日 栃木県に生まれる 2004 年 3 月 電気通信大学 電気通信学部 情報工学科 卒業 2004 年 4 月 電気通信大学 大学院情報システム学研究科 情報ネットワーク学専攻 博士前期課程 入学 2006 年 3 月 同上 修了 2006 年 4 月 電気通信大学 大学院情報システム学研究科 情報ネットワーク学専攻 博士後期課程 入学 2009 年 3 月 同上 修了予定 GPGPU に関する研究に従事.情報処理学会学生会員.
© Copyright 2024 Paperzz