-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrun.sh
More file actions
executable file
·199 lines (163 loc) · 5.73 KB
/
Copy pathrun.sh
File metadata and controls
executable file
·199 lines (163 loc) · 5.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#!/usr/bin/env bash
# run.sh — Lab1 一键实验脚本
#
# 用法:
# chmod +x run.sh
# ./run.sh [partA|partB|all] 默认: all
#
# 结果保存在 results/ 目录下
set -euo pipefail
# ------------------------------------------------------------------ #
# Config #
# ------------------------------------------------------------------ #
TESTFILE="partA/testfile"
TESTFILE_SIZE_MB=500
WRITE_TMP="/tmp/lab1_write_tmp"
RESULTS_DIR="results"
PART_B_PORT=8888
PART_B_CLIENTS=100
PART_B_MSG_SIZE=1024
PART_B_MSG_COUNT=500
THREAD_COUNTS=(1 2 4 8 16)
# ------------------------------------------------------------------ #
# Helpers #
# ------------------------------------------------------------------ #
log() { echo "[$(date '+%H:%M:%S')] $*"; }
warn() { echo "[WARN] $*" >&2; }
need_root_for_dropcache() {
if [[ $EUID -eq 0 ]]; then
sync && echo 3 > /proc/sys/vm/drop_caches 2>/dev/null \
&& log "Page cache dropped." \
|| warn "drop_caches not writable (container restriction) — skipping."
else
warn "Not root — skipping drop_caches. Run 'sync && echo 3 | sudo tee /proc/sys/vm/drop_caches' manually for accurate results."
fi
}
require_cmd() {
command -v "$1" >/dev/null 2>&1 || { warn "Command '$1' not found, skipping."; return 1; }
return 0
}
# ------------------------------------------------------------------ #
# Part A #
# ------------------------------------------------------------------ #
run_partA() {
log "=== Part A: UNIX I/O Performance ==="
log "Building Part A..."
make -C partA -s
# Generate test file
if [[ ! -f "$TESTFILE" || $(stat -c%s "$TESTFILE" 2>/dev/null || stat -f%z "$TESTFILE" 2>/dev/null) -lt $((TESTFILE_SIZE_MB * 1024 * 1024 - 1)) ]]; then
log "Generating ${TESTFILE_SIZE_MB}MB test file at $TESTFILE ..."
dd if=/dev/urandom of="$TESTFILE" bs=1M count="$TESTFILE_SIZE_MB" status=progress 2>&1 | tail -1
else
log "Test file already exists ($TESTFILE), skipping generation."
fi
mkdir -p "$RESULTS_DIR"
local out="$RESULTS_DIR/partA_results.txt"
{
echo "Lab1 Part A Results — $(date)"
echo "Kernel: $(uname -r)"
echo "File : $TESTFILE (${TESTFILE_SIZE_MB}MB)"
echo ""
need_root_for_dropcache
echo "=== read() ==="
partA/bench read_bench "$TESTFILE"
echo ""
need_root_for_dropcache
echo "=== getc() ==="
partA/bench getc_bench "$TESTFILE"
echo ""
need_root_for_dropcache
echo "=== fgetc() ==="
partA/bench fgetc_bench "$TESTFILE"
echo ""
need_root_for_dropcache
echo "=== fread() ==="
partA/bench fread_bench "$TESTFILE"
echo ""
need_root_for_dropcache
echo "=== my_fread() ==="
partA/bench myfread_bench "$TESTFILE"
echo ""
echo "=== write() without O_SYNC ==="
partA/bench write_bench "$WRITE_TMP"
echo ""
echo "=== write() with O_SYNC ==="
partA/bench wsync_bench "$WRITE_TMP"
} | tee "$out"
log "Part A results saved to $out"
}
# ------------------------------------------------------------------ #
# Part B #
# ------------------------------------------------------------------ #
run_server_test() {
local name="$1"
local bin="$2"
local extra_args="${3:-}"
local out="$RESULTS_DIR/partB_${name}.txt"
log "--- Testing $name ---"
# Start server in background
# shellcheck disable=SC2086
partB/"$bin" "$PART_B_PORT" $extra_args &
local srv_pid=$!
sleep 0.5 # give server time to bind
{
echo "Server: $name (pid=$srv_pid)"
echo "Date : $(date)"
echo ""
for c in "${PART_B_CLIENTS_LIST[@]}"; do
echo "--- clients=$c ---"
partB/bench_client 127.0.0.1 "$PART_B_PORT" "$c" \
"$PART_B_MSG_SIZE" "$PART_B_MSG_COUNT" 2>&1
echo ""
done
} | tee "$out"
kill "$srv_pid" 2>/dev/null || true
wait "$srv_pid" 2>/dev/null || true
sleep 0.3
log "Results saved to $out"
}
run_partB() {
log "=== Part B: High-Throughput I/O Servers ==="
log "Building Part B..."
make -C partB -s
mkdir -p "$RESULTS_DIR"
# Vary concurrency levels
PART_B_CLIENTS_LIST=(10 50 100 200 500)
# poll server (required)
run_server_test "poll_server" "poll_server"
# thread server — vary thread count
for t in "${THREAD_COUNTS[@]}"; do
run_server_test "thread_server_t${t}" "thread_server" "$t"
done
# epoll server (optional, bonus — Linux only)
if [[ -f "partB/epoll_server" ]]; then
run_server_test "epoll_server" "epoll_server"
else
warn "epoll_server not built, skipping."
fi
# io_uring server (optional, bonus — requires liburing)
if [[ -f "partB/iouring_server" ]]; then
run_server_test "iouring_server" "iouring_server"
else
warn "iouring_server not built (no liburing?), skipping."
fi
log "Part B done. Results in $RESULTS_DIR/"
}
# ------------------------------------------------------------------ #
# Main #
# ------------------------------------------------------------------ #
TARGET="${1:-all}"
case "$TARGET" in
partA) run_partA ;;
partB) run_partB ;;
all)
run_partA
echo ""
run_partB
;;
*)
echo "Usage: $0 [partA|partB|all]"
exit 1
;;
esac
log "All done. Results are in $RESULTS_DIR/"