File: cppbench

package info (click to toggle)
aqsis 1.8.2-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 18,340 kB
  • ctags: 19,671
  • sloc: cpp: 138,267; python: 12,880; ansic: 4,946; xml: 3,415; yacc: 1,887; sh: 406; makefile: 385; lex: 280
file content (145 lines) | stat: -rwxr-xr-x 4,025 bytes parent folder | download | duplicates (6)
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
#!/bin/bash

# Test runner for small C++ performance tests
#
# Author: Chris Foster [chris42f (at) gmail (dot) com]

function print_help
{
cat <<EOF
Usage: cppbench [options] source_file

Utility for running multiple embedded benchmarks from a single c++ source file.
Comments in a specific format allow linewise modifications of the source to
generate various versions on the fly.  These are compiled and the runtime of
the resulting executable is timed with the unix "time" utility.  The results of
each benchmark in the suite are displayed in human-readable format.


Source code markup:
    The source file contains several special comment types:

    To specifiy lines which should be uncommented when running the
    benchmarks name1, name2, there should be a comment of the form

        // code_to_run; //##bench name1 name2 ...

    The description for a particular benchmark is of the form

        //##description name <string describing test>

    Only benchmarks with a description line are considered.

    Finally, the compiler, compiler optimizations and linker flags are given as
    follows:
    //##CXX g++
    //##CXXFLAGS -O3 ...
    //##LDFLAGS -lm ...

Options:
    -h                   This help
    -n name1,name2,...   Specify benchmark names to run.
    -S                   Dump assembly listings rather than running.
    -v                   View the modified source before running the benchmark
    -l                   List the benchmark tags defined in the source

EOF
}

if [[ -z $1 ]] ; then
    print_help
    exit -1
fi

viewSource=0
dumpAssembly=0
listTags=0
while [[ -n $1 ]] ; do
    case $1 in
        -n)
            shift
            benchmarkNamesToRun="$(echo $1 | tr ',' ' ')";;
        -h)
            print_help
            exit 0;;
        -v)
            viewSource=1;;
        -S)
            dumpAssembly=1;;
        -l)
            listTags=1;;
        *)
            sourceFile=$1;;
    esac
    shift
done

if [[ ! -f $sourceFile ]] ; then
    echo "Source file not found" 1>&2
    exit -1
fi

# get all the benchmark names
benchmarkNamesAll=$(awk '/\/\/##description/ { print $2 }' $sourceFile)

if [[ -z $benchmarkNamesAll ]] ; then
    echo "No benchmarks found" 1>&2
    exit -1
fi

if [[ -z $benchmarkNamesToRun ]] ; then
    benchmarkNamesToRun="$benchmarkNamesAll"
fi

if [[ $listTags == 1 ]] ; then
    echo "Benchmark names:"
    for tag in $benchmarkNamesAll ; do
        echo "    $tag"
    done
    exit 0
fi

# get compile flags
CXX=$(sed -n -e '/\/\/##CXX\>/ { s/\/\/##CXX\>//p ; q}' $sourceFile)
if [[ -z $CXX ]] ; then
    CXX=c++
fi
CXXFLAGS=$(sed -n -e 's/\/\/##CXXFLAGS//p' $sourceFile)
if [[ $dumpAssembly == 1 ]] ; then
    CXXFLAGS="${CXXFLAGS} -S"
else
    LDFLAGS=$(sed -n -e 's/\/\/##LDFLAGS//p' $sourceFile)
fi

tmpFileName=_cppbench_tmp.cpp
tmpOutName=_cppbench_tmp

# Compile each benchmark.
for name in $benchmarkNamesToRun ; do
    notThisNameAlt="\\($(echo $benchmarkNamesAll | sed -e "s/\<$name\> *//" -e 's/ \+/\\|/g')\\)"
    sed -e '/\/\/##bench.*\<'"$name"'\>/ {s+\(//\|/\*\|\*/\)++}' -e '/\/\/##bench.*\<'"NOT_$notThisNameAlt"'\>/ {s/\/\///}' $sourceFile > $tmpFileName
    echo "-------------------- Benchmark: $name --------------------"
    eval echo $CXX $CXXFLAGS $sourceFile $LDFLAGS
    if [[ $viewSource == 1 ]] ; then
        less $tmpFileName
    fi
	# Use 'eval' here so that any environment variables in $CXXFLAGS are
	# expanded correctly.
    eval $CXX $CXXFLAGS $tmpFileName -o $tmpOutName $LDFLAGS
    if [[ $? != 0 ]] ; then
        exit -1
    fi
    if [[ $dumpAssembly == 1 ]] ; then
        # Move assembly somewhere it can be viewed
        mv $tmpOutName "${sourceFile%.cpp}.${name}.s"
        echo "generated assembly: ${sourceFile%.cpp}.${name}.s"
    else
        # output description and time program run
        echo -n "Description: "
        sed -n -e 's/.*\/\/##description *\<'"$name"'\> *//p' $sourceFile
        time ./$tmpOutName 2>/dev/null
        echo
    fi
done

rm -f $tmpFileName $tmpOutName