To protect your data, the CISO officer has suggested users to enable 2FA as soon as possible.
Currently 2.7% of users enabled 2FA.

Commit 115c41f4 authored by John Zhang's avatar John Zhang
Browse files

wip: refactor performance comparison code. Need floating point support to...

wip: refactor performance comparison code. Need floating point support to embed time measurement code in RPython side
parent 592b797b
......@@ -8,6 +8,7 @@ import subprocess as subp
import ctypes
import math
from rpython.rtyper.lltypesystem import lltype, rffi
from rpython.translator.interactive import Translation
from rpython.config.translationoption import set_opt_level
......@@ -28,121 +29,179 @@ def run(cmd):
return p.communicate()
def get_c_function(lib, f):
from ctypes import CDLL
name = f.__name__
return getattr(CDLL(lib.strpath), 'pypy_g_' + name)
def run_cpython(config):
py_file = config['py_file']
out, _ = run([CPYTHON, py_file.strpath] + map(str, config['setup_args']))
return float(out)
def run_pypy_nojit(config):
py_file = config['py_file']
out, _ = run([PYPY, '--jit', 'off', py_file.strpath] + map(str, config['setup_args']))
return float(out)
def run_pypy(config):
py_file = config['py_file']
out, _ = run([PYPY, py_file.strpath] + map(str, config['setup_args']))
return float(out)
def compile_rpython_c(config):
rpyfnc = config['rpy_fnc']
t = Translation(rpyfnc, config['llarg_ts'],
gc='none')
set_opt_level(t.config, '3')
t.ensure_opt('gc', 'none')
libpath = t.compile_c()
fnp = getattr(ctypes.CDLL(libpath.strpath), 'pypy_g_' + rpyfnc.__name__)
fnp.argtypes = config['c_arg_ts']
fnp.restypes = config['c_res_t']
return fnp
def compile_rpython_c_jit(config):
rpyfnc = config['rpy_fnc']
t = Translation(rpyfnc, config['llarg_ts'],
gc='none')
set_opt_level(t.config, 'jit')
t.ensure_opt('gc', 'none')
libpath = t.compile_c()
fnp = getattr(ctypes.CDLL(libpath.strpath), 'pypy_g_' + rpyfnc.__name__)
fnp.argtypes = config['c_arg_ts']
fnp.restypes = config['c_res_t']
return fnp
def compile_rpython_mu(config):
preload_libmu()
rpyfnc = config['rpy_fnc']
libpath = config['libpath_mu']
t = Translation(rpyfnc, config['llarg_ts'],
backend='mu', muimpl='fast', mucodegen='api', mutestjit=True)
set_opt_level(t.config, '3')
db, bdlgen, fnc_name = t.compile_mu()
bdlgen.mu.compile_to_sharedlib(libpath.strpath, [])
fnp = getattr(ctypes.CDLL(libpath.strpath), fnc_name)
fnp.argtypes = config['c_arg_ts']
fnp.restypes = config['c_res_t']
return fnp
def compile_c(config):
libpath = config['libpath_c']
run([CC, '-fpic', '--shared', '-o', libpath.strpath, config['c_file'].strpath])
lib = ctypes.CDLL(libpath.strpath)
fnp = getattr(lib, config['c_sym_name'])
fnp.argtypes = config['c_arg_ts']
fnp.restypes = config['c_res_t']
return fnp
def get_stat(run_fnc, config, warmup=5, iterations=100):
for i in range(warmup):
run_fnc(config)
times = []
for i in range(iterations):
times.append(run_fnc(config))
times.sort()
avg = sum(times) / float(len(times))
t_min = t_max = t_std = None
if len(times) > 1:
t_min = times[0]
t_max = times[-1]
squares = ((t - avg) ** 2 for t in times)
t_std = math.sqrt(sum(squares) / (len(times) - 1))
return {'average': avg, 't_min': t_min, 't_max': t_max, 'std_dev': t_std}
def get_stat_compiled(compile_fnc, config, warmup=5, iterations=100):
def run_funcptr(fnp, config):
args = config['setup'](*config['setup_args'])
print args
t0 = time()
fnp(*args) # TODO: embed time measurement in RPython code
t1 = time()
config['teardown'](*args)
return t1 - t0
fnp = compile_fnc(config)
return get_stat(lambda config: run_funcptr(fnp, config), config, warmup, iterations)
def get_display_str(stat):
output = "average: %(average)s\n" \
"min: %(t_min)s\n" \
"max: %(t_max)s\n" \
"std_dev: %(std_dev)s\n"
return output % stat
def perf(config, warmup, iterations):
results = {
# 'cpython': get_stat(run_cpython, config, warmup, iterations=iterations),
# 'pypy_nojit': get_stat(run_pypy_nojit, config, warmup, iterations=iterations),
# 'pypy': get_stat(run_pypy, config, warmup, iterations=iterations),
# 'rpy_c': get_stat_compiled(compile_rpython_c, config, warmup, iterations=iterations),
# 'rpy_c_jit': get_stat_compiled(compile_rpython_c_jit, config, warmup, iterations=iterations),
'rpy_mu': get_stat_compiled(compile_rpython_mu, config, warmup, iterations=iterations),
# 'c': get_stat_compiled(compile_c, config, warmup, iterations=iterations),
}
for python, result in results.items():
print '\033[35m---- %(python)s ----\033[0m' % locals()
print get_display_str(result)
def perf_fibonacci():
from perftarget.fibonacci import fib
def perf_fibonacci(N, warmup, iterations):
from perftarget.fibonacci import fib, rpy_entry
tmpdir = py.path.local(mkdtemp())
print tmpdir
py_file = perf_target_dir.join('fibonacci.py')
c_file = perf_target_dir.join('fibonacci.c')
def run_cpython(N):
out, _ = run([CPYTHON, py_file.strpath, str(N)])
return float(out)
def run_pypy_nojit(N):
out, _ = run([PYPY, '--jit', 'off', py_file.strpath, str(N)])
return float(out)
def run_pypy(N):
out, _ = run([PYPY, py_file.strpath, str(N)])
return float(out)
def compile_rpython_c():
t = Translation(fib, [int],
gc='none')
set_opt_level(t.config, '3')
t.ensure_opt('gc', 'none')
libpath = t.compile_c()
fnp = getattr(ctypes.CDLL(libpath.strpath), 'pypy_g_' + fib.__name__)
return fnp
def compile_rpython_c_jit():
t = Translation(fib, [int],
gc='none')
set_opt_level(t.config, 'jit')
t.ensure_opt('gc', 'none')
libpath = t.compile_c()
fnp = getattr(ctypes.CDLL(libpath.strpath), 'pypy_g_' + fib.__name__)
return fnp
def compile_c():
libpath = tmpdir.join('libfibonacci' + libext)
run([CC, '-fpic', '--shared', '-o', libpath.strpath, c_file.strpath])
lib = ctypes.CDLL(libpath.strpath)
return lib.fib
def compile_rpython_mu():
preload_libmu()
t = Translation(fib, [int],
backend='mu', muimpl='fast', mucodegen='api', mutestjit=True)
set_opt_level(t.config, '3')
db, bdlgen, fnc_name = t.compile_mu()
libpath = tmpdir.join('lib%(fnc_name)s.dylib' % locals())
bdlgen.mu.compile_to_sharedlib(libpath.strpath, [])
fnp = getattr(ctypes.CDLL(libpath.strpath), fnc_name)
return fnp
def get_stat(run_fnc, args, warmup=5, iterations=100):
for i in range(warmup):
run_fnc(*args)
times = []
for i in range(iterations):
times.append(run_fnc(*args))
times.sort()
avg = sum(times) / float(len(times))
t_min = t_max = t_std = None
if len(times) > 1:
t_min = times[0]
t_max = times[-1]
squares = ((t - avg) ** 2 for t in times)
t_std = math.sqrt(sum(squares) / (len(times) - 1))
return {'average': avg, 't_min': t_min, 't_max': t_max, 'std_dev': t_std}
def get_stat_compiled(compile_fnc, args, warmup=5, iterations=100):
def run_funcptr(fnp, N):
t0 = time()
fnp(N)
t1 = time()
return t1 - t0
fnp = compile_fnc()
return get_stat(lambda *a: run_funcptr(fnp, *a), args, warmup, iterations)
def get_display_str(stat):
output = "average: %(average)s\n" \
"min: %(t_min)s\n" \
"max: %(t_max)s\n" \
"std_dev: %(std_dev)s\n"
return output % stat
N = 30
warmup = 0
iterations = 10
config = {
'py_file': perf_target_dir.join('fibonacci.py'),
'c_file': perf_target_dir.join('fibonacci.c'),
'rpy_fnc': rpy_entry,
'c_sym_name': 'fib',
'llarg_ts': [int],
'c_arg_ts': [ctypes.c_int64],
'c_res_t': ctypes.c_int64,
'setup_args': (N,),
'setup': lambda N: (N, ),
'teardown': lambda N: None,
'libpath_mu': tmpdir.join('libfibonacci_mu.dylib'),
'libpath_c': tmpdir.join('libfibonacci_c.dylib')
}
results = {
'cpython': get_stat(run_cpython, [N], warmup, iterations=iterations),
'pypy_nojit': get_stat(run_pypy_nojit, [N], warmup, iterations=iterations),
'pypy': get_stat(run_pypy, [N], warmup, iterations=iterations),
'rpy_c': get_stat_compiled(compile_rpython_c, [N], warmup, iterations=iterations),
'rpy_c_jit': get_stat_compiled(compile_rpython_c_jit, [N], warmup, iterations=iterations),
'rpy_mu': get_stat_compiled(compile_rpython_mu, [N], warmup, iterations=iterations),
'c': get_stat_compiled(compile_c, [N], warmup, iterations=iterations),
perf(config, warmup, iterations)
def perf_arraysum(N, warmup, iterations):
from perftarget.arraysum import arraysum, setup, teardown
tmpdir = py.path.local(mkdtemp())
print tmpdir
config = {
'py_file': perf_target_dir.join('arraysum.py'),
'c_file': perf_target_dir.join('arraysum.c'),
'rpy_fnc': arraysum,
'c_sym_name': 'arraysum',
'llarg_ts': [rffi.CArrayPtr(rffi.LONGLONG), rffi.SIZE_T],
# 'c_arg_ts': [ctypes.ARRAY(ctypes.c_int64, N), ctypes.c_uint64],
'c_arg_ts': [ctypes.c_voidp, ctypes.c_uint64],
'c_res_t': ctypes.c_int64,
'setup_args': (N, ),
'setup': setup,
'teardown': teardown,
'libpath_mu': tmpdir.join('libfibonacci_mu.dylib'),
'libpath_c': tmpdir.join('libfibonacci_c.dylib')
}
for python, result in results.items():
print '\033[35m---- %(python)s ----\033[0m' % locals()
print get_display_str(result)
perf(config, warmup, iterations)
if __name__ == '__main__':
perf_fibonacci()
perf_fibonacci(5, 0, 1)
# perf_fibonacci(40, 5, 20)
# perf_arraysum(100, 0, 1)
\ No newline at end of file
#include <stdint.h>
uint64_t arraysum(int64_t* arr, uint64_t sz) {
int64_t sum = 0;
uint64_t i;
for(i = 0; i < sz; i ++) {
sum += arr[i];
}
return sum;
}
from rpython.rtyper.lltypesystem import lltype, rffi
from rpython.rlib.jit import JitDriver
d = JitDriver(greens=[], reds='auto')
def arraysum(arr, sz):
sum = rffi.r_longlong(0)
for i in range(sz):
d.jit_merge_point()
sum += arr[i]
return sum
def setup(n):
lst, _ = rand_list_of(n)
arr = lltype.malloc(rffi.CArray(rffi.LONGLONG), n, flavor='raw')
for i, k in enumerate(lst):
arr[i] = k
return rffi.ll2ctypes.lltype2ctypes(arr) , n
def teardown(carr, n):
lltype.free(rffi.ll2ctypes.ctypes2lltype(rffi.CArray(rffi.LONGLONG), carr), 'raw')
def rand_list_of(n):
# 32 extend to 64-bit integers (to avoid overflow in summation
from random import randrange, getstate
init_state = getstate()
return [rffi.r_longlong(randrange(-(1 << 31), (1 << 31) - 1)) for _ in range(n)], init_state
def measure(N):
args = setup(N)
from time import time
t0 = time()
arraysum(*args)
t1 = time()
teardown(*args)
return t0, t1
def rpy_entry(N):
t0, t1 = measure(N)
# from rpython.rlib import rfloat
# print rfloat.double_to_string(t1 - t0, 'e', %(fprec)d, rfloat.DTSF_ADD_DOT_0)
return t1 - t0
if __name__ == '__main__':
import sys
t0, t1 = measure(int(sys.argv[1]))
print '%.15f' % (t1 - t0)
def target(*args):
from rpython.rlib.entrypoint import export_symbol
export_symbol(rpy_entry)
return rpy_entry, [int]
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment