SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

並列処理化による処理速度への影響

処理並列は、必ず処理速度が向上するのか

3つのアルゴリズムを並列化

検証

 さあ、結果を検証しましょう。それぞれのアルゴリズムの主要な要素数を変更して、実行しました。結果の一例を、表形式で表します。

Bubble Sortの計測結果
要素数 10000 20000 30000
  シリアル パラレル シリアル パラレル シリアル パラレル
1回目 0.4060 6.1150 1.6380 24.0090 3.6510 54.057
2回目 0.4210 6.2410 1.6530 25.3200 3.8530 56.287
3回目 0.4060 6.2560 1.7010 25.3660 3.9000 56.474
4回目 0.4050 6.2250 1.6380 25.1940 3.6820 56.443
5回目 0.4210 6.3180 1.6690 25.3040 3.8070 56.459
平均 0.4118 6.2310 1.6598 25.0386 3.7786 55.944
処理効率 0.06608891 0.066289649 0.067542543
FizzBuzzの計測結果
要素数 10000000 20000000 30000000
  シリアル パラレル シリアル パラレル シリアル パラレル
1回目 3.4790 1.9350 7.7220 3.8070 11.384 5.9430
2回目 3.4330 1.8870 7.9250 3.8370 10.920 5.8820
3回目 3.4320 1.8570 7.3910 3.8380 10.921 5.8190
4回目 3.4320 1.9190 7.3950 3.8220 10.874 5.8190
5回目 3.4480 1.9030 7.5290 3.8220 10.921 5.8040
平均 3.4448 1.9002 7.5924 3.8252 11.004 5.8534
処理効率 1.812861804 1.984837394 1.87993303
素数(の数)を求めるの計算結果
要素数 100000 300000 500000
  シリアル パラレル シリアル パラレル シリアル パラレル
1回目 2.6990 2.3400 22.7450 15.5390 52.4810 38.5330
2回目 2.6990 2.3240 21.2480 15.4930 52.4970 38.7670
3回目 2.7140 2.3250 20.9510 15.4150 52.6060 39.0010
4回目 2.7150 2.3870 21.0290 15.4920 52.4500 38.9240
5回目 2.6980 2.4960 20.9980 15.8210 52.5430 38.8140
平均 2.7050 2.3744 21.3942 15.5520 52.5154 38.8078
処理効率 1.139235175 1.375655864 1.353217652

 バブルソートについては、並列化をする方が遅い結果となりました。これは、並列化して実行する処理のほとんどをクリティカルとしたため、実際には並列化が行われないことと、クリティカルエリアを実行するために待ち合わせが発生するためです。並列化をするためには、まず、クリティカルなエリアをまとめ、できるだけ短い時間に抜けるような工夫が必要です。

 素数(の数)を求めると、FizzBuzzで、並列化による効果が異なります。FizzBuzzでは1.8倍の効果が出ていますが、素数(の数)を求めるでは、1.3倍にとどまっています。これは、素数の数をカウントするためにクリティカルエリア(アトミックな計算)があることと、並列化で実行されるループの中の処理が、ループの後ろほど数が多いことが原因です。

 素数(の数)を求める処理では、「2以下の素数の数」「3以下の素数の数」…「100以下の素数の数」と数が進むにつれて、だんだんと調べる数が多くなります。Open MPのforディレクティブでは、1つのスレッドが実行するループの回数を制御します。例えば、全体で千回のループであれば、100回のループを10回繰り返すような動作をします。この10回の繰り返しを、並列に処理するわけです。今、50万以下の素数を求めるわけですが、これを「25万未満」と、「25万以上50万以下」の2つに分けて実行したとします。すると、「25万未満」を担当するスレッドは、「25万以上50万以下」を担当するスレッドよりも、処理の時間が圧倒的に短くなります。すなわち、いずれかのスレッドの負荷だけが上がり、負荷の平準化がされないために、効率が上がらないのです。これを、「100ずつ」に区切って5,000回のタスクに分けると、1つめのタスクと5,000個目のタスクでは処理にかかる時間が大きく異なりますが、1つめのタスクと2つめのタスクでは、わずかな差しかありません。2つのスレッドに負荷を平準化して掛けることにより、処理効率を上げることができます。今回のコードでは、こういう処理をしていないため、1.3倍の効率しか出ていません。コードを少し変更すれば、処理効率はもう少し向上します。

まとめ

 この結果から、何でもかんでも並列化すれば、等しく速くなるわけではない、ということが分かります。並列化に向いているアルゴリズム、向いていないアルゴリズムがあります。また、並列化にむいているアルゴリズムであっても、十分に検討しなければ思わぬバグを作り込むことになります。事前にしっかりと調査し、コードの設計をすることが必要です。

並列化する前に

  1. パフォーマンスを計測し、高速化しなければならないか、検討する
    • 10ミリ秒で終わる処理を5ミリ秒にしたところで、どれほどの意味があるでしょうか。1分かかるところを40秒で処理できるようにするのは、意味があるでしょう。すなわち、「何倍」という倍率よりも、体感できる時間を短くする方が大事です。
  2. より効率化された書き方がないか、調査する
    • 例示した「素数か判定する」ルーチンは、判定に使う数は判定したい数の平方根を超えない整数まででかまいません(IsPrimeNumberFast関数を参照)。そうすると、32ビット程度の数では、並列化をする必要がなくなります。
    • ここでは、「並列化に向かないアルゴリズム」の説明として、バブルソートを選びました。ソートをするなら、クイックソートやマージソートなど、より効率的なアルゴリズムがあります。
  3. 処理を、より単純化する
  4. 並列化できる箇所を明確にする
    • 本文では、いくつかの並列化できない箇所を、予め廃止するか並列化しない箇所へ退避させています。コンソール出力をやめる、メモリの確保を前もって行うなどです。
  5. 並列に動作すると不具合を引き起こす箇所がないか、検証する
    • 処理順序が一定であることに依存しないか、検証します。FizzBuzz問題を、ループ内でコンソールに出力すると、処理順序が一定ではないことが問題になります。そのため、決められた位置へ格納するというアルゴリズムに変更しています。
    • 複数のスレッドで、同じ領域を書き換えることがないか、検証します(「生産者と消費者」問題)。
  6. 不具合を起こす箇所を一か所にまとめ、クリティカルブロックとする
    • デッドロックしないように、慎重に設計します(「哲学者の食事」問題)。
  7. クリティカルブロックの処理時間と、並列化している箇所の処理時間を比較する
  8. クリティカルブロックの処理時間が長い場合、並列化をあきらめる

謝辞

 本記事は、一旦ブログにて公開し、コミュニティの皆さまよりご意見をいただいて、より読みやすいように修正しました。ご協力くださった方々に、この場を借りてお礼申し上げます。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
この記事の著者

はなおかじった(ハナオカジッタ)

わんくま同盟で、ブログを書いています。2004年10月から5年間連続で、Microsoft Most Valueable Professional Award for ASP/ASP.NET を受賞させていただきました。コミュニティの皆様のおかげです。ありがとうございます。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/4914 2010/03/04 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー