Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scale frequency to suppress RCU CPU stall warning #67

Draft
wants to merge 9 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,8 @@ rootfs.cpio

# intermediate
riscv-harts.dtsi

# testing
statistic
test.*
utils_bak.c
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
include mk/common.mk

CC ?= gcc
CFLAGS := -O2 -g -Wall -Wextra
CFLAGS := -O2 -g -Wall -Wextra -pg
CFLAGS += -include common.h

# clock frequency
Expand Down Expand Up @@ -78,6 +78,7 @@ E :=
S := $E $E

SMP ?= 1
CFLAGS += -D SEMU_BOOT_TARGET_TIME=10
.PHONY: riscv-harts.dtsi
riscv-harts.dtsi:
$(Q)python3 scripts/gen-hart-dts.py $@ $(SMP) $(CLOCK_FREQ)
Expand Down
19 changes: 19 additions & 0 deletions auto_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env bash

# Create a directory to store logs (optional)
mkdir -p logs

for N in $(seq 1 32); do
echo "============================================="
echo "Starting experiment with SMP=$N"
echo "============================================="

echo "Building and running 'make check SMP=$N'..."
make check SMP=$N 2>&1 | tee "logs/emulator_SMP_${N}.log"

echo "Done with SMP=$N. Logs saved:"
echo " - logs/emulator_SMP_${N}.log"
echo
done

echo "All experiments complete!"
Comment on lines +1 to +19

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding error handling for make

Consider adding error handling for the make check command. If the command fails, it might be helpful to capture the exit status and handle failures appropriately. Could consider adding set -e at the beginning of the script to fail fast on any error.

Code suggestion
Check the AI-generated fix before applying
Suggested change
#!/usr/bin/env bash
# Create a directory to store logs (optional)
mkdir -p logs
for N in $(seq 1 32); do
echo "============================================="
echo "Starting experiment with SMP=$N"
echo "============================================="
echo "Building and running 'make check SMP=$N'..."
make check SMP=$N 2>&1 | tee "logs/emulator_SMP_${N}.log"
echo "Done with SMP=$N. Logs saved:"
echo " - logs/emulator_SMP_${N}.log"
echo
done
echo "All experiments complete!"
#!/usr/bin/env bash
set -e
# Create a directory to store logs (optional)
mkdir -p logs
failed_runs=()
for N in $(seq 1 32); do
echo "============================================="
echo "Starting experiment with SMP=$N"
echo "============================================="
echo "Building and running 'make check SMP=$N'..."
if ! make check SMP=$N 2>&1 | tee "logs/emulator_SMP_${N}.log"; then
failed_runs+=("$N")
fi
echo "Done with SMP=$N. Logs saved:"
echo " - logs/emulator_SMP_${N}.log"
echo
done
if [ ${#failed_runs[@]} -eq 0 ]; then
echo "All experiments completed successfully!"
else
echo "Experiments failed for SMP values: ${failed_runs[*]}"
exit 1
fi

Code Review Run #6023d9


Is this a valid issue, or was it incorrectly flagged by the Agent?

  • it was incorrectly flagged

75 changes: 75 additions & 0 deletions mac_analyze.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#!/usr/bin/env bash
#
# parse_results_macos.sh
#
# Parses log files of the form: emulator_SMP_{N}.log
# Each log ends with lines like:
# [SEMU LOG]: Real boot time: 43.63820 seconds, called 220128512 times semu_timer_clocksource
# [SEMU LOG]: ns_per_call = 4.46425, predict_sec = 8.92851, scale_factor = 1.12001
#
# We output a table with columns:
# 1) SMP
# 2) real_boot_time
# 3) times_called
# 4) ns_per_call
# 5) predict_sec
# 6) scale_factor
#
# We do not parse total_clocksource_ns or percentage, as they do not appear in this log snippet.

LOGDIR="mac_log" # Directory containing emulator_SMP_{N}.log
OUTFILE="results_summary.txt"

# Print a header:
echo -e "SMP\treal_boot_time\ttimes\t\tns_per_call\tpredict_sec\tscale_factor" > "$OUTFILE"

# Iterate from SMP=1..32 (adjust if needed)
for N in $(seq 1 32); do
FILE="$LOGDIR/emulator_SMP_${N}.log"

if [[ ! -f "$FILE" ]]; then
echo "Skipping N=$N, file not found: $FILE"
continue
fi

# Initialize variables
real_boot_time=""
times_called=""
ns_per_call=""
predict_sec=""
scale_factor=""

# 1) Parse the "Real boot time" line:
# Example:
# [SEMU LOG]: Real boot time: 43.63820 seconds, called 220128512 times semu_timer_clocksource
line_boot="$(grep 'Real boot time:' "$FILE")"
if [[ -n "$line_boot" ]]; then
# Remove ANSI color codes, if any
line_no_ansi="$(echo "$line_boot" | sed 's/\x1b\[[0-9;]*m//g')"
# e.g. "[SEMU LOG]: Real boot time: 43.63820 seconds, called 220128512 times semu_timer_clocksource"
# We'll extract:
# real_boot_time = 43.63820
# times = 220128512
real_boot_time="$(echo "$line_no_ansi" | sed -E 's/.*Real boot time: ([0-9.]+) seconds, called ([0-9]+) .*/\1/')"
times_called="$(echo "$line_no_ansi" | sed -E 's/.*Real boot time: ([0-9.]+) seconds, called ([0-9]+) .*/\2/')"
fi

# 2) Parse the "ns_per_call" line:
# Example:
# [SEMU LOG]: ns_per_call = 4.46425, predict_sec = 8.92851, scale_factor = 1.12001
line_ns="$(grep 'ns_per_call =' "$FILE")"
if [[ -n "$line_ns" ]]; then
# Also remove ANSI codes
ns_no_ansi="$(echo "$line_ns" | sed 's/\x1b\[[0-9;]*m//g')"
# e.g. "ns_per_call = 4.46425, predict_sec = 8.92851, scale_factor = 1.12001"
# We'll extract them
ns_per_call="$(echo "$ns_no_ansi" | sed -E 's/.*ns_per_call = ([0-9.]+).*/\1/')"
predict_sec="$(echo "$ns_no_ansi" | sed -E 's/.*predict_sec = ([0-9.]+).*/\1/')"
scale_factor="$(echo "$ns_no_ansi" | sed -E 's/.*scale_factor = ([0-9.]+).*/\1/')"
fi

# 3) Print a line with the data
echo -e "${N}\t${real_boot_time}\t${times_called}\t${ns_per_call}\t${predict_sec}\t${scale_factor}" >> "$OUTFILE"
done

echo "Done. Results saved to ${OUTFILE}."
12 changes: 11 additions & 1 deletion main.c
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,7 @@ static int semu_start(int argc, char **argv)
emu.disk = virtio_blk_init(&(emu.vblk), disk_file);
#endif
/* Set up ACLINT */
semu_timer_init(&emu.mtimer.mtime, CLOCK_FREQ);
semu_timer_init(&emu.mtimer.mtime, CLOCK_FREQ, hart_count);
emu.mtimer.mtimecmp = calloc(vm.n_hart, sizeof(uint64_t));
emu.mswi.msip = calloc(vm.n_hart, sizeof(uint32_t));
emu.sswi.ssip = calloc(vm.n_hart, sizeof(uint32_t));
Expand Down Expand Up @@ -677,7 +677,17 @@ static int semu_start(int argc, char **argv)
return 0;
}

#include <time.h>
#ifdef CLOCK_MONOTONIC_COARSE
#define CLOCKID CLOCK_MONOTONIC_COARSE
#else
#define CLOCKID CLOCK_REALTIME_COARSE
#endif

extern struct timespec boot_begin;

int main(int argc, char **argv)
{
clock_gettime(CLOCK_REALTIME, &boot_begin);
return semu_start(argc, argv);
}
8 changes: 8 additions & 0 deletions riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,14 @@ static void op_sret(hart_t *vm)
vm->s_mode = vm->sstatus_spp;
vm->sstatus_sie = vm->sstatus_spie;

/* After the booting process is complete, initrd will be loaded. At this
* point, the sytstem will switch to U mode for the first time. Therefore,
* by checking whether the switch to U mode has already occurred, we can
* determine if the boot process has been completed.
*/
if (!boot_complete && !vm->s_mode)
boot_complete = true;

/* Reset stack */
vm->sstatus_spp = false;
vm->sstatus_spie = true;
Expand Down
7 changes: 7 additions & 0 deletions statistic/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
1: 13th Gen Intel(R) Core(TM) i7-13700
2: Intel(R) Xeon(R) CPU E5-2640 v4 @ 2.40GHz
3: Intel(R) Core(TM) i7-1065G7 CPU @ 1.30GHz
4: 13th Gen Intel(R) Core(TM) i9-13900H
5: arm (ThunderX2-99xx)
6: mag
7: M2 Pro Max
101 changes: 101 additions & 0 deletions statistic/analyze_results.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#!/usr/bin/env bash
#
# parse_results_new.sh
#
# Parses new logs named "emulator_SMP_{N}.log" (N=1..32). Each log's final lines look like:
#
# [SEMU LOG]: Real boot time: 233.04606 seconds, called 3628365913 times semu_timer_clocksource
# [SEMU LOG]: ns_per_call = 6.26153, predict_sec = 225.41525, scale_factor = 0.04436
# [SEMU LOG]: test_total_clocksource_ns = 92301869299, real_total_clocksource_ns = 46863590994, percentage = 0.20109
# [SEMU LOG]: real_ns_per_call = 12.91589, diff_ns_per_call = 6.65436
#
# We output results_summary.txt with 11 columns in tab-delimited format:
# 1) SMP
# 2) real_boot_time
# 3) times_called
# 4) ns_per_call
# 5) predict_sec
# 6) scale_factor
# 7) total_clocksource_ns
# 8) percentage
# 9) real_ns_per_call
# 10) diff_ns_per_call
#
# We specifically remove any ANSI color codes and ensure each line is a single line, so the output doesn't break.

for TAG in $(seq 1 7); do
BASEDIR="profile-2"
LOGDIR="logs-${TAG}" # Directory containing the log files
OUTFILE="$BASEDIR/results_summary-${TAG}.txt"
Comment on lines +27 to +29

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider making base directory configurable

Consider making the base directory path configurable through an environment variable or command line argument instead of hardcoding BASEDIR="profile-2". This would make the script more flexible and reusable across different environments.

Code suggestion
Check the AI-generated fix before applying
 -  BASEDIR="profile-2"
 -  LOGDIR="logs-${TAG}"
 -  OUTFILE="$BASEDIR/results_summary-${TAG}.txt"
 +  BASEDIR="${BASE_DIR:-profile-2}"
 +  LOGDIR="logs-${TAG}"
 +  OUTFILE="$BASEDIR/results_summary-${TAG}.txt"

Code Review Run #6023d9


Is this a valid issue, or was it incorrectly flagged by the Agent?

  • it was incorrectly flagged


# Print header (11 columns)
echo -e "SMP real_boot_time times_called ns_per_call predict_sec scale_factor total_clocksource_ns percentage real_ns_per_call diff_ns_per_call" > "$OUTFILE"

for N in $(seq 1 32); do
FILE="$BASEDIR/$LOGDIR/emulator_SMP_${N}.log"

if [[ ! -f "$FILE" ]]; then
echo "Skipping N=$N; file not found: $FILE"
continue
fi

# Initialize variables
real_boot_time=""
times_called=""
ns_per_call=""
predict_sec=""
scale_factor=""
total_clocksource_ns=""
percentage=""
real_ns_per_call=""
diff_ns_per_call=""

# A helper function to grep for a specific pattern once, strip ANSI codes, unify line
grep_single_line() {
# Usage: grep_single_line "<pattern>"
# We'll grep for this pattern, take only the first match, remove color codes, unify line
grep -m1 "$1" "$FILE" \
| sed 's/\x1b\[[0-9;]*m//g' \
| tr '\n' ' '
}

# 1) Real boot time line
# e.g. "[SEMU LOG]: Real boot time: 233.04606 seconds, called 3628365913 times semu_timer_clocksource"
line_boot="$(grep_single_line 'Real boot time:')"
if [[ -n "$line_boot" ]]; then
# extract real_boot_time, times_called
real_boot_time="$(echo "$line_boot" | sed -E 's/.*Real boot time: (-?[0-9.]+) seconds, called ([0-9]+) .*/\1/')"
times_called="$(echo "$line_boot" | sed -E 's/.*Real boot time: (-?[0-9.]+) seconds, called ([0-9]+) .*/\2/')"
fi

# 2) ns_per_call line
# e.g.: "[SEMU LOG]: ns_per_call = 6.26153, predict_sec = 225.41525, scale_factor = 0.04436"
line_nscall="$(grep_single_line 'ns_per_call =')"
if [[ -n "$line_nscall" ]]; then
ns_per_call="$(echo "$line_nscall" | sed -E 's/.*ns_per_call = (-?[0-9.]+).*/\1/')"
predict_sec="$(echo "$line_nscall" | sed -E 's/.*predict_sec = (-?[0-9.]+).*/\1/')"
scale_factor="$(echo "$line_nscall" | sed -E 's/.*scale_factor = (-?[0-9.]+).*/\1/')"
fi

# 3) total_clocksource_ns line
# e.g. "[SEMU LOG]: test_total_clocksource_ns = 92301869299, real_total_clocksource_ns = 46863590994, percentage = 0.20109"
line_totals="$(grep_single_line 'total_clocksource_ns =')"
if [[ -n "$line_totals" ]]; then
total_clocksource_ns="$(echo "$line_totals" | sed -E 's/.*total_clocksource_ns = ([0-9]+).*/\1/')"
percentage="$(echo "$line_totals" | sed -E 's/.*percentage = (-?[0-9.]+).*/\1/')"
fi

# 4) real_ns_per_call line
# e.g. "[SEMU LOG]: real_ns_per_call = 12.91589, diff_ns_per_call = 6.65436"
line_realns="$(grep_single_line 'real_ns_per_call =')"
if [[ -n "$line_realns" ]]; then
real_ns_per_call="$(echo "$line_realns" | sed -E 's/.*real_ns_per_call = (-?[0-9.]+).*/\1/')"
diff_ns_per_call="$(echo "$line_realns" | sed -E 's/.*diff_ns_per_call = (-?[0-9.]+).*/\1/')"
fi

# Print a single line with 11 columns in tab-delimited format
echo -e "${N} ${real_boot_time} ${times_called} ${ns_per_call} ${predict_sec} ${scale_factor} ${total_clocksource_ns} ${percentage} ${real_ns_per_call} ${diff_ns_per_call}" >> "$OUTFILE"
done
done

echo "Data parsed and saved to $OUTFILE."
81 changes: 81 additions & 0 deletions statistic/draw.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#!/usr/bin/env bash
#
# plot_results.sh
#
# Generates 7 separate .png plots using gnuplot. Each plot corresponds
# to a particular data column (2..8) from the results_summary_{1..5}.txt files.
# The x-axis is SMP (column 1), and the y-axis is the chosen data column.
#
# The files are assumed to be:
# results_summary_1.txt
# results_summary_2.txt
# results_summary_3.txt
# results_summary_4.txt
# results_summary_5.txt
#
# Each file has at least these columns:
# 1) SMP
# 2) real_boot_time
# 3) times
# 4) ns_per_call
# 5) predict_sec
# 6) scale_factor
# 7) percentage
# 8) real_ns_per_call
#
# Usage:
# ./plot_results.sh
# It will produce 7 PNG images, e.g. real_boot_time.png, times.png, etc.

# A small map from column index to a more descriptive name (for file titles).
declare -A COLTITLE=(
[2]="real_boot_time"
[3]="times"
[4]="ns_per_call"
[5]="predict_sec"
[6]="scale_factor"
[7]="percentage"
[8]="real_ns_per_call"
)

# Check if gnuplot is installed
command -v gnuplot >/dev/null 2>&1 || {
echo "Error: gnuplot is not installed or not in PATH."
exit 1
}

# Loop over the data columns we want to plot
for col in 2 3 4 5 6 7 8; do
title="${COLTITLE[$col]}"

echo "Generating plot for column $col -> $title"

gnuplot -persist <<EOF
set title "$title vs SMP"
set xlabel "SMP"
set ylabel "$title"
set key left top
set grid

# Output a PNG figure sized 800x600
set term pngcairo size 800,600
set output "${title}.png"

# Skip the header row with 'skip=1'
# We assume each file has a header line, so 'using 1:$col' means:
# x = column 1 (SMP)
# y = column $col (the data we want)
#
# Each line is for a different environment's file.
plot \
"results_summary_1.txt" using 1:$col skip 1 with linespoints title "Env1", \
"results_summary_2.txt" using 1:$col skip 1 with linespoints title "Env2", \
"results_summary_3.txt" using 1:$col skip 1 with linespoints title "Env3", \
"results_summary_4.txt" using 1:$col skip 1 with linespoints title "Env4", \
"results_summary_5.txt" using 1:$col skip 1 with linespoints title "Env5"

EOF

done

echo "All plots generated! Look for *.png in the current directory."
Loading