Skip to content

Commit de55466

Browse files
committed
Switch to frequency/throughput-based testing for test-cdeque
1 parent 4ce7a56 commit de55466

File tree

6 files changed

+119
-208
lines changed

6 files changed

+119
-208
lines changed

libworkstream_df/benchmark-cdeque.sh

+28-80
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
1-
breadth=3
2-
depth=15
1+
b=3
2+
d=15
3+
mu=$(awk "BEGIN{print ($b ^ $d) / 10}")
34
nthread=2
4-
niter=40
5-
while getopts b:d:n:ps:t: opt; do
5+
niter=200
6+
while getopts b:d:f:n:pt: opt; do
67
case $opt in
78
b)
8-
breadth=$OPTARG
9+
b=$OPTARG
910
;;
1011
d)
11-
depth=$OPTARG
12+
d=$OPTARG
13+
;;
14+
f)
15+
mu=$OPTARG
1216
;;
1317
n)
1418
nthread=$OPTARG
@@ -22,81 +26,25 @@ while getopts b:d:n:ps:t: opt; do
2226
done
2327
shift $((OPTIND - 1))
2428

25-
tune()
26-
{
27-
echo tuning $t $testargs -s $2 >&2
28-
awk -f tune-test-cdeque.awk $1 "$t $testargs" $2 $nsteal $nthread
29-
}
30-
31-
iter()
32-
{
33-
for i in `seq 1 $1`; do
34-
if [ $3 ]; then
35-
farg="-f $3"
36-
else
37-
farg=
38-
fi
39-
$t $testargs -s $2 $farg | tail -n 1
40-
done
41-
}
29+
tests='test-cdeque test-cdeque-nofences test-cdeque-c11 test-cdeque-dumbc11'
30+
testargs="-b $b -d $d -n $nthread"
4231

43-
run()
44-
{
45-
log=$t.$nthread.$b.$d.$1.log
46-
f=$(tune 15 $1)
47-
if [ $dry ]; then
48-
echo $t $testargs -s $1 -f $f
49-
$t $testargs -s $1 -f $f
50-
else
51-
echo $t $testargs -s $1 -f $f \> $log >&2
52-
iter $niter $1 $f >$log
53-
fi
32+
awk -v ni=$niter -v mu=$mu '
33+
BEGIN {
34+
for (i = 1; i <= ni; ++i)
35+
print -log(rand()) * mu
5436
}
37+
' >rand.$$
5538

56-
do_tree()
57-
{
58-
b=$1
59-
d=$2
60-
nsteal=$(awk -v b=$b -v d=$d '
61-
BEGIN {
62-
total = 0
63-
if (b == 1)
64-
total = d
65-
else {
66-
row = b
67-
for (i = 0; i < d; ++i) {
68-
row *= b
69-
total += row
70-
}
71-
}
72-
print total
73-
}
74-
')
75-
echo jobs $nsteal >&2
76-
77-
tests='./test-cdeque ./test-cdeque-nofences ./test-cdeque-c11 ./test-cdeque-dumbc11'
78-
testargs="-b $b -d $d -n $nthread"
79-
80-
for t in $tests; do
81-
echo $t prerun >&2
82-
[ $dry ] || iter 10 0 >/dev/null
83-
f=0
84-
run 0
85-
s=1
86-
n10=$((nsteal / 10))
87-
while [ $s -lt $n10 ]; do
88-
if [ $s -lt $((nthread * 10)) ]; then
89-
echo skipping $t $testargs -s $s >&2
90-
else
91-
run $s
92-
fi
93-
s=$((s * 10))
94-
done
95-
for sratio10 in 1 2 4 6 8; do
96-
s=$((sratio10 * nsteal / 10))
97-
run $s
98-
done
39+
for t in $tests; do
40+
echo $t prerun >&2
41+
for i in $(seq 1 10); do
42+
[ $dry ] || ./$t $testargs -f 0 | tail -n 1 >/dev/null
9943
done
100-
}
101-
102-
do_tree $breadth $depth
44+
log=freq.$t.$nthread.$b.$d.log
45+
while read x; do
46+
f=$(awk "BEGIN{print $x / ($nthread-1)}")
47+
echo $t $testargs -f $f >&2 \>\> $log
48+
[ $dry ] || ./$t $testargs -f $f | tail -n 1 >>$log
49+
done <rand.$$
50+
done

libworkstream_df/plot-benchmark-cdeque.sh

+43-42
Original file line numberDiff line numberDiff line change
@@ -23,53 +23,54 @@ plot()
2323
{
2424
gnuplot - <<EOF
2525
set terminal $type
26+
set xlabel '$4'
27+
set ylabel '$5'
2628
set output '$1.$n.$b.$d.$type'
27-
plot '$1.$n.$b.$d.data' title 'native' w lines, \\
28-
'$1-nofences.$n.$b.$d.data' title 'nofences' w lines, \\
29-
'$1-c11.$n.$b.$d.data' title 'c11' w lines, \\
30-
'$1-dumbc11.$n.$b.$d.data' title 'seqcst' w lines
29+
set title '$3 (n=$n; b=$b; d=$d)'
30+
plot '$1.$n.$b.$d.data' title 'native' w $2, \\
31+
'$1-nofences.$n.$b.$d.data' title 'nofences' w $2, \\
32+
'$1-c11.$n.$b.$d.data' title 'c11' w $2, \\
33+
'$1-dumbc11.$n.$b.$d.data' title 'seqcst' w $2
3134
set output '$1.$n.$b.$d.log.$type'
35+
set title '$3 (n=$n; b=$b; d=$d; log)'
3236
set log x
33-
plot '$1.$n.$b.$d.data' title 'native' w lines, \\
34-
'$1-nofences.$n.$b.$d.data' title 'nofences' w lines, \\
35-
'$1-c11.$n.$b.$d.data' title 'c11' w lines, \\
36-
'$1-dumbc11.$n.$b.$d.data' title 'seqcst' w lines
37+
plot '$1.$n.$b.$d.data' title 'native' w $2, \\
38+
'$1-nofences.$n.$b.$d.data' title 'nofences' w $2, \\
39+
'$1-c11.$n.$b.$d.data' title 'c11' w $2, \\
40+
'$1-dumbc11.$n.$b.$d.data' title 'seqcst' w $2
3741
EOF
3842
}
3943

4044
tests='test-cdeque test-cdeque-nofences test-cdeque-c11 test-cdeque-dumbc11'
4145

42-
for t in $tests; do
43-
for log in $t.$n.$b.$d.*.log; do
44-
s=${log%.log}
45-
s=${s##*.}
46-
awk "{x+=\$1;++n} END{print $s, x/n}" $log
47-
done | sort -n >$t.$n.$b.$d.data
48-
done
49-
plot test-cdeque
50-
51-
for t in $tests; do
52-
for log in $t.$n.$b.$d.*.log; do
53-
s=${log%.log}
54-
s=${s##*.}
55-
if [ $s -eq 0 ]; then
56-
echo 0 1.0
57-
else
58-
awk "{x+=\$(NF-4)/\$NF;++n} END{print $s, x/n}" $log
59-
fi
60-
done | sort -n >steal.$t.$n.$b.$d.data
61-
done
62-
plot steal.test-cdeque
63-
64-
for t in $tests; do
65-
for log in $t.$n.$b.$d.*.log; do
66-
s=${log%.log}
67-
s=${s##*.}
68-
if [ $s -eq 0 ]; then
69-
echo 0 1.0
70-
else
71-
awk "{x+=\$(NF-4)/\$1;++n} END{print $s, x/n}" $log
72-
fi
73-
done | sort -n >stealtime.$t.$n.$b.$d.data
74-
done
75-
plot stealtime.test-cdeque
46+
if [ -n "$(find . -maxdepth 1 -name "test-*.$n.$b.$d.log")" ]; then
47+
for t in $tests; do
48+
awk '{print $NF, $1}' $t.$n.$b.$d.log |
49+
sort -n >time.$t.$n.$b.$d.data
50+
done
51+
plot time.test-cdeque points \
52+
'Execution time' \
53+
'effective steals' 'execution time (s)'
54+
for t in $tests; do
55+
awk '{print $(NF-2), $1}' $t.$n.$b.$d.log |
56+
sort -n >time_exp_tput.$t.$n.$b.$d.data
57+
done
58+
plot time_exp_tput.test-cdeque points \
59+
'Execution time' \
60+
'expected steal throughput (s⁻¹)' 'execution time (s)'
61+
for t in $tests; do
62+
awk '{print $NF/$1, $1}' $t.$n.$b.$d.log |
63+
sort -n >time_eff_tput.$t.$n.$b.$d.data
64+
done
65+
plot time_eff_tput.test-cdeque points \
66+
'Execution time' \
67+
'effective steal throughput (s⁻¹)' 'execution time (s)'
68+
for t in $tests; do
69+
awk '{print $NF/$1, 2*$(NF-3)/$1}' $t.$n.$b.$d.log |
70+
sort -n >tput_eff_tput.$t.$n.$b.$d.data
71+
done
72+
plot tput_eff_tput.test-cdeque points \
73+
'Critical path throughput' \
74+
'effective steal throughput (s⁻¹)' \
75+
'push/take throughput (s⁻¹)'
76+
fi

libworkstream_df/stat-benchmark-cdeque.sh

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ for log in test-cdeque*.log; do
1111
mean=$(awk '{x+=$1;++n} END{print x/n}' $log)
1212
stddev=$(awk -v m=$mean '{x+=($1-m)^2;++n} END{print sqrt(x/n)}' $log)
1313
maxdev=$(awk -v m=$mean '{x=($1-m)^2} x>u{u=x} END{print sqrt(u)}' $log)
14-
thief_avg=$(awk '{for(i=1;i<=NF-5;++i){x+=$i;++n}} END{print x/n}' $log)
14+
thief_avg=$(awk '{for(i=1;i<=NF-6;++i){x+=$i;++n}} END{print x/n}' $log)
1515
thief_avgerr90=$(awk \
16-
'{for(i=1;i<=NF-5;++i){x+=$i/(0.9*$1);++n}} END{print x/n}' \
16+
'{for(i=1;i<=NF-6;++i){x+=$i/(0.9*$1);++n}} END{print x/n}' \
1717
$log)
1818
steal_avg=$(awk '{x+=$(NF-1)==0?0:$NF/$(NF-1);++n} END{print x/n}' $log)
19-
steal_avgok=$(awk '{x+=$NF==0?0:$(NF-4)/$NF;++n} END{print x/n}' $log)
19+
steal_avgok=$(awk '{x+=$NF==0?0:$(NF-5)/$NF;++n} END{print x/n}' $log)
2020
printf '%-25s\t%-9g\t%-9g\t%-9g\t%-9g\t%-9g\t%-9g\t%g\n' \
2121
$label \
2222
$mean $stddev $maxdev \

libworkstream_df/test-cdeque.c

+33-19
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ static void *worker_main (void *);
4545
static void worker (struct state *, unsigned long);
4646
static void straight_worker (struct state *, unsigned long);
4747
static void *thief_main (void *);
48+
static bool do_steal (struct state *, double *);
4849

4950
static void *
5051
worker_main (void *data)
@@ -119,39 +120,51 @@ static void *
119120
thief_main (void *data)
120121
{
121122
struct state *state = data;
122-
void *val;
123-
double stealprob;
124-
unsigned long i;
123+
double lasttime;
125124

126125
while (!atomic_load_explicit (&start, memory_order_acquire))
127126
continue;
128127

129128
BEGIN_TIME (&state->time);
130129

131-
if (steal_freq > 0.0)
132-
stealprob = steal_freq;
133-
else
134-
stealprob = (double) num_steal_per_thread / num_job;
135-
for (i = 0; i < num_steal_per_thread; ++i)
130+
lasttime = get_thread_cpu_time ();
131+
while (state->num_attempt < num_steal_per_thread)
132+
{
133+
if (!do_steal (state, &lasttime))
134+
break;
135+
}
136+
137+
END_TIME (&state->time);
138+
139+
return NULL;
140+
}
141+
142+
static bool
143+
do_steal (struct state *state, double *plasttime)
144+
{
145+
double curtime;
146+
unsigned long i, ndue;
147+
void *val;
148+
149+
curtime = get_thread_cpu_time ();
150+
ndue = (unsigned long) ((curtime - *plasttime) * steal_freq);
151+
if (ndue == 0)
152+
return !atomic_load_explicit (&end, memory_order_acquire);
153+
*plasttime = curtime;
154+
for (i = 0; i < ndue; ++i)
136155
{
137-
/* Minimal probability is actually 1/RAND_MAX. */
138-
while ((double) rand_r (&state->seed) / RAND_MAX > stealprob)
139-
continue;
140156
val = cdeque_steal (worker_deque);
141157
if (val == NULL)
142158
++state->num_failed_attempt;
143159
if (atomic_load_explicit (&end, memory_order_acquire))
144160
{
145161
if (num_steal_per_thread == (unsigned long) -1)
146-
break;
162+
return false;
147163
}
148164
else
149165
++state->num_attempt;
150166
}
151-
152-
END_TIME (&state->time);
153-
154-
return NULL;
167+
return true;
155168
}
156169

157170
int
@@ -167,6 +180,7 @@ main (int argc, char *argv[])
167180
num_thread = 2;
168181
num_steal = -1;
169182
stealratio = -1.0;
183+
steal_freq = 1000000.0;
170184
breadth = 6;
171185
depth = 10;
172186
dqlogsize = 6;
@@ -254,12 +268,10 @@ main (int argc, char *argv[])
254268
num_job += nrowjob;
255269
}
256270

257-
if (!has_num_steal && !has_steal_freq)
258-
stealratio = -1.0;
259271
if (stealratio >= 0.0)
260272
num_steal = (unsigned long) (stealratio * num_job);
261273
if (num_steal == (unsigned long) -1)
262-
num_steal_per_thread = -1;
274+
num_steal_per_thread = (unsigned long) -1;
263275
else
264276
{
265277
num_steal_per_thread = num_steal / (num_thread - 1);
@@ -307,6 +319,7 @@ main (int argc, char *argv[])
307319
printf ("empty_takes\t"
308320
"empty_steals\t"
309321
"total_jobs\t"
322+
"steal_freq\t"
310323
"expected_steals\t"
311324
"effective_steals\n");
312325

@@ -321,6 +334,7 @@ main (int argc, char *argv[])
321334
printf ("%-8lu\t", n);
322335

323336
printf ("%-8lu\t", num_job);
337+
printf ("%-8g\t", steal_freq);
324338
if (num_steal == (unsigned long) -1)
325339
printf ("unspecified\t");
326340
else

libworkstream_df/time-util.h

+12
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,18 @@ do \
2929
} \
3030
while (0)
3131

32+
static inline double
33+
get_thread_cpu_time (void)
34+
{
35+
struct timespec _tv;
36+
double _t;
37+
38+
clock_gettime (CLOCK_THREAD_CPUTIME_ID, &_tv);
39+
_t = _tv.tv_sec;
40+
_t += _tv.tv_nsec * 1e-9;
41+
return _t;
42+
}
43+
3244
static inline int
3345
timespec_diff (struct timespec *_result,
3446
const struct timespec *_px, const struct timespec *_py)

0 commit comments

Comments
 (0)