• トップ
  • G-DEPについて
  • ご購入ガイド
  • サポート
  • お問い合わせ

G-DEPトップ  >  第10回 OpenACCとPGIコンパイラについて

第10回 OpenACCとPGIコンパイラについて

第10回 「OpenACCとPGIコンパイラについて」

<< 第9回   |   目次に戻る   |   第11回 >>

今回は、演習から離れてGPUコンピューティングに役立つコンパイラを紹介したいと思います。

10.1 コンパイラ

 ここまで読んで頂いた方に今更聞くまでもないかもしれませんが、コンパイラとはどういうものなのか、どうして必要なのかということを原点に立ち返りたいと思います。

そもそも、コンパイラって何でしょう?
 
 コンパイラ(compiler)とは、プログラミング言語で書かれた、プログラムのソースコード(原始コード)を、機械語、ないしバイトコードなどの中間言語によるオブジェクトコード(目的コード)に変換するプログラムである。
引用 「Wikipedia - コンパイラ」より
 
 ソースコードと言えば、いわゆるC言語のような人の言葉を用いたプログラミング言語で記述されたもので、意味も構成も人間が理解しやすくなっています。しかし、計算機側では0と1の羅列(2進数)によって計算を行うため、そのままプログラムを読み取ることはできません。
 そこで翻訳家として活躍するのが、コンパイラです。
 
つまり簡単に言えば
「人間が理解しやすい言語で作られたプログラムを、機械が理解できる言語に翻訳するもの」
というわけです。
 
翻訳の流れ
ソースコード:C、C++、FORTRAN…etc
 ↓
アセンブリコード
 ↓
オブジェクトコード:0100111010110111001…
 
もう少し踏み込むと、
 
これが処理フローになります。
今回はそれぞれの部分について詳しい説明は避けますが、興味のある方は最下記の参考ページもご覧ください。
 
 
 ちなみに、コンパイラとはプログラミング言語処理系のソフトウェアという位置づけに属します。
 言語処理系とは、プログラミング言語で記述されたプログラムを計算机上で実行するためのもので、大別してインタープリタコンパイラという2つの構成方法があります。
 
○インタープリタ(interpreter)
 言語の意味を解析しながら、その意味する動作を実行します。
 
○コンパイラ(compiler)
 ある言語を他の言語に変換し、計算机上で実行させることができるようにするものです。また上ではプログラミング言語→機械語という役割で説明していますが、他のプログラミング言語、仮想機械コードなどに変換するものもコンパイラと呼びます
 
2つのフローの違いを表したイメージが下図になります。
 
 
 コンパイラと呼ばれるソフトウェアは数多くあり、例えば、GCC、インテルコンパイラ、Visual Studio(cl.exe)など無料のものから有料のものまで多岐に頒布されています。もちろん、これまで取り扱ってきたnvccもコンパイラの一種です。インタプリタにはMATLABなどが挙げられます。

 

10.2 OpenACC

ところで、これまで演習をやっていて、もしくはご自分でCUDAプログラムを作成されていた方、

「元のソースコードを書き換えるのが面倒だな」
「もっと手軽にGPUプログラミングできないのだろうか」
「CUDAってやっぱり難しい…!」
 
と思ったことはありませんか?
 そんなもやもやの解決策になり得る方法はないのだろうか?
 
それが今回の表題にもなっているOpenACCです
 
 これは、GPUプログラミングにおける独自言語(例えばCUDA、OpenCL、Direct Computeなど)に寄らず、簡単な指示文の挿入だけでGPUプログラミングを可能とする、画期的な技術規格です。並列化が可能な構文に合わせた指示文で指定してあげることで、自動的にGPUで計算できるように変換してくれます。
 
 えっ、これがあればCUDAを覚える必要はないのでは?確かに、その通りです。
OpenACCが叶えるのは、CUDAのような独自言語を新たに覚えなくとも、手軽にGPUコンピューティングを扱えるようになることです。

ただ、実際にはマルチGPUに対応していないなどの制約があったり、CUDAのような独自言語でガリガリとコードを書いてチューニングした方が計算速度は速くなります。
そのため、
  • GPUで計算させたらどのくらい早くなるのか手短に調べたい
  • 文量は少ないけれど計算時間が非常にかかる部分はCUDAで、それ以外はOpenACCで手軽に高速化したい
といった使い方が適していると思われます。
 
 
OpenACCを使用する場合は、並列計算させたい関数、構文の前の行に以下のような指示文を挿入します。(Cの場合)
 
#pragma acc ~(オプション
 
オプションなどについてはまた改めて説明しますが、下の例題と合わせて軽く見ていきたいと思います。
 
 
 
 
 
10.3 PGIコンパイラについて

 このOpenACCという規格を使用するためには、それに対応したコンパイラでコンパイルする必要があります。
今回紹介したいのは、そのOpenACCにも対応しているPGIコンパイラという商用コンパイラです。 
 
 
  PGI® コンパイラ は、HPC とコンパイラ技術で長い経験を有する The Portland Group Inc (PGI) 社の科学技術並びにエンジニアリング分野におけるフラグシップ・コンパイラです。インテル(R)のプロセッサにも AMD のプロセッサにも最適化対応し、さらにこれら 32ビット/64ビットのどちらのマルチコア・プロセッサにも最適化対応するハイ・パフォーマンス自動並列化コンパイラです。そして、2009年、PGI は業界で初めて GPGPU 用のPGIアクセラレータ™ コンパイラを提供し、HPCソフトウェア環境を新たなステージへ変革しました。
引用「Softek -PGIトップ」より(http://www.softek.co.jp/SPG/Pgi/index.html
 
 PGIコンパイラとは、上記にもあるよう科学技術・エンジニア分野における強みを持つコンパイラでIntelおよびAMDのプロセッサに最適化対応しています。また近年、業界初のGPGPU用のコンパイル機能も導入(OpenACCに対応)したことで注目を集め、各所において一層の普及を見せています。東工大のTSUBAME2.0にも導入されていますし、弊社のコンピューターにもGPU用コンパイラとして付属することができます。
 
 OpenACC指示文および、このコンパイラを用いることでCUDAコードを記述しなくても並列計算部分を自動的にソフトが判断してGPUで計算できるようなコードに変換してくれます。
 
 
 
10.4 実際にコンパイルをしてみる

 ここで、実際どの程度計算が高速化するのか、例を取ってみてみましょう。

 forループを使ってπの値を計算するというプログラムで試してみます。以下のNVIDIAのウェブサイトを参考にさせて頂きました。

NVIDIA「OpenACC であなたのプログラムを加速しよう 
GPU アクセラレーションディレクティブのオープンスタンダード」
 
参考までにそれぞれのソースコードを示しておきます。
 ここでは計算時間の高速化を分かりやすく示すためにNを非常に大きくしています。計算環境によっては重くなってしまう可能性がありますので、ご自身のPCで試してみたい方はNの値を小さくしてから始めることを推奨します。
 
「pi.c」
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <time.h>


#define N 500000000


int main( int argc, char** argv)
{
    double pi = 0.0f; long i; int k;
    // 時間計測
    clock_t start, stop;

    // 時間計測開始
    start = clock();

    // pi計算
        for (i=0; i<N; i++){
            double t= (double)((i+0.5)/N);
            pi +=4.0/(1.0+t*t);
        }

    // 時間計測終了
    stop = clock();

    // 計算時間結果の表示
    printf("It takes %.2fsec\n", (double)(stop-start)/CLOCKS_PER_SEC);
    return 0;
}
 
「pi_acc.c」
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <time.h>


#define N 500000000


int main( int argc, char** argv)
{
    double pi = 0.0f; long i; int k;
    // 時間計測
    clock_t start, stop;

    // 時間計測開始
    start = clock();

    // pi計算
#pragma acc kernles
        for (i=0; i<N; i++){
            double t= (double)((i+0.5)/N);
            pi +=4.0/(1.0+t*t);
        }


    // 時間計測終了
    stop = clock();

    // 計算時間結果の表示
    printf("It takes %.2fsec\n", (double)(stop-start)/CLOCKS_PER_SEC);
    return 0;
}

#pragma acc kernles」と挿入した部分が指示文です。

 

 それでは、早速結果を見ていきましょう。実行ファイル名「pi.exe」が指示文なし、「pi_acc.exe」が指示文ありのプログラムで、指示文の挿入以外は全く同じソースコードです。

※コンパイラでACCのプログラムであることを認識させるため、「pgcc -acc」というオプションを付けています。これがないとOpenACC指示文をプログラムに書いていても認識されないのでご注意ください。逆に言えば、-accを付けなければ指示文を無視して通常のC言語としてコンパイルし、GPUの無い環境でもプログラムを使用することが出来ます。また、今回は以下のイメージのようにディレクティブ無しの場合も比較のため-accを付けていますが、そのままC言語のみのプログラム同様に処理されます。

開発環境
 CPU:Intel core i7-920
 GPU:NVIDIA Tesla C2050
 Memory:6GB

指示文なし:4.08秒(1coreのみ使用)
指示文あり:0.14秒

同じプログラムなのに、指示文を挿入しただけでなんと約30倍も高速化しています。

上の例は1coreとの比較なので大げさかもしれませんが、CPUのマルチコア性能等を引き出したとしてもその数倍の高速化が可能となる場合が多いです。

OpenACC&PGIコンパイラを用いると、簡単に計算時間を大幅に削減できることができます。

 
 
 今回は今までと少し変わった視点で解説しましたが、もしかしたら、今までやってきたことはなんだったのか!早くこれを教えてくれよ!と思った方もいらっしゃるかもしれませんね(笑)
 
 もちろんGPUコンピューティングの本質を理解することが大切ではありますが、こうした新しい技術を使えばGPUコンピューティングの世界はよりグッと近くなるということを述べたいと思い、今回のコラムを書きました。
 
 次回はもう少し踏み込んで、オプション等も含めた実際の使い方について触れていきたいと思います。

 

<< 第9回   |   目次に戻る   |   第11回 >>


参考資料

・「筑波大学 システム情報工学研究科 佐藤三久教授 講義資料」
http://www.hpcs.is.tsukuba.ac.jp/~msato/lecture-note/comp-lecture/note1.html
 
・「コンパイラの基礎を理解する」(http://www.atmarkit.co.jp/fjava/rensai4/compiler01/compiler01_02.html
 
・「OpenACC公式サイト」(http://www.openacc-standard.org/
 
・「Softek PGIコンパイラ」(http://www.softek.co.jp/SPG/Pgi/

・「東京工業大学GPUコンピューティング研究会-OpenACCの紹介」-PDF-

(執筆 G-DEP Associate Research Engineer 東京大学大学院工学系研究科 岡安優)