BBVは、プログラムの実行特性を分析するための情報で、SimPointでの計算に利用する。QEMUのBBVプラグインを使用してBBVデータを収集する。
BBVプラグインの設定
BBV_PLUGIN := $(QEMU_BUILD_DIR)/contrib/plugins/libbbv.so BBV_DIR := bbv_results
BBV収集の並列実行
run_bbv_<benchmark> ターゲットでは、通常実行と同様に並列化を実装している:
# Run all benchmarks with BBV collection
run_bbv: $(RUN_BBV_TARGETS)
$(RUN_BBV_TARGETS): benchmark=$(subst run_bbv_,,$@)
$(RUN_BBV_TARGETS): run_dir=$(SPEC_ROOT)/benchspec/CPU2006/$(benchmark)/run/run_base_ref_gcc.0000
$(RUN_BBV_TARGETS): bbv_output_dir=$(BBV_DIR)/$(benchmark)
$(RUN_BBV_TARGETS): output_dir=$(RESULT_DIR)/$(benchmark)_bbv
$(RUN_BBV_TARGETS):
@echo "=== Preparing BBV output directory for $(benchmark) ==="
@mkdir -p $(bbv_output_dir)
@mkdir -p $(output_dir)
@subcmds=$$(cd $(run_dir) && $(SPECINVOKE) -n 2>&1 | grep -v "^#" | grep -v "^timer" | grep -v "^$$"); \
num_subcmds=$$(echo "$$subcmds" | wc -l); \
echo "=== Subcommands for $(benchmark) with BBV ($$num_subcmds commands)"; \
bbv_dir_abs=$$(cd $(bbv_output_dir) && pwd); \
output_dir_abs=$$(cd $(output_dir) && pwd); \
export bbv_dir_abs output_dir_abs; \
echo "$$subcmds" | nl -nln | \
parallel --line-buffer --colsep '\t' -j $$num_subcmds \
'cmd_clean=$$(echo {2} | sed "s/ [0-9]*>>* *[^ ]*//g"); \
bbv_file="$$bbv_dir_abs/bbv_{1}.out"; \
output_file="$$output_dir_abs/output_{1}.txt"; \
cmd_with_bbv=$$(echo $$cmd_clean | sed "s|$(QEMU)|$(QEMU) -plugin $(BBV_PLUGIN),outfile=$$bbv_file|"); \
echo "[$(benchmark) BBV {1}/$$num_subcmds] Starting..."; \
(cd $(run_dir) && eval $$cmd_with_bbv > $$output_file 2>&1) && \
echo "[$(benchmark) BBV {1}/$$num_subcmds] Completed - BBV saved to $$bbv_file" || \
echo "[$(benchmark) BBV {1}/$$num_subcmds] Failed"'; \
echo "=== Completed all $(benchmark) BBV collection ==="
通常実行との違いは、QEMUコマンドにBBVプラグインを追加している点:
cmd_with_bbv=$$(echo $$cmd_clean | sed "s|$(QEMU)|$(QEMU) -plugin $(BBV_PLUGIN),outfile=$$bbv_file|")
これにより、各サブコマンドごとに個別のBBVファイルが生成される:
bbv_results/ ├── 400.perlbench/ │ ├── bbv_1.out.0.bb │ ├── bbv_2.out.0.bb │ └── bbv_3.out.0.bb ├── 401.bzip2/ │ ├── bbv_1.out.0.bb │ └── bbv_2.out.0.bb └── ...
SimPointの並列実行
SimPointは、BBVファイルを解析して代表的な実行ポイントを抽出するツール。各BBVファイルに対して独立に実行できるため、並列化が可能。
# Run SimPoint analysis on all benchmarks
run_simpoint: $(RUN_SIMPOINT_TARGETS)
$(RUN_SIMPOINT_TARGETS): benchmark=$(subst run_simpoint_,,$@)
$(RUN_SIMPOINT_TARGETS): bbv_output_dir=$(BBV_DIR)/$(benchmark)
$(RUN_SIMPOINT_TARGETS): simpoint_output_dir=$(SIMPOINT_DIR)/$(benchmark)
$(RUN_SIMPOINT_TARGETS):
@echo "=== Running SimPoint analysis for $(benchmark) ==="
@mkdir -p $(simpoint_output_dir)
@if [ ! -d "$(bbv_output_dir)" ]; then \
echo "Error: BBV directory $(bbv_output_dir) not found. Please run 'make run_bbv_$(benchmark)' first."; \
exit 1; \
fi; \
bbv_files=$$(ls $(bbv_output_dir)/bbv_*.out.*.bb 2>/dev/null); \
if [ -z "$$bbv_files" ]; then \
echo "Error: No BBV files found in $(bbv_output_dir). Please run 'make run_bbv_$(benchmark)' first."; \
exit 1; \
fi; \
echo "$$bbv_files" | \
parallel --line-buffer -j $$(nproc) \
'bbv_file={}; \
base_name=$$(basename $$bbv_file .bb); \
simpoint_out="$(simpoint_output_dir)/$${base_name}.simpoints"; \
weights_out="$(simpoint_output_dir)/$${base_name}.weights"; \
echo "[$(benchmark)] Processing $$bbv_file..."; \
$(SIMPOINT) -loadFVFile $$bbv_file -saveSimpoints $$simpoint_out -saveSimpointWeights $$weights_out -maxK $(SIMPOINT_K) > /dev/null 2>&1; \
if [ -f "$$simpoint_out" ]; then \
echo "[$(benchmark)] SimPoint completed: $$simpoint_out (weights: $$weights_out)"; \
else \
echo "[$(benchmark)] SimPoint failed for $$bbv_file"; \
fi'; \
echo "=== Completed SimPoint analysis for $(benchmark) ==="
ここでは、parallel -j $$(nproc) を使用して、CPUコア数分だけ並列実行している。