~linaro-toolchain-dev/cortex-strings/trunk

« back to all changes in this revision

Viewing changes to scripts/bench.py

  • Committer: Will Newton
  • Date: 2013-09-09 15:34:02 UTC
  • Revision ID: will.newton@linaro.org-20130909153402-40quvmkeofe6g7og
Fix more comments relating to alignment.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 
22
22
HAS = {
23
23
    'this': 'bounce memchr memcpy memset strchr strcpy strlen',
24
 
    'bionic': 'memcmp memcpy memset strcmp strcpy strlen',
 
24
    'bionic-a9': 'memcmp memcpy memset strcmp strcpy strlen',
 
25
    'bionic-a15': 'memcmp memcpy memset strcmp strcpy strlen',
25
26
    'bionic-c': ALL,
26
27
    'csl': 'memcpy memset',
27
28
    'glibc': 'memcpy memset strlen',
32
33
    'plain': 'memset memcpy strcmp strcpy',
33
34
}
34
35
 
35
 
def run(cache, variant, function, bytes, loops, alignment=8, quiet=False):
 
36
BOUNCE_ALIGNMENTS = ['1']
 
37
SINGLE_BUFFER_ALIGNMENTS = ['1', '2', '4', '8', '16', '32']
 
38
DUAL_BUFFER_ALIGNMENTS = ['1:32', '2:32', '4:32', '8:32', '16:32', '32:32']
 
39
 
 
40
ALIGNMENTS = {
 
41
    'bounce': BOUNCE_ALIGNMENTS,
 
42
    'memchr': SINGLE_BUFFER_ALIGNMENTS,
 
43
    'memset': SINGLE_BUFFER_ALIGNMENTS,
 
44
    'strchr': SINGLE_BUFFER_ALIGNMENTS,
 
45
    'strlen': SINGLE_BUFFER_ALIGNMENTS,
 
46
    'memcmp': DUAL_BUFFER_ALIGNMENTS,
 
47
    'memcpy': DUAL_BUFFER_ALIGNMENTS,
 
48
    'strcmp': DUAL_BUFFER_ALIGNMENTS,
 
49
    'strcpy': DUAL_BUFFER_ALIGNMENTS,
 
50
}
 
51
 
 
52
NUM_RUNS = 5
 
53
 
 
54
def run(cache, variant, function, bytes, loops, alignment, run_id, quiet=False):
36
55
    """Perform a single run, exercising the cache as appropriate."""
37
 
    key = ':'.join('%s' % x for x in (variant, function, bytes, loops, alignment))
 
56
    key = ':'.join('%s' % x for x in (variant, function, bytes, loops, alignment, run_id))
38
57
 
39
58
    if key in cache:
40
59
        got = cache[key]
41
60
    else:
42
61
        xbuild = build
43
 
        cmd = '%(xbuild)s%(variant)s -t %(function)s -c %(bytes)s -l %(loops)s -a %(alignment)s' % locals()
 
62
        cmd = '%(xbuild)s%(variant)s -t %(function)s -c %(bytes)s -l %(loops)s -a %(alignment)s -r %(run_id)s' % locals()
44
63
 
45
64
        try:
46
65
            got = subprocess.check_output(cmd.split()).strip()
48
67
            assert False, 'Error %s while running %s' % (ex, cmd)
49
68
 
50
69
    parts = got.split(':')
51
 
    took = float(parts[5])
 
70
    took = float(parts[7])
52
71
 
53
72
    cache[key] = got
54
73
 
58
77
 
59
78
    return took
60
79
 
61
 
def run_many(cache, variants, bytes, alignments):
 
80
def run_many(cache, variants, bytes, all_functions):
62
81
    # We want the data to come out in a useful order.  So fix an
63
82
    # alignment and function, and do all sizes for a variant first
64
83
    bytes = sorted(bytes)
65
 
    mid = bytes[len(bytes)/2]
66
 
 
67
 
    # Use the ordering in 'this' as the default
68
 
    all_functions = HAS['this'].split()
69
 
 
70
 
    # Find all other functions
71
 
    for functions in HAS.values():
72
 
        for function in functions.split():
73
 
            if function not in all_functions:
74
 
                all_functions.append(function)
75
 
 
76
 
    for alignment in alignments:
77
 
        for function in all_functions:
 
84
    mid = bytes[int(len(bytes)/1.5)]
 
85
 
 
86
    if not all_functions:
 
87
        # Use the ordering in 'this' as the default
 
88
        all_functions = HAS['this'].split()
 
89
 
 
90
        # Find all other functions
 
91
        for functions in HAS.values():
 
92
            for function in functions.split():
 
93
                if function not in all_functions:
 
94
                    all_functions.append(function)
 
95
 
 
96
    for function in all_functions:
 
97
        for alignment in ALIGNMENTS[function]:
78
98
            for variant in variants:
79
99
                if function not in HAS[variant].split():
80
100
                    continue
87
107
                want = 5.0
88
108
 
89
109
                loops = int(f / math.sqrt(max(1, mid)))
90
 
                took = run(cache, variant, function, mid, loops, alignment, quiet=True)
 
110
                took = run(cache, variant, function, mid, loops, alignment, 0,
 
111
                           quiet=True)
91
112
                # Keep it reasonable for silly routines like bounce
92
113
                factor = min(20, max(0.05, want/took))
93
114
                f = f * factor
99
120
                for b in sorted(bytes):
100
121
                    # Figure out the number of loops to give a roughly consistent run
101
122
                    loops = int(f / math.sqrt(max(1, b)))
102
 
                    run(cache, variant, function, b, loops, alignment)
 
123
                    for run_id in range(0, NUM_RUNS):
 
124
                        run(cache, variant, function, b, loops, alignment,
 
125
                            run_id)
103
126
 
104
127
def run_top(cache):
105
128
    variants = sorted(HAS.keys())
 
129
    functions = sys.argv[1:]
106
130
 
107
131
    # Upper limit in bytes to test to
108
132
    top = 512*1024
119
143
            steps = int(round(math.log(top) / math.log(step)))
120
144
            bytes.extend([int(step**x) for x in range(0, steps+1)])
121
145
 
122
 
    alignments = [8, 16, 4, 1, 2, 32]
123
 
 
124
 
    run_many(cache, variants, bytes, alignments)
 
146
    run_many(cache, variants, bytes, functions)
125
147
 
126
148
def main():
127
149
    cachename = 'cache.txt'
133
155
            for line in f:
134
156
                line = line.strip()
135
157
                parts = line.split(':')
136
 
                cache[':'.join(parts[:5])] = line
 
158
                cache[':'.join(parts[:7])] = line
137
159
    except:
138
160
        pass
139
161