1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Macで簡単に並列処理をしたい(OpenMPを使って)

Posted at

はじめに

それなりに高性能なMacを持っているので、そのCPUの力を引き出してみようという試みです。(あら、でもさらに高性能な後継モデルがつい先日発表になってしまいましたね、、、)
また、この文章の内容は、筆者が所属している会社・団体とは一切関わりがありません。いわゆる「自主的な研究の成果の発表」というものです。

OpenMP

簡単に並列処理をするならOpenMPということで。

準備

OpenMP on High Sierraによると、どうやら、Macの標準のコンパイラ(clang)はOpenMPの機能をサポートしているようです。なので、コンパイラ一式からインストールしなくていいです1。が、ライブラリは入ってなかったりするようなので、その辺りの準備は必要です。(ここから先、基本的には"OpenMP on High Sierra"の内容をなぞってます。が、当然、私のOSは"High Sierra"(macOS 10.13)な訳はなく、"Sequoia"(macOS 15)です。)

brew install libomp

が、その前に"brew search"で確認したら、手元のMacではすでにlibompはインストールされているようです。libompそのものをbrewでインストールした記憶はないので、OpenMPの機能を使っているHomebrewのソフトがあって依存関係でインストールされているってことでしょうね。ということで"brew install"はしませんでした。

コンパイル

諸々適切に設定されているのなら

cc -fopenmp myprog.c

でコンパイルできるようです2が、普通はそんなことはないでしょう。ということで、以下のようにします。

cc -o myprog -Xpreprocessor -fopenmp -lomp -I"$(brew --prefix libomp)/include" -L"$(brew --prefix libomp)/lib" myprog.c

(基本的には"OpenMP on High Sierra"の真似です。ccを使ったことのある方なら、やろうとしていることは大体分かるでしょう。)
これで特にエラーも出ることなく、コンパイルできました。

実験結果

以下のプログラムで実験してみます。OpenMPでは恒例らしい円周率を求めるプログラムです。

pi.c
#include <stdio.h>
#include <omp.h>

static long num_steps = 500000000;
long double step;

int main(void)
{
  int i; long double x, pi, sum  = 0.0;

  step = 1.0 / (long double) num_steps;

#pragma omp parallel for reduction(+: sum) private (x)
  for (i = 0; i < num_steps; i++) {
    x = (i + 0.5) * step;
    sum += 4.0 / (1.0 + x * x);
  }
  pi = sum * step;

  printf("%.15Lf\n", pi);

  return 0;
}

スレッド数は環境変数 OMP_NUM_THREADS で制御できます。まず並列化せずに実行です。

$ OMP_NUM_THREADS=1 ./pi
3.141592653589814

3.14...と円周率っぽい値3が出ているのでよしとしましょう。

では、スレッド数を変えて実行してみましょう。OMP_NUM_THREADS を1から20まで変更して実行した結果です。
pi-thread.png
real、userというのは、それぞれtimeコマンドのreal、userです。8スレッドまではuserはほぼ一定、realが順調に減っているのが分かるかと思います。ということは、全体の処理に掛かる時間はほぼ変わらないものの、処理が適切に分散されているため終了までに掛かる時間が順調に短くなっているということです。一方、9スレッドになるとuserの値が少し増えてしまっています。これは「パフォーマンス」コアが8であることに対応していると考えられます。8よりも多くのスレッドを同時に動かそうとすると、今度は「効率性」コアもスレッドの実行に参入してくるようです。「効率性」コアは「パフォーマンス」コアよりも遅いですから、全体として処理に掛かる時間が増えてしまった、ということでしょう。

お前の実力はそんなものか

いいえ、違います4。最適化オプション(-O3)すら付けてませんので。実は後からそれに気がついて、-O3を指定して同じことをやってみました。が、傾向は同じでした。(なので、改めてグラフを載せることもしません。)
今回は傾向が見られればそれで満足ですので、以上とします。(はい、私の実力はこんなものでした:sweat:。)さらなる高速化を追求したい方、あとは任せた!

  1. OpenMPを使うためにコンパイラ(OpenMPに対応したclangとか、gccとか)からインストールしないといけない時代もあったようです。今はずいぶん楽になりました。いい時代になったものです。

  2. あー、確かにGhostBSDならこれだけでできました。そういう環境もあるんですね。

  3. 最後の3桁(814)はスレッド数を変更すると変わるので信用してはいけません。が、今回は精度を追求するのが目的ではないので、これでよしとします。

  4. もちろん、私の人としての実力ではなくMacのCPUの実力のことですよ:wink:

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?