Upload
others
View
1
Download
0
Embed Size (px)
Citation preview
インテル® スレッドチェッカー 3.1 Linux* 版
入門ガイド
インテル® スレッドチェッカーは、競合状態、デッドロック、ストールなど、スレッド化問
題を特定します。解析中にエラーが発生しない場合でも、潜在的なエラーを特定することが
できます。スレッドチェッカーを使用して、特定の診断結果をフィルターしたり、クリティ
カル・ソースの場所を識別したり、並列ソフトウェアをより強固にするためのヒントを得る
ことができます。
概要
本ガイドでは、マルチスレッド・コード例を用いて、インテル® スレッドチェッカーでス
レッド化問題を特定し、対処する方法について示します。本ガイドは、スレッドチェッカー
を使用してコードを解析、修正することを目的としています。
目次
著作権と商標について ............................................................................................................................................................................................ 2
1. サンプルコードのビルド ................................................................................................................................................................. 3
2. データ収集................................................................................................................................................................................................. 5
3. 結果の解析およびコードの修正 ................................................................................................................................................. 7
4. 次のステップ ........................................................................................................................................................................................ 10
インテル® スレッドチェッカー 3.1 Linux* 版
著作権と商標について
本資料に掲載されている情報は、インテル製品の概要説明を目的としたものです。本資料は、明示されているか否かにかかわらず、また禁反言によるとよらずにかかわらず、いかなる知的財産権のライセンスを許諾するためのものではありません。製品に付属の売買契約書『Intel's Terms and Conditions of Sale』に規定されている場合を除き、インテルはいかなる責を負うものではなく、またインテル製品の販売や使用に関する明示または黙示の保証(特定目的への適合性、商品性に関する保証、第三者の特許権、著作権、その他、知的所有権を侵害していないことへの保証を含む)にも一切応じないものとします。インテル製品は、医療、救命、延命措置、重要な制御または安全システム、核施設などの目的に使用することを前提としたものではありません。インテル製品は、予告なく仕様や説明が変更される場合があります。
本資料で説明されているソフトウェアには、不具合が含まれている可能性があり、公表されている仕様とは異なる動作をする場合があります。現在までに判明している不具合の情報については、インテルのサポートサイトをご覧ください。
本資料およびこれに記載されているソフトウェアはライセンス契約に基づいて提供されるものであり、その使用および複製はライセンス契約で定められた条件下でのみ許可されます。本資料で提供される情報は、情報供与のみを目的としたものであり、予告なしに変更されることがあります。また、本資料で提供される情報は、インテルによる確約と解釈されるべきものではありません。インテルは本資料の内容およびこれに関連して提供されるソフトウェアにエラー、誤り、不正確な点が含まれていたとしても一切責任を負わないものとします。
ライセンス契約で許可されている場合を除き、インテルからの文書による承諾なく、本資料のいかなる部分も複製したり、検索システムに保持したり、他の形式や媒体によって転送したりすることは禁じられています。
機能または命令の一覧で「留保」または「未定義」と記されているものがありますが、その「機能が存在しない」あるいは「性質が留保付である」という状態を開発の前提にしないでください。留保または未定義の機能を不適当な方法で使用すると、開発したソフトウェア・コードをインテル・プロセッサー上で実行する際に、予測不可能な動作や障害が発生するおそれがあります。これらの項目は、インテルが将来のために留保しているものです。インテルが将来これらの項目を定義したことにより、衝突が生じたり互換性が失われたりしても、インテルは一切責任を負いません。
Intel、インテル、Intel ロゴは、アメリカ合衆国およびその他の国における Intel Corporation の商標です。
* その他の社名、製品名などは、一般に各社の表示、商標または登録商標です。
© 2007 Intel Corporation.
改訂履歴
資料番号 リビジョン
番号
説明 改訂日付
313445JA 001 初版 2006 年 5 月
313445 JA 002 マイナー変更 2006 年 9 月
2 資料番号: 313445-002JA
サンプルコードのビルド
1. サンプルコードのビルド サンプルコード primes は、1 ~ 10,000 の範囲の素数を割り出し、総数を算出して記録しま
す。POSIX* スレッド API を使用して、マルチスレッドで実行しますが、スレッドが同時に
同じメモリー・ロケーションにアクセスするため、潜在的な競合状態を引き起こします。そ
の結果、不正確な結果を生成することがあります。
サンプルコードをビルドするには
1. 次のコマンドを使用して、インテル® スレッドチェッカー環境を設定します。
2. > source <path_to_tcheck_bin_directory>/tcheckvars.csh
または
> . <path_to_tcheck_bin_directory>/tcheckvars.sh
3. 次のいずれかの方法で、primes 実行ファイルをビルドします。
GNU* C/C++ コンパイラーでビルドするには
a. primes ディレクトリーをコピーしたワークスペースに移動します。
b. 次のコマンドを入力します。
> make
このコマンドは、デバッグ情報を有効にし最適化を無効にする -g -o0 スイッチ
を使用して、primes.gcc と primesFixed.gcc という実行ファイルをビルド
します。これらの設定によって、スレッドチェッカーはバイナリー・インストル
メンテーション を実行できるようになり、実行ファイルをインストルメントして、
POSIX スレッド API の呼び出しおよびメモリーアクセスを監視できます。
インテル® C++ コンパイラー Linux 版でビルドするには
a. シェルコマンドのプロンプトで、インテル® コンパイラー環境を設定します。
次のように入力します。
> source <path_to_compiler_bin_directory>/iccvars.csh
または
> . <path_to_compiler_bin_directory>/iccvars.sh.
b. インテル® スレッドチェッカーがデフォルト (/opt/intel/itt) 以外の場所にイ
ンストールされている場合、変数 ITT_BASE が tcheck ディレクトリーを参照す
るように Makefile を編集してください。
313445-002JA/入門ガイド 3
インテル® スレッドチェッカー 3.1 Linux* 版
c. primes ディレクトリーに移動して、次のコマンドを入力します。
> make icc
コンパイラーは、最も多くの情報を収集できるように、デバッグを有効にし、最
適化を無効にする -g -o0 スイッチを使用して、.icc と .icc.tc という拡張子
の実行ファイルをビルドします。拡張子が .icc.tc の実行ファイルでは、コン
パイル時のソース・インストルメンテーションを可能にする -tcheck スイッチ
も使用されます。このスイッチにより、スレッドチェッカーは解析中により多く
の情報を提供することができます。
メモ: 拡張子が .icc の実行ファイルは、-tcheck スイッチを使用してコンパイルされていないため、バイナリー・インストルメンテーションのみ利用できます。
注意: 別のウィンドウでコードを実行したり、新たにログイン後コードを実行する前に、再度 "source iccvars.*" コマンドを実行する必要があります。
primes 実行ファイルを何度か実行すると、次のような出力が表示されます。
> ./primes.gcc
Determining primes from 1 - 10000
Found 1228 primes
> ./primes.gcc
Determining primes from 1 - 10000
Found 1229 primes
> ./primes.gcc
Determining primes from 1 - 10000
Found 1229 primes
> ./primes.gcc
Determining primes from 1 - 10000
Found 1227 primes この出力結果をよく見ると、同じプログラムであるにもかかわらず、実行結果が異なってい
ることがわかります。
1 ~ 10,000 の素数の正しい総数は 1,229 です。ここでは、スレッド化による不整合を比較
的簡単に見つけることができましたが、大規模なプログラムでは、スレッド化による不整合
を見つけることはより困難になります。
スレッドチェッカーは、すべての実行で発生しないものも含め、スレッド化による不整合を
特定します。
4 資料番号: 313445-002JA
データ収集
2. データ収集 セクション 1 で行ったように、次のコマンドを使用して、インテル® スレッドチェッカーの
コマンドライン・ツール環境を設定します。
> source <path_to_tcheck_bin_directory>/tcheckvars.csh
または
> . <path_to_tcheck_bin_directory>/tcheckvars.sh
次のコマンドを入力して、コマンドライン・ツールを起動します。
> tcheck_cl ./primes.gcc
次のような出力が表示されます。
Intel® Thread Checker 3.1 command line instrumentation driver
Copyright (c) 2006 Intel Corporation. All rights reserved.
Building project
Instrumenting
25% primes.gcc ( All Functions ):..
75% libc-2.3.2.so ( Minimal ):....
100% libpthread-0.60.so ( Minimal ):..
Running: <path>/primes/primes.gcc
Determining primes from 1 - 10000
Found 1229 primes
Application finished
....
コマンドライン・ツールは、実行ファイル primes.gcc および関連モジュールのバイナ
リー・インストルメンテーションを実行します。インストルメンテーションの予測時間とイ
ンストルメントされるモジュールが表示されます。大規模なアプリケーションでは、処理に
時間がかかります。インストルメント・レベルも表示されます。
primes.gcc ではデバッグ情報が有効なため、スレッドチェッカーは最も高いインストル
メント・レベル All Functions (すべての関数) を使用します。
コンパイル済みライブラリーにはデバッグ情報がないため、スレッドチェッカーはライブラ
リー関数の呼び出しだけを記録するインストルメント・レベル Minimal (最小) を使用します。
インテル® スレッドチェッカーは、一時的にデータを格納するためのディレクトリーを作成
します。デフォルトでは、ディレクトリーの名前は /tmp/<login_name>_tc_cl_cache
です。次のように、短い形式または長い形式のコマンドライン・スイッチを使用して別の
ディレクトリーを指定することもできます。
313445-002JA/入門ガイド 5
インテル® スレッドチェッカー 3.1 Linux* 版
> tcheck_cl -d /home/sample_data primes.gcc
または
> tcheck_cl --cache_dir /home/sample_data primes.gcc
6 資料番号: 313445-002JA
結果の解析およびコードの修正
3. 結果の解析およびコードの修正 実行後、インテル® スレッドチェッカーはインストルメンテーション・データを収集し解析
して、利用可能なシンボル情報と関連付けます。診断結果は次のように表示されます。
________________________________________________________________________________
|ID|Short |Severity|Count|Context|Description |1st Acc|2nd Acc|
| |Descri| Name | |[Best] | |ess[Bes|ess[Bes|
| |ption | | | | |t] |t] |
________________________________________________________________________________
|1 |Write |Error |941 |primes |Memory read at primes.c: 41 c|primes |primes |
| |-> Rea| | |.c:27 |onflicts with a prior memory |.c:42 |.c:41 |
| |d data| | | |write at primes.c:42 (flow de| | |
| |-race | | | |pendence) | | |
________________________________________________________________________________
|2 |Write |Error |941 |primes |Memory read at primes.c: 42 c|primes |primes |
| |-> Rea| | |.c:27 |onflicts with a prior memory |.c:42 |.c:42 |
| |d data| | | |write at primes.c:42 (flow de| | |
| |-race | | | |pendence) | | |
________________________________________________________________________________
|3 |Write |Error |941 |primes |Memory write at primes.c:42 c|primes |primes |
| |-> Wri| | |.c:27 |onflicts with a prior memory |.c:42 |.c:42 |
| |te dat| | | |write at primes.c:42 (output | | |
| |a-race| | | |dependence) | | |
________________________________________________________________________________
|4 |Write |Error |1 |primes |Memory write at primes.c:41 c|primes |primes |
| |-> Wri| | |.c:27 |onflicts with a prior memory |.c:41 |.c:41 |
| |te dat| | | |write at primes.c:41 (output | | |
| |a-race| | | |dependence) | | |
________________________________________________________________________________
|5 |Thread|Informat|1 |Whole P|Thread termination at primes.|primes |primes |
| | termi|ion | |rogram |.c:61 – includes stack alloca|.c:61 |.c:61 |
| |nation| | |1 |tion of 10489856 and use of 2| | |
| | | | | |332 bytes | | |
これで、診断結果を解析し、アプリケーションにおけるスレッド化による不整合を修正する
準備が完了しました。
上の表で ID 1 というのが最初の診断データです。ここでは、Write -> Read data-race (書き
込み -> 読み取りの競合状態) エラーが発見されました。Severity Name (重要度) は、診断ク
ラスを示します。ここでは、Error (エラー) となっています。Count (カウント) は、実行中に
このイベントが発生した回数を示します。実際のカウントは、スレッドのスケジューリング
によって実行ごとに異なります。
Context[Best] (コンテキスト [最高]) は、診断のコンテキストを示します。Best (最高) では、
スレッドチェッカーは最も多くの情報を表示します。デバッグ情報が有効なため、ソース
ファイル primes.c の 27 行目の関数というように、コンテキストが表示されます。
313445-002JA/入門ガイド 7
インテル® スレッドチェッカー 3.1 Linux* 版
Description (説明) は、より詳細な診断結果を示します。ここでは、primes.c の 42 行目で 1
つのスレッドが変数に書き込み (1st Access[Best] (1 回目のアクセス [最高])) を行い、41 行
目で別のスレッドが保護されていない同じ変数から読み取り (2nd Access[Best] (2 回目のア
クセス [最高])) を行っているために、データ依存エラー (フロー依存) が発生しています。
ソース・インストルメント済みの primes.icc.tc を使用してスレッドチェッカーを実行
すると、最初の診断結果が次のように表示されます。
________________________________________________________________________________
|ID|Short |Severity|Count|Context|Description |1st Acc|2nd Acc|
| |Descri| Name | |[Best] | |ess[Bes|ess[Bes|
| |ption | | | | |t] |t] |
________________________________________________________________________________
|1 |Write |Error |737 |primes |Memory read of primeCount at |primes |primes |
| |-> Rea| | |.c:27 |primes.c:41 conflicts with a |.c:42 |.c:41 |
| |d data| | | |prior memory write of primeCo| | |
| |-race | | | |unt at primes.c:42 (flow depe| | |
| | | | | |ndence) | | |
この診断結果には、前出の診断結果と異なる点が 2 つあります。まず、スケジューリングが
異なるために、Count (カウント) 値が異なっています。また、Description (説明) では、問題
となっているグローバル変数 primeCount についても表示されています。この追加情報は、
ソース・インストルメンテーションを行った場合のみ表示されます。バイナリー・インスト
ルメンテーションでは、グローバル・オブジェクト名は表示されません。
実際に、問題のソース行を見てみましょう。
38 while ( (number % factor) != 0 ) factor += 2;
39 if ( factor == number )
40 {
41 primes[ primeCount ] = number;
42 primeCount++;
43 }
グローバル変数 primeCount とグローバル配列 primes[] は保護されておらず、4 つの作
業スレッドすべてによってアクセスされます。同期オブジェクトを追加して変数の使用をシ
リアル化することにより、予測不可能な同時変更から共有変数を保護することができます。
8 資料番号: 313445-002JA
結果の解析およびコードの修正
コードを修正し問題を排除するには
1. グローバル・ミューテックスを追加して、メインプログラムで初期化します。
2. 次のように、変数の読み取り/書き込みを行う前に、各スレッドにミューテックスを取
得させます。
3. primes ディレクトリーをワークスペースにコピーします。デフォルトでは、このサン
プルコードは /opt/intel/itt/tcheck/samples/primes にインストールされま
す。
pthread_mutex_t cs;
...
void * findPrimes ( void * arg )
{
....
while ( (number % factor) != 0 ) factor += 2;
if ( factor == number )
{
pthread_mutex_lock(&cs);
primes[ primeCount ] = number;
primeCount++;
pthread_mutex_unlock(&cs);
}
}
サンプルコード primesFixed.c には修正後のコードが含まれています。実行ファイル
primesFixed.gcc は、すぐにインテル® スレッドチェッカーで解析することができます。
インテル® C/C++ コンパイラー Linux 版でビルドされている場合、primesFixed.icc では
バイナリー・インストルメンテーションを使用した解析を行うことができます。また、
primesFixed.icc.tc は、コンパイラーにより既にインストルメント済みです。
313445-002JA/入門ガイド 9
インテル® スレッドチェッカー 3.1 Linux* 版
4. 次のステップ インテル® スレッドチェッカーを最大限に活用するために、次のリソースも参考にしてくだ
さい。
• オンラインヘルプ: オンラインヘルプには、スレッドチェッカーで利用可能なコマンド
ライン・オプションの一覧が含まれています。オンラインヘルプにアクセスするには、
次のコマンドを実行してください。
> tcheck_cl --help
• 診断: tcheck/doc ディレクトリーにある DiagnosticsGuide.pdf では、診断の詳
細、原因、および解決方法を提供しています。
• サンプル: 追加のコード例を利用することができます。本ガイドで取り上げていないほ
かのスレッド化問題を特定し、対処する方法について理解するのに役立ててください。
サンプルは、tcheck/samples ディレクトリーにあります。
• リリースノート: tcheck/doc にある製品のリリースノート (Release_Notes.txt)
には、製品のリリースノートには、製品の簡単な概要、動作環境、テクニカルサポー
ト、および既知の制限事項に関する更新情報が含まれています。
• インテル® スレッド・プロファイラー: インテル® スレッドチェッカーでコードを解析し
た後に、インテル® スレッド・プロファイラーを使用してパフォーマンスを向上させる
ことができます。
スレッド・プロファイラーおよびその他のインテル® ソフトウェア開発製品に関する情
報は、http://www.intel.co.jp/jp/software/products/ を参照してください。
10 資料番号: 313445-002JA