ノード内並列

まずは,内積計算プログラムが1つのRaspberry Pi上の複数のCPUコアを利用できるよう に拡張しましょう.これを,ノード内並列化と呼びます.

複数のCPUコアを活用するには様々な方法がありますが,スパコンにおいて広く 用いられているのは,OpenMPと呼ばれるAPIです. OpenMPに対応するコンパイラを用いると,ソースコード中にディレクティブと 呼ばれるコメントを挿入するだけで, コンパイラが自動的に並列化しててくれます.

逐次版の内積計算プログラムに追加したのは, #pragma omp parallel for reduction(+:sum)という1行だけです.

#include <stdio.h>

#define TRIALS (1000)
#define ARRAY_SIZE (1000 * 1000)

double a[ARRAY_SIZE];
double b[ARRAY_SIZE];

void compute()
{
    double sum = 0;

    #pragma omp parallel for reduction(+:sum)
    for (int i = 0; i < ARRAY_SIZE; i++) {
        sum += a[i] * b[i];
    }
}

int main(int argc, char *argv[])
{
    for (int i = 0; i < ARRAY_SIZE; i++) {
        a[i] = 1.0;
        b[i] = 2.0;
    }

    for (int i = 0; i < TRIALS; i++) {
        compute();
    }

    return 0;
}

このプログラムをgccコンパイラでコンパイルします. OpenMPを使用するプログラムするためには,-fopenmpというオプションを指定する必要があります.

$ gcc -fopenmp -o dot_omp dot_omp.c

このプログラムを実行します.

time ./dot_omp

OpenMPを使用しない場合の26.886秒に対して,7.372秒に実行時間を短縮できました. Raspberry Pi 3B+は4つのCPUコアを搭載しています.4つのCPUコアを活用することで, 3.6倍の高速化を達成できたことになります.

real	0m7.372s
user	0m29.175s
sys	0m0.040s