performance-profiling について
計算材料科学シミュレーション向けの性能分析スキルです。ログ、スケーリングデータ、シミュレーション設定を分析し、時間のかかる処理、並列効率、メモリ量、ボトルネックを特定して改善案を示します。
主な機能
- 01シミュレーションログの時間データ解析
- 02強スケーリングと弱スケーリングの分析
- 03総メモリ量と内訳の推定
- 04ボトルネック検出と改善案の提示
- 05JSON形式での分析結果出力
活用シーン
- 01シミュレーションで最も時間のかかる処理の特定
- 02プロセッサー数増加時の並列効率の評価
- 03利用可能なメモリに収まるかの推定
- 04検出したボトルネックに応じた改善策の選択
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ heshamfs/ materials-simulation-skills --skill performance-profilingインストール後、Claude Code で/performance-profilingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
CHANGELOG.mdevals/evals.jsonevals/files/custom_format.logmemory_params.jsonscaling_results.jsonscaling.jsonsimulation.logtiming.jsonreferences/optimization_strategies.mdprofiling_guide.mdscripts/bottleneck_detector.pymemory_profiler.pyscaling_analyzer.pytiming_analyzer.py詳細
パフォーマンスプロファイリング
目標
シミュレーションのパフォーマンスを分析し、ボトルネックを特定し、計算材料科学シミュレーション向けの最適化戦略を推奨するツールを提供します。
要件
- Python 3.10+
- 外部依存関係なし(Python 標準ライブラリのみを使用)
- Linux、macOS、Windows で動作
収集する入力情報
プロファイリングスクリプトを実行する前に、ユーザーから次の情報を収集します。
| 入力 | 説明 | 例 |
|---|---|---|
| シミュレーションログ | 時間情報を含むログファイル | simulation.log |
| スケーリングデータ | 複数回実行したパフォーマンスデータを含む JSON | scaling_data.json |
| シミュレーションパラメーター | メッシュ、場、ソルバー設定を含む JSON | params.json |
| 使用可能なメモリ | システムメモリ(GB)(任意) | 16.0 |
判断の指針
各スクリプトの使い分け
Need to identify slow phases?
├── YES → Use timing_analyzer.py
│ └── Parse simulation logs for timing data
│
Need to understand parallel performance?
├── YES → Use scaling_analyzer.py
│ └── Analyze strong or weak scaling efficiency
│
Need to estimate memory requirements?
├── YES → Use memory_profiler.py
│ └── Estimate memory from problem parameters
│
Need optimization recommendations?
└── YES → Use bottleneck_detector.py
└── Combine analyses and get actionable advice
分析しきい値の選択
| 指標 | 良好 | 許容範囲 | 不良 |
|---|---|---|---|
| フェーズの占有率 | <30% | 30-50% | >50% |
| 並列効率 | >0.80 | 0.70-0.80 | <0.70 |
| メモリ使用量 | <60% | 60-80% | >80% |
スクリプトの出力(JSON フィールド)
すべてのスクリプトは、inputs と results の 2 つのキーを持つトップレベルオブジェクトでペイロードをラップします。以下のフィールドは results の下にあります。
| スクリプト | 主な出力(results の下) |
|---|---|
timing_analyzer.py | results.phases、results.slowest_phase、results.total_time |
scaling_analyzer.py | results.results、results.efficiency_threshold_processors、results.average_efficiency、results.baseline |
memory_profiler.py | results.total_memory_gb、results.per_process_gb、results.field_memory_gb、results.solver_workspace_gb、results.matrix_storage_gb、results.warnings |
bottleneck_detector.py | results.bottlenecks、results.recommendations |
ワークフロー
プロファイリングの全体的なワークフロー
- シミュレーションログから実行時間を分析します
- 複数回実行したデータがある場合は、そこからスケーリングを分析します
- シミュレーションパラメーターからメモリをプロファイリングします
- ボトルネックを検出し、推奨事項を取得します
- 推奨事項に基づいて最適化を実施します
- 改善を検証するために再度プロファイリングします
クイックプロファイリング(実行時間のみ)
- シミュレーションログに対して実行時間アナライザーを実行します
- 支配的なフェーズ(実行時間の >50%)を特定します
- 支配的なフェーズに対して対象を絞った最適化を適用します
CLI の例
実行時間分析
# Basic timing analysis
python3 scripts/timing_analyzer.py \
--log simulation.log \
--json
# Custom timing pattern
python3 scripts/timing_analyzer.py \
--log simulation.log \
--pattern 'Step\s+(\w+)\s+took\s+([\d.]+)s' \
--json
スケーリング分析
# Strong scaling (fixed problem size)
python3 scripts/scaling_analyzer.py \
--data scaling_data.json \
--type strong \
--json
# Weak scaling (constant work per processor)
python3 scripts/scaling_analyzer.py \
--data scaling_data.json \
--type weak \
--json
メモリプロファイリング
# Estimate memory requirements
python3 scripts/memory_profiler.py \
--params simulation_params.json \
--available-gb 16.0 \
--json
ボトルネック検出
# Detect bottlenecks from timing only
python3 scripts/bottleneck_detector.py \
--timing timing_results.json \
--json
# Comprehensive analysis with all inputs
python3 scripts/bottleneck_detector.py \
--timing timing_results.json \
--scaling scaling_results.json \
--memory memory_results.json \
--json
会話型ワークフローの例
ユーザー:シミュレーションに時間がかかりすぎています。遅い箇所を特定するのを手伝ってもらえますか?
エージェントのワークフロー:
- シミュレーションログファイルを求めます
- 実行時間アナライザーを実行します:
python3 scripts/timing_analyzer.py --log simulation.log --json - 結果を解釈します(検出器はソルバー/組み立てフェーズが 50% を超える場合、I/O フェーズが 30% を超える場合にフラグを付けます。70% を超えると重大度が高くなります):
- ソルバーが支配的な場合(>50%、70% 超で高):前処理条件付けの調整を推奨します
- 組み立てが支配的な場合(>50%):キャッシュまたはベクトル化を推奨します
- I/O が支配的な場合(>30%):出力頻度の削減を推奨します
- ユーザーが複数回実行したデータを持っている場合は、スケーリングを分析します:
python3 scripts/scaling_analyzer.py --data scaling.json --type strong --json - 包括的な推奨事項を生成します:
python3 scripts/bottleneck_detector.py --timing timing.json --scaling scaling.json --json
解釈の指針
実行時間分析
検出器は、種類ごとに異なる占有率のしきい値を適用します。ソルバー/組み立て/一般フェーズは実行時間の 50% を超えるとフラグが付き、I/O フェーズは 30% を超えるとフラグが付きます。フラグが付いたフェーズが 70% を超える場合は、重大度が高いと報告されます。
| シナリオ | 意味 | 対応 |
|---|---|---|
| ソルバー >50%(70% 超で高) | ソルバーが支配的 | 前処理条件付けを調整し、許容誤差を確認 |
| 組み立て >50% | 組み立てが支配的 | 行列をキャッシュし、ベクトル化および並列化 |
| I/O >30% | I/O が支配的 | 頻度を下げ、並列 I/O を使用 |
| バランスが取れている(しきい値未満) | バランスが良好 | アルゴリズムの改善点を探す |
スケーリング分析
| 効率 | 意味 | 対応 |
|---|---|---|
| >0.80 | 優れたスケーリング | スケールアップを続ける |
| 0.70-0.80 | 良好なスケーリング | より大きな規模で監視する |
| 0.50-0.70 | スケーリングが不良 | 通信/負荷分散を調査する |
| <0.50 | スケーリングが非常に不良 | プロセッサ数を減らすか、再設計する |
メモリプロファイル
| 使用量 | 意味 | 対応 |
|---|---|---|
| 利用可能量の<60% | 安全 | 対応不要 |
| 利用可能量の60-80% | 中程度 | 監視し、最適化を検討する |
| 利用可能量の>80% | 高い | 解像度を下げるか、プロセッサ数を増やす |
| 利用可能量の>100% | 容量超過 | 問題のサイズを必ず小さくする |
この推定では、3項式 Total = Field + Solver Workspace + Matrix Storage を使用します(references/profiling_guide.md を参照)。行列ストレージとソルバーワークスペースは、solver.type によって異なります。
iterative(デフォルト):スパース行列(デフォルトの7点ステンシル。solver.stencil_nnzで上書き可能)とワークスペースベクトル。direct:保守的なフィルイン係数(solver.fillin_factor、デフォルトは10)でスケーリングしたスパース行列。因数分解時のフィルインを反映します。同じメッシュでは、直接ソルバーは反復ソルバーよりもはるかに多くのメモリを見積もります。matrix-free:組み立て済み行列はなく、ワークスペースベクトルのみです。
この推定は意図的に保守的な値にしているため、「RAMに収まるか」という判断で必要量を過小評価することはありません。
エラー処理
| エラー | 原因 | 解決方法 |
|---|---|---|
Log file not found | パスが無効 | ログファイルのパスを確認する |
No timing data found | パターンが一致しない | --pattern でカスタムパターンを指定する |
At least 2 runs required | データが不足 | スケーリング実行を追加で指定する |
Missing required parameters | パラメーターが不完全 | params ファイルにメッシュとフィールドを追加する |
ボトルネックの種類別の最適化戦略
ソルバーのボトルネック
- 代数的マルチグリッド(AMG)前処理器を使用する
- 過剰に解いている場合は、ソルバーの許容誤差を厳しくする
- 小規模な問題では、直接ソルバーを検討する
- 行列の組み立て時間と求解時間をプロファイルする
組み立てのボトルネック
- ジオメトリが固定されている場合は、要素行列をキャッシュする
- ベクトル化された組み立てルーチンを使用する
- 行列フリー手法を検討する
- 色分けを用いて組み立てを並列化する
I/O のボトルネック
- 出力頻度を下げる
- 並列 I/O(HDF5、MPI-IO)を使用する
- 高速なスクラッチストレージに書き込む
- 出力データを圧縮する
スケーリングのボトルネック
- 通信のオーバーヘッドを調査する
- 負荷の不均衡を確認する
- 同期ポイントを減らす
- 非同期通信を使用する
- ハイブリッド MPI+OpenMP を検討する
メモリのボトルネック
- メッシュの解像度を下げる
- 反復ソルバーを使用する(直接ソルバーよりメモリ使用量が少ない)
- アウトオブコア計算を有効にする
- プロセッサ数を増やす
- 適切な場合は単精度を使用する
検証チェックリスト
プロファイリング結果を信頼したり、推奨事項に基づいて行動したりする前に、以下の具体的な証拠を記録してください。
-
timing_analyzer.pyが実際にエントリーを検出したことを確認しました —results.phasesが空でなく、results.total_time> 0 であることを確認します。カスタムの--patternを使用してresults.message/suggested_patternsが表示された場合は、パターンを修正して再実行します(phasesリストが空だと、シミュレーションが高速だったように見えてしまいます)。 -
phases[].percentageの合計が約100%であり、名前付きフェーズが実時間をカバーしていることを照合しました — 説明できない時間がある場合、実行のバランスが取れていないのではなく、ログ行が不足しています。 - スケーリングに関する主張では、実際のプロセッサ数の範囲にわたる2回以上の実行を使用し、
scaling_analyzer.pyのresults.average_efficiencyとresults.efficiency_threshold_processorsを記録しました。また、実行の生成方法(合計サイズ固定とランクあたりの作業量固定)に--type(strong と weak)が合っていることを確認しました。 -
memory_profiler.pyのメモリ内訳(field_memory_gb、solver_workspace_gb、matrix_storage_gb、total_memory_gb)を記録し、solver.type(iterative/direct/matrix-free)が実際のソルバーと一致することを確認しました — direct ソルバーには約10倍のフィルイン係数が適用されるため、型を誤ると「RAM に収まるか」という判定が危険になります。 -
results.warningsを確認し、total_memory_gb(およびper_process_gb)を実際の--available-gbと比較しました。80%超は、合格ではなく、文書に記載された「高」帯として扱いました。 -
bottleneck_detector.pyの各推奨事項について、根拠となるbottleneck(そのcategory、value、threshold)が、実際に指定したタイミング/スケーリング/メモリの入力と整合していることを確認しました — 推奨事項に反映されるのは、--timing/--scaling/--memoryで渡した JSON ファイルのみです。 - 最適化を実装した後、該当するアナライザーを再実行し、改善前後の
valueを記録して、ボトルネックが実際に移動したことを確認しました(ワークフローの再プロファイリング手順)。
よくある落とし穴と自己正当化
| 安易な近道 | 誤りである理由/すべきこと |
|---|---|
「timing_analyzer.py がボトルネックを返さなかったので、実行のバランスが取れています。」 | 結果が空、または少ない場合は、パターンの不一致が原因であることがよくあります — phases が空、または一部しかない可能性があります。「バランスが取れている」と結論付ける前に、total_time が実時間と一致し、フェーズの割合の合計が約100%であることを確認してください。 |
| 「2回の実行でスケーリングが良好だったので、スケーリングできます。」 | 2点から分かるのは平均効率だけであり、効率がどこで低下するかは分かりません。プロセッサ数を増やして efficiency_threshold_processors を確認し、正しい --type(strong と weak)を使用したことも確かめてください。 |
| 「Iterative と direct の違いはフラグだけなので、メモリはほぼ同じです。」 | memory_profiler.py は direct に保守的な約10倍のフィルイン係数を適用し、matrix-free では行列を保存しません。誤った solver.type を設定すると、RAM を桁違いに過小評価するおそれがあります — 実際のソルバーに合わせて設定してください。 |
「--available-gb の合計には収まるので問題ありません。」 | MPI 実行で重要なのは、プロセスあたりの RAM と比較した per_process_gb であり、合計の80%を超えるとすでに警告が発生します。合計だけでなく、プロセスあたりの値と warnings リストを確認してください。 |
| 「I/O が50%未満なので、I/O はボトルネックではありません。」 | I/O の判定しきい値は50%ではなく、より低い**30%**です。I/O フェーズが30~50%なら、検出器が報告する実際のボトルネックです — 出力頻度を下げるか、並列 I/O を使用してください。 |
| 「推奨事項が前処理条件の調整を指示しているので、問題はソルバーにあります。」 | 推奨事項の網羅性は、渡した JSON の内容に左右されます。--scaling/--memory を省略した場合、それらに関するボトルネックは単に見えません — 優先順位を信頼する前に、利用可能な分析をすべて渡してください。 |
セキュリティ
入力検証
- ユーザー指定の
--pattern正規表現値は長さ(最大500文字)が検証され、壊滅的なバックトラッキングを引き起こしやすい構造(ReDoS)が含まれている場合は拒否されます - スケーリングデータのエントリーは、時間値が有限であること、プロセッサ数が整数であること、実行回数に上限(最大10,000)があることが検証されます
available_gbは正の有限数であることが検証され、メッシュの次元とフィールドパラメーターは正の整数であることが検証されます--type(スケーリングタイプ)は固定の許可リスト(strong、weak)に照らして検証されます- 読み込むすべてのJSONファイルは、ルート要素がオブジェクト(dict)である必要があります
ファイルアクセス
timing_analyzer.pyは--logで指定された単一のログファイルを読み込みます。ログファイルは最大500 MBに制限され、解析前に上限を超えていないか検査されますscaling_analyzer.py、memory_profiler.py、bottleneck_detector.pyは、最大100 MBに制限されたJSONファイルを読み込みます- ログファイルから抽出されたフェーズ名は、エージェントのコンテキストにプロンプトインジェクションのペイロードが伝播するのを防ぐため、200文字に切り詰められ、制御文字が除去されます
- スクリプトはファイルシステムに書き込みません。すべての出力は標準出力に送られます
ツールの制限
- Read:スクリプトのソース、参照資料、シミュレーションログ、結果ファイルの確認に使用します
- Write:プロファイリングレポートや最適化の推奨事項の保存に使用します。書き込み先はユーザーの作業ディレクトリ内に限定されます
- Grep/Glob:ログファイルや結果ファイルの検索、参照資料の検索に使用します
- スキルの
allowed-toolsではBashを除外し、信頼できないシミュレーションログや結果ファイルを処理する際に、エージェントが任意のコマンドを実行するのを防ぎます
安全対策
eval()、exec()、動的なコード生成は使用しません- すべてのサブプロセス呼び出しでは、明示的な引数リストを使用します(
shell=Trueは使用しません) - ツールの範囲を縮小し(Bash なし)、エージェントの操作を読み取りと書き込みのみに限定します
- フェーズ名と診断文字列は、インジェクションを防ぐため、出力に含める前にサニタイズされます
制限事項
- ログ解析:パターンマッチングに依存するため、特殊な形式を検出できない場合があります
- スケーリング分析:有意義な結果を得るには、少なくとも2回の実行が必要です
- メモリ推定:概算であり、実際の使用量とは異なる場合があります
- 推奨事項:一般的な指針であり、ドメイン固有の調整が必要な場合があります
参考資料
references/profiling_guide.md- プロファイリングの概念と解釈references/optimization_strategies.md- 最適化手法の詳細
バージョン履歴
正式な日付入りのリリース履歴については、CHANGELOG.md を参照してください。