[pypy-commit] benchmarks default: TM benchmark tuning
Raemi
noreply at buildbot.pypy.org
Wed Nov 18 08:08:45 EST 2015
Author: Remi Meier <remi.meier at gmail.com>
Branch:
Changeset: r341:2c38edec82f1
Date: 2015-11-18 13:40 +0100
http://bitbucket.org/pypy/benchmarks/changeset/2c38edec82f1/
Log: TM benchmark tuning
diff --git a/multithread/lee_routing/lee_router_tm.py b/multithread/lee_routing/lee_router_tm.py
--- a/multithread/lee_routing/lee_router_tm.py
+++ b/multithread/lee_routing/lee_router_tm.py
@@ -38,6 +38,27 @@
# Author: IW
# Translated from Java to Python by Remi Meier
+#
+# Changes done to improve TM performance:
+# * The tempgrid was created once, then used repeatedly. For STM,
+# this is bad because when we modify the tempgrid, we write to
+# tons of *old* objects that have to be recorded in the write-set.
+# Also, the write-set goes to the commit log and increases its
+# size tremendously.
+#
+# * The Java version used a list of lists of lists for the grid.
+# To use memory more efficiently, we use one list/array that
+# is indexed linearly with index calculation.
+#
+# * The change above (one big list) means that conflict detection
+# on the shared grid detects conflicts all the time. So we box
+# each value in a STMValue() object. (-> overhead for single-
+# threaded version)
+#
+# * Use optimized STMQueue from pypystm module instead of
+# hand-written WorkQueue.
+#
+
import time
import sys, math
@@ -45,14 +66,12 @@
try:
from pypystm import atomic, hint_commit_soon
+ from pypystm import queue as STMQueue, Empty as STMEmpty
+ print "RUNNING STM"
except ImportError:
print "NOT RUNNING STM"
atomic = threading.RLock()
hint_commit_soon = lambda : 0
-
-try:
- from pypystm import STMQueue, STMEmpty
-except ImportError:
from Queue import Queue as STMQueue, Empty as STMEmpty
@@ -83,9 +102,6 @@
self.width = width
self.height = height
self.depth = depth
- # self._data = [[[0 for _ in range(depth)]
- # for _ in range(height)]
- # for _ in range(width)]
self._data = None
self.reset(EMPTY)
@@ -93,29 +109,19 @@
return (x * self.height + y) * self.depth + z
def __getitem__(self, args):
- #x, y, z = args
- #return self._data[x][y][z]
return self._data[self._idx(*args)]
def __setitem__(self, args, value):
self._data[self._idx(*args)] = value
- # x, y, z = args
- # self._data[x][y][z] = value
def reset(self, val):
self._data = [val] * (self.width * self.height * self.depth)
- # for col in self._data:
- # for r in range(len(col)):
- # col[r] = [val] * self.depth
def occupy(self, lo_x, lo_y, up_x, up_y):
for x in range(lo_x, up_x + 1):
for y in range(lo_y, up_y + 1):
for c in range(self.depth):
self[x, y, c] = OCC
- # depth = self._data[x][y]
- # for c in range(len(depth)):
- # depth[c] = OCC
def add_weights(self):
@@ -139,8 +145,29 @@
if self[x + dx, y + dy, z] == EMPTY:
self[x + dx, y + dy, z] = val - 1
+class STMValue(object):
+ def __init__(self, v):
+ self.v = v
+class STMGrid(Grid):
+ """Grid that boxes each value to avoid conflicts and that
+ keeps around the grid on reset"""
+ def __init__(self, *args):
+ super(STMGrid, self).__init__(*args)
+
+ def reset(self, val):
+ if self._data is None:
+ self._data = [STMValue(val) for _ in range(self.width * self.height * self.depth)]
+ else:
+ for i in range(len(self._data)):
+ self._data[i].v = val
+
+ def __getitem__(self, args):
+ return super(STMGrid, self).__getitem__(args).v
+
+ def __setitem__(self, args, value):
+ super(STMGrid, self).__getitem__(args).v = value
class WorkItem:
@@ -159,7 +186,7 @@
class WorkQueue:
def __init__(self, items):
self._stmQ = STMQueue()
- for i in (items):
+ for i in items:
self._stmQ.put(i)
def dequeue(self):
@@ -190,7 +217,7 @@
class LeeRouter(object):
def __init__(self, file):
- self.grid = Grid(GRID_SIZE, GRID_SIZE, 2)
+ self.grid = STMGrid(GRID_SIZE, GRID_SIZE, 2)
self._work = []
self.net_no = 0
self._parse_data_file(file)
@@ -248,14 +275,6 @@
pass
#print "|".join(map(lambda x:str((x.x1 - x.x2)**2+(x.y1-x.y2)**2), work[:20]))
- # @staticmethod
- # def _compatibility_sort(work):
- # # just here for result-compatibility with Java code
- # for passnum in range(len(work) - 1, 0, -1):
- # for i in range(passnum):
- # if work[i] > work[i+1]:
- # work[i], work[i+1] = work[i+1], work[i]
- # #print "|".join(map(lambda x:str((x.x1 - x.x2)**2+(x.y1-x.y2)**2), work))
def get_next_track(self):
try:
More information about the pypy-commit
mailing list