From 2193701dbf7f8dfe08054df4fc880f0d18081632 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20R=C3=B6hl?= Date: Wed, 21 Aug 2019 14:48:45 +0200 Subject: [PATCH 1/4] Python version of bench.pl --- MainMemory/bench.py | 73 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100755 MainMemory/bench.py diff --git a/MainMemory/bench.py b/MainMemory/bench.py new file mode 100755 index 0000000..f8a7711 --- /dev/null +++ b/MainMemory/bench.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 + +# ======================================================================================= +# +# Author: Thomas Gruber (tg), thomas.gruber@googlemail.com +# Copyright (c) 2019 RRZE, University Erlangen-Nuremberg +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# ======================================================================================= + +import sys, subprocess, re + +default_regex = "^(\w+):\s+([\d\.]+)" +default_smt = 2 + +if len(sys.argv) < 4 or len(sys.argv) > 5: + print("{} - ()".format(sys.argv[0])) + print("Default value is {}".format(default_smt)) + sys.exit(1) + +cmd = str(sys.argv[1]) +minthreads = maxthreads = 0 +try: + minthreads, maxthreads = sys.argv[2].split("-") + minthreads = int(minthreads) + maxthreads = int(maxthreads) + if (minthreads == 0 or minthreads > maxthreads): + print("Cannot use threads range values: {} {}".format(minthreads, maxthreads)) + sys.exit(1) +except: + print("- option not readable: {}".format(sys.argv[2])) + sys.exit(1) +repeats = int(sys.argv[3]) +smt = int(sys.argv[4]) if len(sys.argv) == 5 else default_smt + +maximum = bestthreads = 0 +bestkernel = "None" +for numthreads in range(int(minthreads), int(maxthreads)+1): + runcmd = "likwid-pin -c E:S0:{}:1:{} {}".format(numthreads, smt, cmd) + for rep in range(repeats): + p = subprocess.Popen(runcmd, stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + shell=True) + p.wait() + if p.returncode == 0: + lines = [ l for l in p.stdout.read().decode('utf-8').split("\n") ] + for l in lines: + m = re.search(default_regex, l) + if m and maximum < float(m.group(2)): + maximum = float(m.group(2)) + bestthreads = numthreads + bestkernel = m.group(1) + else: + print("Execution failed: {}".format(runcmd)) + +print("{} was best using {} threads: {}".format(bestkernel, bestthreads, maximum)) From ef4ee1000df079724e0c0a087d93b75f8338645a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20R=C3=B6hl?= Date: Wed, 21 Aug 2019 15:10:12 +0200 Subject: [PATCH 2/4] Python version of bench.pl --- MemoryHierarchy/bench.py | 75 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100755 MemoryHierarchy/bench.py diff --git a/MemoryHierarchy/bench.py b/MemoryHierarchy/bench.py new file mode 100755 index 0000000..5d12715 --- /dev/null +++ b/MemoryHierarchy/bench.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 + +# ======================================================================================= +# +# Author: Thomas Gruber (tg), thomas.gruber@googlemail.com +# Copyright (c) 2019 RRZE, University Erlangen-Nuremberg +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# ======================================================================================= + +import sys, subprocess, re + +default_regex = "([0-9.]+) ([0-9.]+)" +default_smt = 2 +striad_types = {"seq" : 0, + "tp" : 1, + "ws" : 2 + } +start_N = 100 +max_N = 8000000 +scale_N = 1.2 + +if len(sys.argv) < 3 or len(sys.argv) > 4: + print("Usage: {} ()".format(sys.argv[0])) + print("Default value is {}".format(default_smt)) + sys.exit(1) + +numcores = int(sys.argv[1]) +striad_type = sys.argv[2] +striad_t = 0 +if striad_type in striad_types: + striad_t = striad_types.get(striad_type) +else: + print("Invalid type for striad. Available types: {}".format(", ".join(striad_types.keys()))) + sys.exit(1) +smt = int(sys.argv[3]) if len(sys.argv) == 4 else default_smt + +N = start_N +while N < max_N: + performance = 0 + result = None + runcmd = "likwid-pin -c E:S0:{}:1:{} -q ./striad {} {}".format(numcores, smt, + striad_t, N) + while performance == 0: + p = subprocess.Popen(runcmd, stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + shell=True) + p.wait() + if p.returncode == 0: + result = p.stdout.read().decode('utf-8').strip() + m = re.search(default_regex, result) + if m: + performance = float(m.group(2)) + else: + print("Execution failed: {}".format(runcmd)) + break + print(result) + N = int(N * scale_N) From 4009c36127223f6387676d4731250c0a32c11924 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20R=C3=B6hl?= Date: Wed, 21 Aug 2019 16:03:23 +0200 Subject: [PATCH 3/4] Add header line to output for later use in bench.plot --- MemoryHierarchy/bench.pl | 2 +- MemoryHierarchy/bench.py | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/MemoryHierarchy/bench.pl b/MemoryHierarchy/bench.pl index 6c29456..d1e91a4 100755 --- a/MemoryHierarchy/bench.pl +++ b/MemoryHierarchy/bench.pl @@ -22,7 +22,7 @@ if ( $ARGV[1] eq 'seq' ){ $type = 2; } - +print("# striad $numCores $SMT $ARGV[1]\n"); while ( $N < 8000000 ) { my $result; my $performance = '0.00'; diff --git a/MemoryHierarchy/bench.py b/MemoryHierarchy/bench.py index 5d12715..48ec4c3 100755 --- a/MemoryHierarchy/bench.py +++ b/MemoryHierarchy/bench.py @@ -52,12 +52,14 @@ else: sys.exit(1) smt = int(sys.argv[3]) if len(sys.argv) == 4 else default_smt +print("# striad {} {} {}".format(numcores, smt, striad_type)) + N = start_N while N < max_N: performance = 0 result = None runcmd = "likwid-pin -c E:S0:{}:1:{} -q ./striad {} {}".format(numcores, smt, - striad_t, N) + striad_t, N) while performance == 0: p = subprocess.Popen(runcmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, @@ -72,4 +74,5 @@ while N < max_N: print("Execution failed: {}".format(runcmd)) break print(result) + sys.stdout.flush() N = int(N * scale_N) From f4f081e59658a67abd63c937a254a94a2dc594ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20R=C3=B6hl?= Date: Wed, 21 Aug 2019 16:03:51 +0200 Subject: [PATCH 4/4] Gnuplot plotting script --- MemoryHierarchy/bench.plot | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 MemoryHierarchy/bench.plot diff --git a/MemoryHierarchy/bench.plot b/MemoryHierarchy/bench.plot new file mode 100644 index 0000000..08b5ba0 --- /dev/null +++ b/MemoryHierarchy/bench.plot @@ -0,0 +1,15 @@ +set terminal png size 1024,768 enhanced font ,12 +set output 'striad.png' +set xlabel 'Size [kB]' +set xrange [100:] +set yrange [0:] +set ylabel 'Performance [MFLOP/s]' +cpuname = system("likwid-topology | grep 'CPU name' | cut -d ':' -f2 | sort -u | xargs") +numcores = system("grep 'striad' striad.dat | cut -d ' ' -f 3") +smt = system("grep 'striad' striad.dat | cut -d ' ' -f 4") +type = system("grep 'striad' striad.dat | cut -d ' ' -f 5") +set title sprintf("Benchmark of stream triad A[i] = B[i] + C[i] * D[i]\nType '%s', Threads %s, SMT %s, CPU %s", type, numcores, smt, cpuname) +set logscale x + + +plot 'striad.dat' u 1:2 w linespoints title 'striad'