From 278073707f1fb1277f8dedb46377d98359d56af1 Mon Sep 17 00:00:00 2001 From: lc <18783417278@163.com> Date: Wed, 27 May 2026 19:42:29 +0800 Subject: [PATCH] =?UTF-8?q?=E8=84=9A=E6=9C=AC=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +- doc/lab3-进度.md | 5 ++-- scripts/test_lab3_final.sh | 46 +++++++++++++++++++++-------- scripts/verify_asm.sh | 59 +++++++++++++++++++++++++++++++------- 4 files changed, 87 insertions(+), 26 deletions(-) diff --git a/.gitignore b/.gitignore index 3f53e35..0c809bd 100644 --- a/.gitignore +++ b/.gitignore @@ -71,4 +71,5 @@ Thumbs.db test/test_result/ sema_check -.codex \ No newline at end of file +.codex +memory.md diff --git a/doc/lab3-进度.md b/doc/lab3-进度.md index 288b576..835bfc1 100644 --- a/doc/lab3-进度.md +++ b/doc/lab3-进度.md @@ -37,8 +37,8 @@ - 修复了混合参数(`int/ptr` 与 `float`)场景下寄存器编号错误的问题,按 AArch64 规则分别为 GPR/FPR 计数分配。 - 调用点新增栈参数区的 16 字节对齐分配与回收。 - **测试链路健壮性(本次更新)**: - - `verify_asm.sh` 新增 QEMU 执行超时控制(默认 90 秒,可通过 `SY_QEMU_TIMEOUT` 覆盖)。 - - `test_lab3_final.sh` 默认设置 `SY_QEMU_TIMEOUT=180`,避免性能样例导致整轮测试卡死。 + - `verify_asm.sh` 新增 QEMU 执行超时控制(默认 600 秒,可通过 `SY_QEMU_TIMEOUT` 覆盖)。 + - `test_lab3_final.sh` 默认设置 `SY_QEMU_TIMEOUT=600`,避免性能样例导致整轮测试卡死。 ## 4. 遗留问题与不足 @@ -74,4 +74,5 @@ cmake --build build -j "$(nproc)" ```bash # 格式:./scripts/verify_asm.sh <.sy文件> <结果目录> --run ./scripts/verify_asm.sh test/test_case/functional/simple_add.sy test/test_result/manual --run +./scripts/verify_asm.sh test/test_case/performance/2025-MYO-20.sy test/test_result/manual --run ``` diff --git a/scripts/test_lab3_final.sh b/scripts/test_lab3_final.sh index f739597..c957c27 100755 --- a/scripts/test_lab3_final.sh +++ b/scripts/test_lab3_final.sh @@ -10,7 +10,7 @@ PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" COMPILER="$PROJECT_ROOT/build/bin/compiler" VERIFY_ASM="$SCRIPT_DIR/verify_asm.sh" RESULT_DIR="$PROJECT_ROOT/test/test_result/lab3_final" -export SY_QEMU_TIMEOUT="${SY_QEMU_TIMEOUT:-180}" +export SY_QEMU_TIMEOUT="${SY_QEMU_TIMEOUT:-600}" # 颜色输出 RED='\033[0;31m' @@ -63,6 +63,22 @@ PERFORMANCE_CASES=( passed=0 failed=0 failed_list=() +total_elapsed_ms=0 + +now_ms() { + local ns + ns=$(date +%s%N 2>/dev/null || true) + if [[ "$ns" =~ ^[0-9]+$ ]]; then + printf '%s\n' "$((ns / 1000000))" + else + printf '%s000\n' "$(date +%s)" + fi +} + +format_ms() { + local ms=$1 + printf '%d.%03ds' "$((ms / 1000))" "$((ms % 1000))" +} # 3. 测试函数 run_test() { @@ -70,6 +86,10 @@ run_test() { local type=$2 local full_path="$PROJECT_ROOT/$sy_file" local base=$(basename "$sy_file") + local log_file="$RESULT_DIR/$base.log" + local start_ms + local end_ms + local elapsed_ms echo -n "[$type] 测试 $base ... " @@ -80,19 +100,20 @@ run_test() { # 调用官方脚本进行验证 # 使用绝对路径,彻底避免路径解析问题 - if "$VERIFY_ASM" "$full_path" "$RESULT_DIR" --run > /dev/null 2>&1; then - echo -e "${GREEN} 通过${NC}" + start_ms=$(now_ms) + if "$VERIFY_ASM" "$full_path" "$RESULT_DIR" --run > "$log_file" 2>&1; then + end_ms=$(now_ms) + elapsed_ms=$((end_ms - start_ms)) + total_elapsed_ms=$((total_elapsed_ms + elapsed_ms)) + echo -e "${GREEN} 通过${NC} ($(format_ms "$elapsed_ms"))" ((passed++)) || true else - # 特殊处理已知的问题用例 - if [[ "$base" == "2025-MYO-20.sy" ]]; then - echo -e "${YELLOW}! 逻辑正确但库函数参数不兼容 (已知问题)${NC}" - ((passed++)) || true - else - echo -e "${RED} 失败${NC}" - ((failed++)) || true - failed_list+=("$base") - fi + end_ms=$(now_ms) + elapsed_ms=$((end_ms - start_ms)) + total_elapsed_ms=$((total_elapsed_ms + elapsed_ms)) + echo -e "${RED} 失败${NC} ($(format_ms "$elapsed_ms"))" + ((failed++)) || true + failed_list+=("$base") fi } @@ -110,6 +131,7 @@ echo -e "${BLUE}=========================================================${NC}" echo -e "总用例数: 21" echo -e "通过数量: ${GREEN}$passed${NC}" echo -e "失败数量: ${RED}$failed${NC}" +echo -e "总耗时: $(format_ms "$total_elapsed_ms")" if [[ $failed -gt 0 ]]; then echo -e "\n${RED}失败用例列表:${NC}" diff --git a/scripts/verify_asm.sh b/scripts/verify_asm.sh index 1c45d13..dcfe3bc 100755 --- a/scripts/verify_asm.sh +++ b/scripts/verify_asm.sh @@ -40,10 +40,47 @@ if [[ ! -x "$compiler" ]]; then exit 1 fi -if ! command -v aarch64-linux-gnu-gcc >/dev/null 2>&1; then - echo "未找到 aarch64-linux-gnu-gcc,无法汇编/链接。" >&2 +now_ms() { + local ns + ns=$(date +%s%N 2>/dev/null || true) + if [[ "$ns" =~ ^[0-9]+$ ]]; then + printf '%s\n' "$((ns / 1000000))" + else + printf '%s000\n' "$(date +%s)" + fi +} + +format_ms() { + local ms=$1 + printf '%d.%03ds' "$((ms / 1000))" "$((ms % 1000))" +} + +link_aarch64() { + local asm_file=$1 + local sylib=$2 + local exe=$3 + + if command -v aarch64-linux-gnu-gcc >/dev/null 2>&1; then + if [[ -f "$sylib" ]]; then + aarch64-linux-gnu-gcc "$asm_file" "$sylib" -o "$exe" + else + aarch64-linux-gnu-gcc "$asm_file" -o "$exe" + fi + return + fi + + if command -v clang >/dev/null 2>&1; then + if [[ -f "$sylib" ]]; then + clang --target=aarch64-linux-gnu "$asm_file" "$sylib" -o "$exe" + else + clang --target=aarch64-linux-gnu "$asm_file" -o "$exe" + fi + return + fi + + echo "未找到 AArch64 链接工具:需要 aarch64-linux-gnu-gcc,或支持 --target=aarch64-linux-gnu 的 clang。" >&2 exit 1 -fi +} mkdir -p "$out_dir" base=$(basename "$input") @@ -60,11 +97,7 @@ SYLIB="$SCRIPT_DIR/../sylib/sylib.c" "$compiler" --emit-asm "$input" > "$asm_file" echo "汇编已生成: $asm_file" -if [[ -f "$SYLIB" ]]; then - aarch64-linux-gnu-gcc "$asm_file" "$SYLIB" -o "$exe" -else - aarch64-linux-gnu-gcc "$asm_file" -o "$exe" -fi +link_aarch64 "$asm_file" "$SYLIB" "$exe" echo "可执行文件已生成: $exe" if [[ "$run_exec" == true ]]; then @@ -75,11 +108,12 @@ if [[ "$run_exec" == true ]]; then stdout_file="$out_dir/$stem.stdout" actual_file="$out_dir/$stem.actual.out" - run_timeout="${SY_QEMU_TIMEOUT:-90}" - echo "运行 $exe ..." + run_timeout="${SY_QEMU_TIMEOUT:-600}" + echo "运行 $exe ... (timeout: ${run_timeout}s)" set +e ulimit -s unlimited 2>/dev/null || true export QEMU_STACK_SIZE=67108864 + run_start_ms=$(now_ms) if command -v timeout >/dev/null 2>&1; then if [[ -f "$stdin_file" ]]; then timeout "${run_timeout}s" qemu-aarch64 -L /usr/aarch64-linux-gnu "$exe" < "$stdin_file" > "$stdout_file" @@ -94,11 +128,14 @@ if [[ "$run_exec" == true ]]; then fi fi status=$? + run_end_ms=$(now_ms) + run_elapsed_ms=$((run_end_ms - run_start_ms)) set -e if [[ $status -eq 124 ]]; then - echo "运行超时: ${run_timeout}s" >&2 + echo "运行超时: ${run_timeout}s,耗时: $(format_ms "$run_elapsed_ms")" >&2 exit 124 fi + echo "运行耗时: $(format_ms "$run_elapsed_ms")" cat "$stdout_file" echo "退出码: $status" {