CodeZine(コードジン)

特集ページ一覧

インテル Parallel Studioを使って
並列化プログラミングを試してみた

インテル Parallel Studioの導入と検証

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2009/06/22 14:01
目次

サンプルコードの説明と実行

 まずは、この記事のサンプルコードをダウンロードしてください。このコードの内容は、教師が生徒の5科目の採点をし平均点を求めるというものです。なお、このサンプルコードは実務を意識したものではないので、あくまでもParallel Studioを使用するためのものだと考えてください。

 ダウンロードが終わったら、「ParallelComputation.sln」をダブルクックしてMicrosoft Visual Studioを起動します。

 起動後、ソリューションエクスプローラのプロジェクト名[ParallelComputation]を右クリックし、[Intel Parallel Composer]-[Using Intel C++]を選択してください。選択するとメッセージボックスが表示されますので[Yes]を押下します。

 次に、ソリューションエクスプローラのプロジェクト名[ParallelComputation]を右クリックし、[Build Component Selection]を選択すると、ダイアログボックスが表示されますので、[Use TBB]をチェックしてください。

ソリューション名を右クリックして[Build Component Selection]を選択します。
ソリューション名を右クリックして[Build Component Selection]を選択します。

 最後にこのプロジェクトではラムダ式を使っていますので、[プロジェクトのプロパティ]-[C++]-[Language]を選択すると表示されるプロパティページで、[Enable C++0x Support]をYesにしてください。

[Enable C++0x Support]をYesにする。
[Enable C++0x Support]をYesにする。

 以上で準備完了です。デバッグなしで開始してください。すると、直列(シングルコア)での処理時間と並列(マルチコア)での処理時間が表示されます。

筆者の環境Aでは…

  • CPU:Intel Core2 Duo E7400
  • メモリ:4G
  • OS:WindowsXP(32ビット、最新パッチ適用済み)
実行結果。
実行結果。

 計測結果は、直列計算は0.0131596秒、並列計算は0.00733408秒でした。処理に必要な時間がおよそ55.7%(処理スピード約1.79倍)になっていますので、効率的に2つのCPUが使われていることが分かります。さらに、より多いコア数であればさらなる処理能力の向上が見込めます。

 次に既存のシステムを改良することも考えて、古い環境でも試してみました。

筆者の環境Bでは…

  • CPU:Intel Pentium4 530j
  • メモリ:4G
  • OS:WindowsXP(32ビット、最新パッチ適用済み)

 計測結果は、直列計算は0.0262007秒、並列計算は0.0225461秒でした。処理に必要な時間がおよそ86%(処理スピード約1.16倍)になっていますので、ハイパースレッディング・テクノロジー対応の古いCPUですら処理効率が上がることが分かります。

 しかも、パフォーマンスを向上させるために必要な作業量は少量です。

パフォーマンスチューニングで行う作業

 必要な作業は大まかに言うと3つだけです。

 1つ目に、TBBを使用するのに当たって必要なヘッダファイルをインクルードします。

 2つ目に、main関数内にtask_scheduler_init init;のプログラムを追加します。

 最後に、一番処理時間がかかっている場所を並列用に変えます。このサンプルでは、採点&平均点を求める場所が一番多くの処理時間を費やしているので、その部分を改良します。

元のコード
void ComputationAverage() {
    Student* tmp = this->students;
    for( int i = 0; i < Count; i++) {
        tmp[ i ].set_score_j( ( int )( rand() % 100 ) );
        tmp[ i ].set_score_n( ( int )( rand() % 100 ) );
        tmp[ i ].set_score_sc( ( int )( rand() % 100 ) );
        tmp[ i ].set_score_so( ( int )( rand() % 100 ) );
        tmp[ i ].set_score_e( ( int )( rand() % 100 ) );
        tmp[ i ].set_agerage ( ( tmp[ i ].get_score_j() + tmp[ i ].get_score_n() +
            tmp[ i ].get_score_so() + tmp[ i ].get_score_sc() +
            tmp[ i ].get_score_e() ) / 5 );
    }
};
改良後のコード
void ParallelComputationAverage() {
    parallel_for(
        blocked_range( 0, Count, 10000 ),
        [](const blocked_range& range) {
            Student* tmp = this->students;
            for( int i = range.begin(); i < range.end(); i++) {
                tmp[ i ].set_score_j( ( int )( rand() % 100 ) );
                tmp[ i ].set_score_n( ( int )( rand() % 100 ) );
                tmp[ i ].set_score_sc( ( int )( rand() % 100 ) );
                tmp[ i ].set_score_so( ( int )( rand() % 100 ) );
                tmp[ i ].set_score_e( ( int )( rand() % 100 ) );
                tmp[ i ].set_agerage ( ( tmp[ i ].get_score_j() + tmp[ i ].get_score_n() +
                    tmp[ i ].get_score_so() + tmp[ i ].get_score_sc() +
                    tmp[ i ].get_score_e() ) / 5 );
            }
    });
};

 今回は紙面の都合上コードの詳しい説明はできませんが、自分の手でマルチスレッドプログラミングをするよりも容易に、パフォーマンス向上が実現できることが実感できると思います。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

あなたにオススメ

著者プロフィール

  • インドリ(インドリ)

    分析・設計・実装なんでもありのフリーエンジニア。 ブログ「無差別に技術をついばむ鳥(http://indori.blog32.fc2.com/)」の作者です。 アドバイザーをしたり、システム開発したり、情報処理技術を研究したりと色々しています。 座右の銘は温故知新で、新旧関係なく必要だと考えた...

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5