目次

3.3 OpenMPによる並列化

3.3.1 OpenMPによる並列化

OpenMPでは並列化可能なループの直前に指示文を記入します。
図2-9-2の行列・ベクトル積はデータ依存関係がないので、 一番外側のループをOpenMPを用いてそのまま並列化することができます。
ベクトル同士の演算(BLAS Level-1)も以下のように簡単に並列化することができます。

リスト3-3-1 OpenMPによるコピー(Zcopy)の並列化


void Zcopy(int64_t n, const d_complex_t *x, d_complex_t *y)
{
	int64_t i;
#ifdef _OPENMP
#pragma omp parallel for
#endif
	for (i = 0; i < n; i++) {
		y[i].r = x[i].r;
		y[i].i = x[i].i;
	}
}

リスト3-3-2 OpenMPによる内積(Zdotu)の並列化


d_complex_t Zdotu(int64_t n, const d_complex_t *x, const d_complex_t *y)
{
	d_complex_t ret;
	double sum_r = 0, sum_i = 0;
	int64_t i;
#ifdef _OPENMP
#pragma omp parallel for reduction (+:sum_r, sum_i)
#endif
	for (i = 0; i < n; i++) {
		sum_r += (x[i].r * y[i].r) - (x[i].i * y[i].i);
		sum_i += (x[i].r * y[i].i) + (x[i].i * y[i].r);
	}
	ret.r = sum_r;
	ret.i = sum_i;
	return ret;
}

3.3.2 OpenMPの計算時間

表3-3-1と図3-3-1にスレッド数と計算時間の関係を示します。
スレッド数が少ないときはmatrixモードの方が速いですが、 スレッド数が多いときはnomatrixモードの方が速くなります。
ただし、両者の差は小さいので使用メモリーの少ないnomatrixモードを推奨します。
またスレッド数は物理コア数(=8)と論理コア数(=16)の差は小さいのでどちらでもかまいません。

表3-3-1 OpenMPの計算時間(CPU、()内は1スレッドとの速度比)
スレッド数benchmark100benchmark200
nomatrixmatrixnomatrixmatrix
1136秒 (1.0) 113秒 (1.0) 1066秒 (1.0) 859秒 (1.0)
2 77秒 (1.77) 79秒 (1.43) 592秒 (1.80)523秒 (1.64)
4 71秒 (1.92) 55秒 (2.05) 535秒 (1.99)460秒 (1.87)
8 47秒 (2.89) 49秒 (2.31) 377秒 (2.83)385秒 (2.23)
16 46秒 (2.96) 52秒 (2.17) 296秒 (3.60)402秒 (2.14)


図3-3-1 OpenMPの計算時間(CPU)