[pypy-commit] benchmarks multithread-runner: add benchmark from benchmarksgame
Raemi
pypy.commits at gmail.com
Thu Jul 11 04:46:44 EDT 2019
Author: Remi Meier <remi.meier at gmail.com>
Branch: multithread-runner
Changeset: r385:06b36af4f84d
Date: 2016-07-22 10:10 +0200
http://bitbucket.org/pypy/benchmarks/changeset/06b36af4f84d/
Log: add benchmark from benchmarksgame
diff --git a/multithread/fannkuch-redux/fannkuch-redux.py b/multithread/fannkuch-redux/fannkuch-redux.py
new file mode 100644
--- /dev/null
+++ b/multithread/fannkuch-redux/fannkuch-redux.py
@@ -0,0 +1,157 @@
+# -*- coding: utf-8 -*-
+import gc
+import sys
+import time
+from common.abstract_threading import (
+ atomic, Future, set_thread_pool, ThreadPool,
+ hint_commit_soon, turn_jitting_off)
+
+
+# Revised BSD license
+# This is a specific instance of the Open Source Initiative (OSI) BSD license template.
+# Copyright (c) 2004-2008 Brent Fulgham, 2005-2016 Isaac Gouy
+# All rights reserved.
+
+# The Computer Language Benchmarks Game
+# http://benchmarksgame.alioth.debian.org/
+#
+# contributed by Joerg Baumann
+# many thanks to Oleg Mazurov for his helpful description
+
+from sys import argv
+from math import factorial
+from itertools import islice, starmap
+
+def permutations(n, start, size):
+ p = bytearray(range(n))
+ count = bytearray(n)
+
+ remainder = start
+ for v in range(n - 1, 0, -1):
+ count[v], remainder = divmod(remainder, factorial(v))
+ for _ in range(count[v]):
+ p[:v], p[v] = p[1:v + 1], p[0]
+
+ assert(count[1] == 0)
+ assert(size < 2 or (size % 2 == 0))
+
+ if size < 2:
+ yield p[:]
+ else:
+ rotation_swaps = [None] * n
+ for i in range(1, n):
+ r = list(range(n))
+ for v in range(1, i + 1):
+ r[:v], r[v] = r[1:v + 1], r[0]
+ swaps = []
+ for dst, src in enumerate(r):
+ if dst != src:
+ swaps.append((dst, src))
+ rotation_swaps[i] = tuple(swaps)
+
+ while True:
+ yield p[:]
+ p[0], p[1] = p[1], p[0]
+ yield p[:]
+ i = 2
+ while count[i] >= i:
+ count[i] = 0
+ i += 1
+ else:
+ count[i] += 1
+ t = p[:]
+ for dst, src in rotation_swaps[i]:
+ p[dst] = t[src]
+
+def alternating_flips_generator(n, start, size):
+ maximum_flips = 0
+ alternating_factor = 1
+ for permutation in islice(permutations(n, start, size), size):
+ first = permutation[0]
+ if first:
+ flips_count = 1
+ while True:
+ permutation[:first + 1] = permutation[first::-1]
+ first = permutation[0]
+ if not first: break
+ flips_count += 1
+ if maximum_flips < flips_count:
+ maximum_flips = flips_count
+ yield flips_count * alternating_factor
+ else:
+ yield 0
+ alternating_factor = -alternating_factor
+ yield maximum_flips
+
+def task(n, start, size):
+ alternating_flips = alternating_flips_generator(n, start, size)
+ return sum(islice(alternating_flips, size)), next(alternating_flips)
+
+def fannkuch(n):
+ assert(n > 0)
+
+ task_count = 16
+ total = factorial(n)
+ task_size = (total + task_count - 1) // task_count
+
+ if task_size < 20000:
+ task_size = total
+ task_count = 1
+
+ assert(task_size % 2 == 0)
+
+ task_args = [(n, i * task_size, task_size) for i in range(task_count)]
+
+ t = time.time()
+ fs = []
+ for args in task_args:
+ fs.append(Future(task, *args))
+ checksums, maximums = zip(*[f() for f in fs])
+ # with Pool() as pool:
+ # checksums, maximums = zip(*pool.starmap(task, task_args))
+
+ checksum, maximum = sum(checksums), max(maximums)
+ t = time.time() - t
+ print("{0}\nPfannkuchen({1}) = {2}".format(checksum, n, maximum))
+ return t
+
+
+def run(threads=2, n=9):
+ threads = int(threads)
+ n = int(n)
+
+ set_thread_pool(ThreadPool(threads))
+
+ t = fannkuch(n)
+
+ # shutdown current pool
+ set_thread_pool(None)
+ return t
+
+def main(argv):
+ # warmiters threads args...
+ warmiters = int(argv[0])
+ threads = int(argv[1])
+ n = int(argv[2])
+
+ print "params (iters, threads, n):", warmiters, threads, n
+
+ print "do warmup:"
+ for i in range(4):
+ t = run(threads, n)
+ print "iter", i, "time:", t
+
+ print "turn off jitting"
+ turn_jitting_off()
+ print "do", warmiters, "real iters:"
+ times = []
+ for i in range(warmiters):
+ gc.collect()
+
+ t = run(threads, n)
+ times.append(t)
+ print "warmiters:", times
+
+if __name__ == "__main__":
+ import sys
+ main(sys.argv[1:])
More information about the pypy-commit
mailing list