forked from ppxf25tqu/nudt-compiler-cpp
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
148 lines
4.5 KiB
148 lines
4.5 KiB
#!/usr/bin/env bash
|
|
# 优化效果对比:测量 O0 vs O1 的编译时间和运行时间
|
|
# 用法: bash scripts/bench_ir.sh [--test-dir=<dir>] [--result-dir=<dir>]
|
|
|
|
set -uo pipefail
|
|
|
|
PROJECT_ROOT=$(cd "$(dirname "$0")/.." ; pwd)
|
|
TEST_CASE_DIR="${PROJECT_ROOT}/test/test_case"
|
|
RESULT_DIR="${PROJECT_ROOT}/test/test_result/bench"
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--test-dir=*) TEST_CASE_DIR="${1#*=}" ;;
|
|
--result-dir=*) RESULT_DIR="${1#*=}" ;;
|
|
*) echo "未知参数: $1" >&2; exit 1 ;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
compiler="${PROJECT_ROOT}/build/bin/compiler"
|
|
[[ -x "$compiler" ]] || { echo "错误:未找到编译器 $compiler" >&2; exit 1; }
|
|
command -v llc >/dev/null 2>&1 || { echo "错误:未找到 llc" >&2; exit 1; }
|
|
command -v clang >/dev/null 2>&1 || { echo "错误:未找到 clang" >&2; exit 1; }
|
|
|
|
mkdir -p "$RESULT_DIR"
|
|
|
|
# 时间测量:使用 date +%s.%N
|
|
now() { date +%s.%N; }
|
|
elapsed() { python3 -c "print(f'{float($2)-float($1):.4f}')" 2>/dev/null || awk "BEGIN{printf \"%.4f\\n\",$2-$1}"; }
|
|
|
|
summary_file="${RESULT_DIR}/summary.csv"
|
|
echo "test,opt,compile_s,exec_s,compile+exec_s" > "$summary_file"
|
|
|
|
total=0
|
|
o0_ct_total=0; o1_ct_total=0
|
|
o0_et_total=0; o1_et_total=0
|
|
|
|
echo "=== 优化效果对比 O0 vs O1 ==="
|
|
echo ""
|
|
|
|
while read -r test_file; do
|
|
full_path=$(readlink -f "$test_file")
|
|
tcdir=$(readlink -f "$TEST_CASE_DIR")
|
|
rel="${full_path#$tcdir}"
|
|
[[ "${rel:0:1}" != "/" ]] && rel="/$rel"
|
|
|
|
base=$(basename "$test_file")
|
|
stem="${base%.sy}"
|
|
idir=$(dirname "$test_file")
|
|
stdin="${idir}/${stem}.in"
|
|
expected="${idir}/${stem}.out"
|
|
|
|
total=$((total+1))
|
|
printf "[%4d] %s" "$total" "$rel"
|
|
|
|
o0_ll="${RESULT_DIR}/O0/${rel%.sy}.ll"
|
|
o1_ll="${RESULT_DIR}/O1/${rel%.sy}.ll"
|
|
mkdir -p "$(dirname "$o0_ll")" "$(dirname "$o1_ll")"
|
|
|
|
# --- 编译 O0 ---
|
|
t1=$(now)
|
|
"$compiler" "$test_file" -IR -o "$o0_ll" 2>/dev/null; rc0=$?
|
|
t2=$(now)
|
|
if [[ $rc0 -ne 0 ]]; then
|
|
echo " | O0编译失败"
|
|
echo "$stem,O0,-,-,-" >> "$summary_file"
|
|
echo "$stem,O1,-,-,-" >> "$summary_file"
|
|
continue
|
|
fi
|
|
o0_ct=$(elapsed "$t1" "$t2")
|
|
|
|
# --- 编译 O1 ---
|
|
t1=$(now)
|
|
"$compiler" "$test_file" -IR -o "$o1_ll" -O1 2>/dev/null; rc1=$?
|
|
t2=$(now)
|
|
if [[ $rc1 -ne 0 ]]; then
|
|
echo " | O1编译失败"
|
|
echo "$stem,O0,$o0_ct,-,-" >> "$summary_file"
|
|
echo "$stem,O1,-,-,-" >> "$summary_file"
|
|
continue
|
|
fi
|
|
o1_ct=$(elapsed "$t1" "$t2")
|
|
|
|
# --- llc + clang O0 ---
|
|
o0_obj="${RESULT_DIR}/O0/${stem}.o"
|
|
o1_obj="${RESULT_DIR}/O1/${stem}.o"
|
|
o0_exe="${RESULT_DIR}/O0/${stem}.exe"
|
|
o1_exe="${RESULT_DIR}/O1/${stem}.exe"
|
|
|
|
llc -filetype=obj "$o0_ll" -o "$o0_obj" 2>/dev/null
|
|
llc -filetype=obj "$o1_ll" -o "$o1_obj" 2>/dev/null
|
|
clang "$o0_obj" "${PROJECT_ROOT}/sylib/sylib.c" -o "$o0_exe" -lm 2>/dev/null
|
|
clang "$o1_obj" "${PROJECT_ROOT}/sylib/sylib.c" -o "$o1_exe" -lm 2>/dev/null
|
|
|
|
# --- 运行 O0 ---
|
|
t1=$(now)
|
|
sr0=0
|
|
if [[ -f "$stdin" ]]; then
|
|
(ulimit -s unlimited; "$o0_exe" < "$stdin") > /dev/null 2>&1 || sr0=$?
|
|
else
|
|
(ulimit -s unlimited; "$o0_exe") > /dev/null 2>&1 || sr0=$?
|
|
fi
|
|
t2=$(now)
|
|
o0_et=$(elapsed "$t1" "$t2")
|
|
|
|
# --- 运行 O1 ---
|
|
t1=$(now)
|
|
sr1=0
|
|
if [[ -f "$stdin" ]]; then
|
|
(ulimit -s unlimited; "$o1_exe" < "$stdin") > /dev/null 2>&1 || sr1=$?
|
|
else
|
|
(ulimit -s unlimited; "$o1_exe") > /dev/null 2>&1 || sr1=$?
|
|
fi
|
|
t2=$(now)
|
|
o1_et=$(elapsed "$t1" "$t2")
|
|
|
|
# 验证一致性
|
|
flag=""
|
|
if [[ $sr0 -ne $sr1 ]]; then
|
|
flag=" EXIT:O0=$sr0 O1=$sr1"
|
|
fi
|
|
|
|
# 累计 & 比率
|
|
o0_ct_total=$(awk "BEGIN{printf \"%.4f\",$o0_ct_total+$o0_ct}")
|
|
o1_ct_total=$(awk "BEGIN{printf \"%.4f\",$o1_ct_total+$o1_ct}")
|
|
o0_et_total=$(awk "BEGIN{printf \"%.4f\",$o0_et_total+$o0_et}")
|
|
o1_et_total=$(awk "BEGIN{printf \"%.4f\",$o1_et_total+$o1_et}")
|
|
|
|
cspd=$(awk "BEGIN{if($o1_ct>0)printf \"%.1fx\",$o0_ct/$o1_ct; else print \"-\"}")
|
|
espd=$(awk "BEGIN{if($o1_et>0)printf \"%.1fx\",$o0_et/$o1_et; else print \"-\"}")
|
|
|
|
printf " | 编译 O0:%.4fs O1:%.4fs(%s) 运行 O0:%.4fs O1:%.4fs(%s)%s\n" \
|
|
"$o0_ct" "$o1_ct" "$cspd" "$o0_et" "$o1_et" "$espd" "$flag"
|
|
|
|
echo "$stem,O0,$o0_ct,$o0_et,$(awk "BEGIN{printf \"%.4f\",$o0_ct+$o0_et}")" >> "$summary_file"
|
|
echo "$stem,O1,$o1_ct,$o1_et,$(awk "BEGIN{printf \"%.4f\",$o1_ct+$o1_et}")" >> "$summary_file"
|
|
|
|
done < <(find "$TEST_CASE_DIR" -name "*.sy" | sort)
|
|
|
|
echo ""
|
|
echo "============================================"
|
|
echo "总用例: $total"
|
|
echo "O0 编译总耗时: ${o0_ct_total}s"
|
|
echo "O1 编译总耗时: ${o1_ct_total}s"
|
|
echo "O0 运行总耗时: ${o0_et_total}s"
|
|
echo "O1 运行总耗时: ${o1_et_total}s"
|
|
echo "CSV: $summary_file"
|